def update_res(name, image, password, database, body): api = kubernetes.client.AppsV1Api() apiBatch = kubernetes.client.BatchV1Api() print(f"delete job: restore-{name}-job") try: #удаляем деплоймент api.delete_namespaced_deployment(name, 'default', propagation_policy='Background') except kubernetes.client.rest.ApiException: pass #Инициализируем деплоймент с новым паролем deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) kopf.append_owner_reference(deployment, owner=body) #Создаем деплоймент и задание try: api.create_namespaced_deployment('default', deployment) api = kubernetes.client.BatchV1Api() except kubernetes.client.rest.ApiException: pass
async def adopt_service(meta, spec, body, namespace, labels, name, **kwargs): """Handler function for new services If the service has an oda.tmforum.org/componentName label, it makes the service a child of the named component. This can help with navigating around the different resources that belong to the component. It also ensures that the kubernetes garbage collection will delete these resources automatically if the component is deleted. Args: * meta (Dict): The metadata from the yaml service definition * spec (Dict): The spec from the yaml service definition showing the intent (or desired state) * status (Dict): The status from the yaml service definition showing the actual state. * body (Dict): The entire yaml service definition * namespace (String): The namespace for the service * labels (Dict): The labels attached to the service. All ODA Components (and their children) should have a oda.tmforum.org/componentName label * name (String): The name of the service Returns: No return value. :meta public: """ logger.debug( f"[adopt_service/{namespace}/{name}] handler called with spec: {spec}") logger.debug("adopt_service called for service - if it is part of a component (oda.tmforum.org/componentName as a label) then make it a child ") if 'oda.tmforum.org/componentName' in labels.keys(): # get the parent component object # str | the custom object's name component_name = labels['oda.tmforum.org/componentName'] try: custom_objects_api = kubernetes.client.CustomObjectsApi() parent_component = custom_objects_api.get_namespaced_custom_object( GROUP, VERSION, namespace, COMPONENTS_PLURAL, component_name) except ApiException as e: # Cant find parent component (if component in same chart as other kubernetes resources it may not be created yet) if e.status == HTTP_NOT_FOUND: raise kopf.TemporaryError( "Cannot find parent component " + component_name) else: logger.error( "Exception when calling custom_objects_api.get_namespaced_custom_object: %s", e) # append oener reference to parent component newBody = dict(body) # cast the service body to a dict kopf.append_owner_reference(newBody, owner=parent_component) core_api_instance = kubernetes.client.CoreV1Api() try: api_response = core_api_instance.patch_namespaced_service( newBody['metadata']['name'], newBody['metadata']['namespace'], newBody) logger.debug( 'Patch service with owner. api_response = %s', api_response) logger.info( f'[adopt_service/{namespace}/{name}] Adding component {component_name} as parent of service') except ApiException as e: if e.status == HTTP_CONFLICT: # Conflict = try again raise kopf.TemporaryError("Conflict updating service.") else: logger.error( "Exception when calling core_api_instance.patch_namespaced_service: %s", e)
def test_removal_from_kubernetes_model(kubernetes_model): kubernetes_model.metadata = None kopf.append_owner_reference(kubernetes_model, owner=Body(OWNER)) kopf.remove_owner_reference(kubernetes_model, owner=Body(OWNER)) assert kubernetes_model.metadata is not None assert kubernetes_model.metadata.owner_references is not None assert isinstance(kubernetes_model.metadata.owner_references, list) assert len(kubernetes_model.metadata.owner_references) == 0
def test_removal_from_pykube_object(pykube_object): del pykube_object.obj['metadata'] kopf.append_owner_reference(pykube_object, owner=Body(OWNER)) kopf.remove_owner_reference(pykube_object, owner=Body(OWNER)) assert 'metadata' in pykube_object.obj assert 'ownerReferences' in pykube_object.obj['metadata'] assert isinstance(pykube_object.obj['metadata']['ownerReferences'], list) assert len(pykube_object.obj['metadata']['ownerReferences']) == 0
def test_removal_from_dict(): obj = {} kopf.append_owner_reference(obj, owner=Body(OWNER)) # assumed to work, tested above kopf.remove_owner_reference(obj, owner=Body(OWNER)) # this one is being tested here assert 'metadata' in obj assert 'ownerReferences' in obj['metadata'] assert isinstance(obj['metadata']['ownerReferences'], list) assert len(obj['metadata']['ownerReferences']) == 0
def test_appending_to_kubernetes_model(kubernetes_model): kubernetes_model.metadata = None kopf.append_owner_reference(kubernetes_model, owner=Body(OWNER)) assert kubernetes_model.metadata is not None assert kubernetes_model.metadata.owner_references is not None assert isinstance(kubernetes_model.metadata.owner_references, list) assert len(kubernetes_model.metadata.owner_references) == 1 assert kubernetes_model.metadata.owner_references[ 0].api_version == OWNER_API_VERSION assert kubernetes_model.metadata.owner_references[0].kind == OWNER_KIND assert kubernetes_model.metadata.owner_references[0].name == OWNER_NAME assert kubernetes_model.metadata.owner_references[0].uid == OWNER_UID
def test_appending_to_dict(): obj = {} kopf.append_owner_reference(obj, owner=Body(OWNER)) assert 'metadata' in obj assert 'ownerReferences' in obj['metadata'] assert isinstance(obj['metadata']['ownerReferences'], list) assert len(obj['metadata']['ownerReferences']) == 1 assert isinstance(obj['metadata']['ownerReferences'][0], dict) assert obj['metadata']['ownerReferences'][0]['apiVersion'] == OWNER_API_VERSION assert obj['metadata']['ownerReferences'][0]['kind'] == OWNER_KIND assert obj['metadata']['ownerReferences'][0]['name'] == OWNER_NAME assert obj['metadata']['ownerReferences'][0]['uid'] == OWNER_UID
def test_appending_distinguishes_by_uid(): """ Changing only the uid should be sufficient to consider a new owner. Here, all other non-id fields are the same, and must be ignored. """ owner1 = copy.deepcopy(OWNER) owner2 = copy.deepcopy(OWNER) owner1['metadata']['uid'] = 'uid-a' owner2['metadata']['uid'] = 'uid-b' obj = {} kopf.append_owner_reference(obj, owner=Body(owner1)) kopf.append_owner_reference(obj, owner=Body(owner2)) uids = {ref['uid'] for ref in obj['metadata']['ownerReferences']} assert uids == {'uid-a', 'uid-b'}
def test_removal_from_multiple_objects(multicls): obj1 = {} obj2 = {} objs = multicls([obj1, obj2]) kopf.append_owner_reference(objs, owner=Body(OWNER)) # assumed to work, tested above kopf.remove_owner_reference(objs, owner=Body(OWNER)) # this one is being tested here assert 'metadata' in obj1 assert 'ownerReferences' in obj1['metadata'] assert isinstance(obj1['metadata']['ownerReferences'], list) assert len(obj1['metadata']['ownerReferences']) == 0 assert 'metadata' in obj2 assert 'ownerReferences' in obj2['metadata'] assert isinstance(obj2['metadata']['ownerReferences'], list) assert len(obj2['metadata']['ownerReferences']) == 0
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] # cохраняем в переменные содержимое описания MySQL из CR password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', {'name': name, 'storage_size': storage_size}) persistent_volume_claim = render_template('mysql-pvc.yml.j2', {'name': name, 'storage_size': storage_size}) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', {'name': name, 'image': image, 'password': password, 'database': database}) restore_job = render_template('restore-job.yml.j2', {'name': name, 'image': image, 'password': password, 'database': database}) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments # Используем api k8s api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) except kubernetes.client.rest.ApiException: pass # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass
def test_appending_to_pykube_object(pykube_object): del pykube_object.obj['metadata'] kopf.append_owner_reference(pykube_object, owner=Body(OWNER)) assert 'metadata' in pykube_object.obj assert 'ownerReferences' in pykube_object.obj['metadata'] assert isinstance(pykube_object.obj['metadata']['ownerReferences'], list) assert len(pykube_object.obj['metadata']['ownerReferences']) == 1 assert isinstance(pykube_object.obj['metadata']['ownerReferences'][0], dict) assert pykube_object.obj['metadata']['ownerReferences'][0][ 'apiVersion'] == OWNER_API_VERSION assert pykube_object.obj['metadata']['ownerReferences'][0][ 'kind'] == OWNER_KIND assert pykube_object.obj['metadata']['ownerReferences'][0][ 'name'] == OWNER_NAME assert pykube_object.obj['metadata']['ownerReferences'][0][ 'uid'] == OWNER_UID
def test_appending_to_multiple_objects(multicls): obj1 = {} obj2 = {} objs = multicls([obj1, obj2]) kopf.append_owner_reference(objs, owner=Body(OWNER)) assert isinstance(obj1['metadata']['ownerReferences'], list) assert len(obj1['metadata']['ownerReferences']) == 1 assert obj1['metadata']['ownerReferences'][0]['apiVersion'] == OWNER_API_VERSION assert obj1['metadata']['ownerReferences'][0]['kind'] == OWNER_KIND assert obj1['metadata']['ownerReferences'][0]['name'] == OWNER_NAME assert obj1['metadata']['ownerReferences'][0]['uid'] == OWNER_UID assert isinstance(obj2['metadata']['ownerReferences'], list) assert len(obj2['metadata']['ownerReferences']) == 1 assert obj2['metadata']['ownerReferences'][0]['apiVersion'] == OWNER_API_VERSION assert obj2['metadata']['ownerReferences'][0]['kind'] == OWNER_KIND assert obj2['metadata']['ownerReferences'][0]['name'] == OWNER_NAME assert obj2['metadata']['ownerReferences'][0]['uid'] == OWNER_UID
def test_removal_identifies_by_uid(): owner1 = copy.deepcopy(OWNER) owner2 = copy.deepcopy(OWNER) owner3 = copy.deepcopy(OWNER) owner1['kind'] = 'KindA' owner2['kind'] = 'KindA' owner3['kind'] = 'KindB' owner1['metadata']['name'] = 'name-a' owner2['metadata']['name'] = 'name-b' owner3['metadata']['name'] = 'name-b' owner1['metadata']['uid'] = 'uid-0' owner2['metadata']['uid'] = 'uid-0' owner3['metadata']['uid'] = 'uid-0' obj = {} # Three different owners added, but all have the same uid. # One is removed and only once, all must be gone (due to same uids). kopf.append_owner_reference(obj, owner=owner1) # assumed to work, tested above kopf.append_owner_reference(obj, owner=owner2) # assumed to work, tested above kopf.append_owner_reference(obj, owner=owner3) # assumed to work, tested above kopf.remove_owner_reference(obj, owner=owner1) # this one is being tested here assert len(obj['metadata']['ownerReferences']) == 0
def test_appending_deduplicates_by_uid(): """ The uid is the only necessary criterion to identify same objects. No matter how we change the irrelevant non-id fields, they must be ignored. """ owner1 = copy.deepcopy(OWNER) owner2 = copy.deepcopy(OWNER) owner3 = copy.deepcopy(OWNER) owner1['kind'] = 'KindA' owner2['kind'] = 'KindA' owner3['kind'] = 'KindB' owner1['metadata']['name'] = 'name-a' owner2['metadata']['name'] = 'name-b' owner3['metadata']['name'] = 'name-b' owner1['metadata']['uid'] = 'uid-0' owner2['metadata']['uid'] = 'uid-0' owner3['metadata']['uid'] = 'uid-0' obj = {} kopf.append_owner_reference(obj, owner=Body(owner1)) kopf.append_owner_reference(obj, owner=Body(owner2)) kopf.append_owner_reference(obj, owner=Body(owner3)) assert len(obj['metadata']['ownerReferences']) == 1 assert obj['metadata']['ownerReferences'][0]['uid'] == 'uid-0'
def test_removal_distinguishes_by_uid(): owner1 = copy.deepcopy(OWNER) owner2 = copy.deepcopy(OWNER) owner3 = copy.deepcopy(OWNER) owner1['metadata']['uid'] = 'uid-a' owner2['metadata']['uid'] = 'uid-b' owner3['metadata']['uid'] = 'uid-c' obj = {} # Three very similar owners added, different only by uid. # One is removed, others must stay (even if kinds/names are the same). kopf.append_owner_reference(obj, owner=Body(owner1)) # assumed to work, tested above kopf.append_owner_reference(obj, owner=Body(owner2)) # assumed to work, tested above kopf.append_owner_reference(obj, owner=Body(owner3)) # assumed to work, tested above kopf.remove_owner_reference(obj, owner=Body(owner1)) # this one is being tested here uids = {ref['uid'] for ref in obj['metadata']['ownerReferences']} assert uids == {'uid-b', 'uid-c'}
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size }) persistent_volume_claim = render_template('mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size }) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(deployment, owner=body) kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt #kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(restore_job, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) # Пытаемся восстановиться из backup restore_status = 'mysql-instance created without restore-job' api = kubernetes.client.CoreV1Api() ret = api.list_persistent_volume() for i in ret.items: if i.metadata.name == f"backup-{name}-pv": try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) restore_status = 'mysql-instance created with restore-job' except kubernetes.client.rest.ApiException: restore_status = 'mysql-instance created without restore-job' pass # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() #print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass return {'message': restore_status}
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] namespace = body['metadata']['namespace'] group, version = body['apiVersion'].split('/') plural = body['metadata']['selfLink'].split('/')[6] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template( 'mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size } ) persistent_volume_claim = render_template( 'mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size } ) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template( 'mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database } ) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database } ) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim( 'default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) status = { "status": { 'kopf': { 'message': 'mysql-instance created with restore-job'}}} logging.info("Restore job executed successfully, so setup '%s' status", status) except kubernetes.client.rest.ApiException: status = { "status": { 'kopf': { 'message': 'mysql-instance created without restore-job'}}} logging.info("Restore job exception, so setup '%s' status", status) # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass api = kubernetes.client.CustomObjectsApi() try: crd_status = api.patch_namespaced_custom_object_status( group, version, namespace, plural, name, body=status) logging.info(crd_status) except kubernetes.client.rest.ApiException as error: print("Exception when calling CustomObjectsApi->get_namespaced_custom_object: %s\n" % error)
def mysql_on_create(body, spec, status, logger, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', {'name': name, 'storage_size': storage_size}) persistent_volume_claim = render_template('mysql-pvc.yml.j2', {'name': name, 'storage_size': storage_size}) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # kopf.append_owner_reference(restore_job, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) jobs = api.list_namespaced_job('default') time.sleep(20) for job in jobs.items: if "restore" in job.metadata.name and job.status.succeeded == 1: body["status"] = dict(message="mysql-instance created with restore-job") else: kopf.event(body, type='Warning', reason='RestoreDB', message='Database job didnt completed successfully within 20 sec, action required!') body["status"] = dict(message="mysql-instance created without restore-job") except kubernetes.client.rest.ApiException: body["status"] = dict(message="mysql-instance created without restore-job") pass # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass return body["status"]
def test_when_set_for_owner_references_removal(owner): obj = {} kopf.append_owner_reference(obj) # assumed to work, tested above kopf.remove_owner_reference(obj) # this one is being tested here assert not obj['metadata']['ownerReferences']
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] namespace = body['metadata']['namespace'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size }) persistent_volume_claim = render_template('mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size }) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim(namespace, persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service(namespace, service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment(namespace, deployment) # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job(namespace, restore_job) time.sleep(60) jobs = api.list_namespaced_job(namespace) for job in jobs.items: jobname = job.metadata.name if (jobname == f"restore-{name}-job"): print("Find recovery job: " + jobname) if (job.status.succeeded == 1): body["status"] = dict( message="mysql-instance created with restore-job") else: body["status"] = dict( message= "mysql-instance created with restore-job. But job works long time" ) except kubernetes.client.rest.ApiException: body["status"] = dict( message="mysql-instance created without restore-job") # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim(namespace, backup_pvc) except kubernetes.client.rest.ApiException: pass return body["status"]
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size }) persistent_volume_claim = render_template('mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size }) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) kopf.event(body, type='Normal', reason='Logging', message=f"mysql deployment {body['metadata']['name']} created") # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) restore_result = 'with' kopf.event(body, type='Normal', reason='Logging', message=f"restore_job created") except kubernetes.client.rest.ApiException: restore_result = 'without' kopf.event(body, type='Error', reason='Logging', message=f"restore_job creation failed") # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass return {'message': f"mysql-instance created {restore_result} restore-job"}
def test_in_owner_reference_appending(): with pytest.raises(TypeError) as e: kopf.append_owner_reference(object(), Body({})) assert "K8s object class is not supported" in str(e.value)
def mysql_on_create(body, spec, **kwargs): logging.info("Mysql is creating...") logging.debug(body) # cохраняем в переменные содержимое описания MySQL из CR name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя logging.info("Generating manifests...") persistent_volume = render_template('mysql-pv.yml.j2', {'name': name, 'storage_size': storage_size}) persistent_volume_claim = render_template('mysql-pvc.yml.j2', {'name': name, 'storage_size': storage_size}) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) logging.debug("manifests:") logging.debug(persistent_volume) logging.debug(persistent_volume_claim) logging.debug(service) logging.debug(deployment) logging.debug(restore_job) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: logging.info("Set resources dependant from mysql...") kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # ^ Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) message = name + " Deployment is created" try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_persistent_volume(backup_pv) logging.info("backup-pv is created") except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) logging.info("backup-pvc is created") except kubernetes.client.rest.ApiException: pass # Пытаемся восстановиться из backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) message += " with restore job" logging.info("Restored from backup") except kubernetes.client.rest.ApiException: message += " without restore job" pass logging.info(message) return {'message': message}
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Generating JSON manifest for deployment persistent_volume = render_template('mysql-pv.yml.j2', {'name': name, 'storage_size': storage_size}) persistent_volume_claim = render_template('mysql-pvc.yml.j2', {'name': name, 'storage_size': storage_size}) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) # Определяем, что созданные ресурсы являются дочерними к управляемому CustomResource: kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) # Таким образом при удалении CR удалятся все, связанные с ним pv,pvc,svc, deployments api = kubernetes.client.CoreV1Api() # Creating mysql PV: api.create_persistent_volume(persistent_volume) # Creating mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Creating mysql SVC: api.create_namespaced_service('default', service) # Creating mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) # Trying restore from backup try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) except kubernetes.client.rest.ApiException: pass # Creating PVC and PV for backups: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass
def test_when_set_for_owner_references_appending(owner): obj = {} kopf.append_owner_reference(obj) assert obj['metadata']['ownerReferences'] assert obj['metadata']['ownerReferences'][0]['uid'] == OWNER_UID
def mysql_on_create(body, spec, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] persistent_volume = render_template('mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size }) persistent_volume_claim = render_template('mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size }) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) kopf.append_owner_reference(restore_job, owner=body) api = kubernetes.client.CoreV1Api() api.create_persistent_volume(persistent_volume) api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) api.create_namespaced_service('default', service) api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) except kubernetes.client.rest.ApiException: pass try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() print(api.create_persistent_volume(backup_pv)) api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: pass try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass
def test_when_unset_for_owner_references_appending(): with pytest.raises(LookupError) as e: kopf.append_owner_reference([]) assert 'Owner must be set explicitly' in str(e.value)
def mysql_on_create(body, spec, **_): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] storage_size = body['spec']['storage_size'] # Генерируем JSON манифесты для деплоя persistent_volume = render_template('mysql-pv.yml.j2', { 'name': name, 'storage_size': storage_size }) persistent_volume_claim = render_template('mysql-pvc.yml.j2', { 'name': name, 'storage_size': storage_size }) service = render_template('mysql-service.yml.j2', {'name': name}) deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database }) kopf.append_owner_reference(persistent_volume, owner=body) kopf.append_owner_reference(persistent_volume_claim, owner=body) # addopt kopf.append_owner_reference(service, owner=body) kopf.append_owner_reference(deployment, owner=body) kopf.append_owner_reference(restore_job, owner=body) api = kubernetes.client.CoreV1Api() # Создаем mysql PV: api.create_persistent_volume(persistent_volume) # Создаем mysql PVC: api.create_namespaced_persistent_volume_claim('default', persistent_volume_claim) # Создаем mysql SVC: api.create_namespaced_service('default', service) # Создаем mysql Deployment: api = kubernetes.client.AppsV1Api() api.create_namespaced_deployment('default', deployment) try: api = kubernetes.client.BatchV1Api() api.create_namespaced_job('default', restore_job) except kubernetes.client.rest.ApiException: pass try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_persistent_volume(backup_pv) message = "Without restore job" except kubernetes.client.rest.ApiException: pass if 'message' not in locals(): message = "With restore job" try: backup_pvc = render_template('backup-pvc.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_namespaced_persistent_volume_claim('default', backup_pvc) except kubernetes.client.rest.ApiException: pass return {'message': message}