def update_object_password(body, meta, **kwargs): print("=====================") print("Start update password") name = body['metadata']['name'] namespace = body['metadata']['namespace'] image = body['spec']['image'] new_password = body['spec']['password'] database = body['spec']['database'] delete_success_jobs(name, namespace) last_config = yaml.load( meta.get('annotations')['kopf.zalando.org/last-handled-configuration']) old_password = last_config['spec']['password'] api = kubernetes.client.BatchV1Api() passwd_job = render_template( 'mysql-change-password.yml.j2', { 'name': name, 'image': image, 'old_password': old_password, 'new_password': new_password, 'database': database }) api.create_namespaced_job(namespace, passwd_job) wait_until_job_end(f"change-password-{name}-job", namespace) kopf.event(body, type='Info', reason='Password', message='Update password') print("End update password") print("=====================") return {'message': "mysql password changed"}
def test_queueing_fails_with_no_queue(event_queue_loop): # Prerequisite: the context-var should not be set by anything in advance. sentinel = object() assert event_queue_var.get(sentinel) is sentinel with pytest.raises(LookupError): event(OBJ1, type='type1', reason='reason1', message='message1')
def update_psswd(body, spec, diff, status, logger, **kwargs): name = body['metadata']['name'] image = body['spec']['image'] password = body['spec']['password'] database = body['spec']['database'] delete_success_jobs(name) # call tuple element if diff[0][1][1] == "password": logging.info(diff) change_pswd_job = render_template('change-pswd-job.yml.j2', { 'name': name, 'image': image, 'old_password': diff[0][2], 'new_password': diff[0][3], 'database': database}) api = kubernetes.client.BatchV1Api() try: restore_job = render_template('restore-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) backup_job = render_template('backup-job.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) api = kubernetes.client.BatchV1Api() api.delete_namespaced_job(restore_job["metadata"]["name"],"default") except: pass try: api.create_namespaced_job('default', change_pswd_job) if wait_until_job_end(f"change-pswd-{name}-job"): kopf.event(body, type='Normal', reason='PasswordChange', message='Database password has been changed recently') except: api.delete_namespaced_job(change_pswd_job["metadata"]["name"],"default") time.sleep(5) api.create_namespaced_job('default', change_pswd_job) if wait_until_job_end(f"change-pswd-{name}-job"): kopf.event(body, type='Normal', reason='PasswordChange', message='Database password has been changed recently') api.delete_namespaced_job(change_pswd_job["metadata"]["name"],"default") # update deployment manifest deployment = render_template('mysql-deployment.yml.j2', { 'name': name, 'image': image, 'password': password, 'database': database}) api = kubernetes.client.AppsV1Api() api.patch_namespaced_deployment(deployment["metadata"]["name"],"default",deployment)
def create_1(body, meta, spec, status, **kwargs): children = _create_children(owner=body) kopf.info(body, reason='AnyReason') kopf.event(body, type='Warning', reason='SomeReason', message="Cannot do something") kopf.event(children, type='Normal', reason='SomeReason', message="Created as part of the job1step") return {'job1-status': 100}
async def test_via_event_function(mocker, event_queue, event_queue_loop): post = mocker.patch('kopf._cogs.clients.api.post') event(OBJ1, type='type1', reason='reason1', message='message1') assert not post.called assert event_queue.qsize() == 1 event1 = event_queue.get_nowait() assert isinstance(event1, K8sEvent) assert event1.ref == REF1 assert event1.type == 'type1' assert event1.reason == 'reason1' assert event1.message == 'message1'
def create_fn(body, **kwargs): # The all-purpose function for the vent creation. kopf.event(body, type="SomeType", reason="SomeReason", message="Some message") # The shortcuts for the conventional events and common cases. kopf.info(body, reason="SomeReason", message="Some message") kopf.warn(body, reason="SomeReason", message="Some message") try: raise RuntimeError("Exception text.") except: kopf.exception(body, reason="SomeReason", message="Some exception:")
def test_via_event_function(mocker): post_event = mocker.patch('kopf.clients.events.post_event') event_queue = asyncio.Queue() event_queue_var.set(event_queue) event(OBJ1, type='type1', reason='reason1', message='message1') assert not post_event.called assert event_queue.qsize() == 1 event1 = event_queue.get_nowait() assert isinstance(event1, K8sEvent) assert event1.ref == REF1 assert event1.type == 'type1' assert event1.reason == 'reason1' assert event1.message == 'message1'
def thread_fn(): event(OBJ1, type='type1', reason='reason1', message='message1')
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 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 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) 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) except kubernetes.client.rest.ApiException: pass created_backup_pv = True # Cоздаем PVC и PV для бэкапов: try: backup_pv = render_template('backup-pv.yml.j2', {'name': name}) api = kubernetes.client.CoreV1Api() api.create_persistent_volume(backup_pv) except kubernetes.client.rest.ApiException: created_backup_pv = False 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 if created_backup_pv: kopf.event(body, type='Normal', reason='Logging', message="mysql created with created backup-pv ") return {'Message': "mysql created with created backup-pv"} else: kopf.event( body, type='Normal', reason='Logging', message="mysql created without created backup-pv, backup-pv exist " ) return { 'Message': "mysql created without created backup-pv, backup-pv exist" }