diff options
author | Bartek Grzybowski <b.grzybowski@partner.samsung.com> | 2019-05-27 14:57:55 +0200 |
---|---|---|
committer | Bartek Grzybowski <b.grzybowski@partner.samsung.com> | 2019-05-27 14:57:55 +0200 |
commit | 929f0905e6bf1b370dae729d657962d9d75d6041 (patch) | |
tree | 135a849b9ea7369545906be80cdb7fffbec09e6a | |
parent | c2b38a5d0fec6c74d6e9a8c4cbd7be769cdcfe41 (diff) |
Support SSL certificate based authentication to kube API
With this change script by default connects to kube API
performing SSL authentication with certificates that it
tries to read from kube config. A flag of '--no-ssl-auth'
is provided to disable this behaviour.
Change-Id: Ibc1ea21c0c9f3c4a298b5bfef35d916652b598d4
Issue-ID: OOM-1806
Signed-off-by: Bartek Grzybowski <b.grzybowski@partner.samsung.com>
-rwxr-xr-x | helm_deployment_status.py | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/helm_deployment_status.py b/helm_deployment_status.py index f56935ee..20521329 100755 --- a/helm_deployment_status.py +++ b/helm_deployment_status.py @@ -32,6 +32,8 @@ from os.path import expanduser from itertools import chain import csv from requests.packages.urllib3.exceptions import InsecureRequestWarning +from base64 import b64decode +from tempfile import NamedTemporaryFile def add_resource_kind(resources, kind): for item in resources: @@ -186,6 +188,8 @@ def parse_args(): help='run check loop only once') parser.add_argument('-v', dest='verbosity', action='count', default=0, help='increase output verbosity, e.g. -vv is more verbose than -v') + parser.add_argument('--no-ssl-auth', action='store_true', + help='Disable SSL certificate based authentication while connecting to server') return parser.parse_args() @@ -201,13 +205,23 @@ class Kubernetes: self.config = args.kubeconfig self.url = args.server if args.server is not None else \ self._get_k8s_url() + self.no_ssl_auth = args.no_ssl_auth + self.certs = self._get_k8s_certs() if not self.no_ssl_auth else {} self.namespace = args.namespace + # Setup tmp file with ca chain only if certs were gathered successfully + # and --no-ssl-auth wasn't set + if self.certs and not self.no_ssl_auth: + self._setup_cert_files() + def get_resources(self, api, kind): '''Performs actual API call''' url = '/'.join([self.url, api, 'namespaces', self.namespace, kind]) try: - req = requests.get(url, verify=False) + if self.no_ssl_auth: + req = requests.get(url, verify=False) + else: + req = requests.get(url, verify=self.crt_tmp_file.name, cert=self.crt_tmp_file.name) except requests.exceptions.ConnectionError as err: sys.exit('Error: Could not connect to {}'.format(self.url)) if req.status_code == 200: @@ -219,6 +233,16 @@ class Kubernetes: else: sys.exit("Error: There's been an unspecified issue while making a request to the API") + def _setup_cert_files(self): + '''Helper funtion to setup named file for requests.get() call + in self.get_resources() which is able read certificate only + from file''' + ca_chain = NamedTemporaryFile() + for crt in self.certs.values(): + ca_chain.write(crt) + ca_chain.read() # flush the file buffer + self.crt_tmp_file = ca_chain + def _get_k8s_url(self): # TODO: Get login info with open(self.config) as f: @@ -226,6 +250,24 @@ class Kubernetes: # TODO: Support cluster by name return config['clusters'][0]['cluster']['server'] + def _get_k8s_certs(self): + '''Helper function to read and decode certificates from kube config''' + with open(self.config) as f: + config = yaml.load(f) + certs = {} + try: + certs.update(dict(ca_cert=b64decode( + config['clusters'][0]['cluster']['certificate-authority-data']))) + certs.update(dict(client_cert=b64decode( + config['users'][0]['user']['client-certificate-data']))) + certs.update(dict(client_key=b64decode( + config['users'][0]['user']['client-key-data']))) + except KeyError as err: + print('Warning: could not get Kubernetes config for certificates. ' \ + 'Turning off SSL authentication.') + self.no_ssl_auth = True + return certs + def main(): args = parse_args() |