| 69 | return sys.platform in ("win32", "cygwin") |
| 70 | |
| 71 | def run(self, previous_response=None): |
| 72 | is_interactive = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() |
| 73 | kubernetes_exec_info = { |
| 74 | 'apiVersion': self.api_version, |
| 75 | 'kind': 'ExecCredential', |
| 76 | 'spec': { |
| 77 | 'interactive': is_interactive |
| 78 | } |
| 79 | } |
| 80 | if previous_response: |
| 81 | kubernetes_exec_info['spec']['response'] = previous_response |
| 82 | if self.cluster: |
| 83 | kubernetes_exec_info['spec']['cluster'] = self.cluster.value |
| 84 | if self.cluster.value.get("extensions"): |
| 85 | for extension in self.cluster.value["extensions"]: |
| 86 | if extension["name"] == "client.authentication.k8s.io/exec": |
| 87 | kubernetes_exec_info["spec"]["cluster"]["config"] = extension["extension"] |
| 88 | break |
| 89 | |
| 90 | self.env['KUBERNETES_EXEC_INFO'] = json.dumps(kubernetes_exec_info) |
| 91 | process = subprocess.Popen( |
| 92 | self.args, |
| 93 | stdout=subprocess.PIPE, |
| 94 | stderr=sys.stderr if is_interactive else subprocess.PIPE, |
| 95 | stdin=sys.stdin if is_interactive else None, |
| 96 | cwd=self.cwd, |
| 97 | env=self.env, |
| 98 | universal_newlines=True, |
| 99 | shell=self.shell) |
| 100 | (stdout, stderr) = process.communicate() |
| 101 | exit_code = process.wait() |
| 102 | if exit_code != 0: |
| 103 | msg = 'exec: process returned %d' % exit_code |
| 104 | stderr = stderr.strip() |
| 105 | if stderr: |
| 106 | msg += '. %s' % stderr |
| 107 | raise ConfigException(msg) |
| 108 | try: |
| 109 | data = json.loads(stdout) |
| 110 | except ValueError as de: |
| 111 | raise ConfigException( |
| 112 | 'exec: failed to decode process output: %s' % de) |
| 113 | for key in ('apiVersion', 'kind', 'status'): |
| 114 | if key not in data: |
| 115 | raise ConfigException( |
| 116 | 'exec: malformed response. missing key \'%s\'' % key) |
| 117 | if data['apiVersion'] != self.api_version: |
| 118 | raise ConfigException( |
| 119 | 'exec: plugin api version %s does not match %s' % |
| 120 | (data['apiVersion'], self.api_version)) |
| 121 | return data['status'] |