def syncToVault(self): k8s_client = ApiClient().apiclient() dyn_client = DynamicClient(k8s_client) v1_resources = dyn_client.resources.get(api_version='v1', kind='Secret') try: resource_list = v1_resources.get(namespace=self.namespace) logging.info('Retrieved list of secrets from project ' + self.namespace) except Exception as e: logging.error('Error encountered ' + str(e)) sys.exit(1) secdict = [] for resource in resource_list.items: secdict.append(resource.metadata.name) logging.info('Secret list is ' + str(secdict)) for secret in secdict: try: fullyaml = v1_resources.get(name=secret, namespace=self.namespace) yamlresponse = yaml.safe_load(str(fullyaml)) yamldata = yamlresponse['ResourceInstance[Secret]']['data'] for key, value in yamldata.iteritems(): try: Actions(secret_path=self.namespace + '/' + secret, mount_point='secret', secret={ key: value }).toVault() logging.info('Secret ' + secret + ' key ' + key + ' added to hashicorp vault') except Exception as e: logging.error('Error pushing secret key ' + key + ' from secret ' + secret + ' to hashicorp vault. See ERROR: ' + str(e)) except Exception as e: logging.error('Encountered error while getting Secret ' + secret + ' Error: ' + str(e)) logging.info('All secrets in namespace ' + self.namespace + ' pushed to Vault')
def createResource(self): logging.info('Creating '+ self.resource_type + ' ' + self.filepath + ' into project ' + self.namespace) with open(self.filepath) as resource: resource_dict=yaml.load(resource) #config.load_kube_config() name=resource_dict['metadata']['name'] data=resource_dict['data'] k8s_client = ApiClient().apiclient() api_instance = k8s_client.CoreV1Api() sec = k8s_client.V1Secret() try: sec.metadata = k8s_client.V1ObjectMeta(name=name) sec.type = "Opaque" sec.data = data resp = api_instance.create_namespaced_secret(namespace=self.namespace, body=sec) return resp except Exception as e: logging.error('Exception occured '+ str(e)) sys.exc_clear()
def deleteResourceType(self): k8s_client = ApiClient.apiclient() dyn_client = DynamicClient(k8s_client) v1_resources = dyn_client.resources.get(api_version='v1', kind=self.resource_type) logging.info('Requested to delete resources of type ' + self.resource_type) try: v1_resources.delete(namespace=self.namespace, field_selector='metadata.namespace=' + self.namespace) logging.info('Deleted all resources of type ' + self.resource_type) except Exception as ex: logging.error(str(ex)) sys.exc_clear()
def deleteResource(self): k8s_client = ApiClient.apiclient() dyn_client = DynamicClient(k8s_client) logging.info('Requested to delete resource ' + self.name + ' via API version v1') try: v1_resources = dyn_client.resources.get(api_version='v1', kind=self.resource_type) v1_resources.delete(namespace=self.namespace, name=self.name) logging.info('Deleted resource ' + self.resource_type + ' ' + self.name) except Exception as ex: logging.error(str(ex)) sys.exc_clear()
def syncToVault(self): k8s_client = ApiClient().apiclient api_instance = kubernetes.client.CoreV1Api(k8s_client) try: resource_list = api_instance.list_namespaced_secret( self.namespace, pretty=True, timeout_seconds=30) logging.info('Retrieved list of secrets from project ' + self.namespace) except ApiException as e: logging.error( 'Error encountered when calling CoreV1Api --> list_namespaced_secret ' + str(e)) sys.exit(1) secdict = [] for resource in resource_list.items: secdict.append(resource.metadata.name) logging.info('Secret list is ' + str(secdict)) for secret in secdict: try: fullyaml = api_instance.read_namespaced_secret(secret, self.namespace, pretty=True) yamlresponse = yaml.safe_load(str(fullyaml)) yamldata = yamlresponse['V1Secret[Secret]']['data'] for key, value in yamldata.iteritems(): try: Actions(secret_path=self.namespace + '/' + secret, mount_point='secret', secret={ key: value }).toVault() logging.info('Secret ' + secret + ' key ' + key + ' added to hashicorp vault') except Exception as e: logging.error('Error pushing secret key ' + key + ' from secret ' + secret + ' to hashicorp vault. See ERROR: ' + str(e)) except ApiException as e: logging.error( 'Encountered error while calling CoreV1Api --> read_namespaced_secret for secret' + secret + ' Error: ' + str(e)) logging.info('All secrets in namespace ' + self.namespace + ' pushed to Vault')
def main(): src.logger.setLevel() parser = argparse.ArgumentParser( description='Listed arguments --namespace') parser.add_argument("-n", "--namespace", help="The namespace of the openshift project to watch") args = parser.parse_args() namespace = args.namespace k8s_client = ApiClient.apiclient() dyn_client = DynamicClient(k8s_client) v1_resources = dyn_client.resources.get(api_version='v1', kind='Secret') while True: secdict = Sync(namespace).checkForSync() if len(secdict) == 0: logging.info('No secrets have changed in the meantime...') else: logging.info( 'We have secrets that were modified, requeing the deployments now...' ) Requeue(seclist=secdict, namespace=namespace).syncObjects() logging.info('Sleeping 3 minutes before scheduling next check') time.sleep(180)
def test_apiclient(self): client = ApiClient().apiclient self.assertEqual(type(client), "<class 'kubernetes.client.api_client.ApiClient'>")
def checkForSync(self): k8s_client = ApiClient.apiclient() dyn_client = DynamicClient(k8s_client) v1_resources = dyn_client.resources.get(api_version='v1', kind='Secret') try: resources_list = v1_resources.get(namespace=self.namespace) logging.info('Retrived list of secrets from project ' + self.namespace) except Exception as e: logging.error('Error encountered ' + str(e)) sys.exit(1) secdict = [] secact = [] for resource in resources_list.items: secdict.append(resource.metadata.name) logging.info('Secret list is ' + str(secdict)) for secret in secdict: try: fullyaml = v1_resources.get(name=secret, namespace=self.namespace) yaml_response = yaml.safe_load(str(fullyaml)) yamldata = yaml_response['ResourceInstance[Secret]']['data'] for key, value in yamldata.iteritems(): try: val = Actions(key=key, mount_point='secret', secret_path=self.namespace + '/' + secret).fromVault() encodedbytes = base64.b64encode(val.encode("utf-8")) if encodedbytes and value == encodedbytes: logging.info( 'The current value of the secret-key ' + key + ' in secret ' + secret + ' is unchanged, skipping this one...') elif encodedbytes and value != encodedbytes: fullyaml = yaml.safe_load(str(fullyaml)) fullyaml['ResourceInstance[Secret]']['data'][ key] = encodedbytes logging.info('Updating key-value for key ' + key + ' in secret ' + secret) try: print fullyaml['ResourceInstance[Secret]'] v1_resources.patch( body=fullyaml['ResourceInstance[Secret]'], namespace=self.namespace, name=secret) logging.info( 'Secret ' + secret + ' updated with a new value in namespace ' + self.namespace) secact.append(secret) logging.info( 'Updating the list with secrets that has been modified' ) except Exception as e: logging.error('Error encountered ' + str(e)) else: logging.error('The value for key ' + key + ' does not exist in Vault') break except Exception as e: logging.error('Error getting/setting secret key ' + key + ' for secret ' + secret + ' from Hashicorp Vault. See ERROR: ' + str(e)) except Exception as e: logging.error('Error encountered while getting secret ' + secret + ' Error: ' + str(e)) return secact