def test_create_deployment(self): client = api_client.ApiClient('http://127.0.0.1:8080/') api = extensions_v1beta1_api.ExtensionsV1beta1Api(client) name = 'nginx-deployment-' + str(uuid.uuid4()) deployment = '''apiVersion: extensions/v1beta1 kind: Deployment metadata: name: %s spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 ''' resp = api.create_namespaced_deployment(body=yaml.load(deployment % name), namespace="default") resp = api.read_namespaced_deployment(name, 'default') self.assertIsNotNone(resp) options = v1_delete_options.V1DeleteOptions() resp = api.delete_namespaced_deployment(name, 'default', body=options)
def apply_ds_from_manifest_dict(manifest): """ This method apply daemonset yaml from manifest dict. :param dict manifest: manifest describe the daemonset configuration. """ config.load_kube_config() api = extensions_v1beta1_api.ExtensionsV1beta1Api() return api.create_namespaced_daemon_set(body=manifest, namespace='default')
def get_k8s_clients(conf): config = k8s_config.Configuration() config.host = conf.kubernetes.kube_host config.verify_ssl = False client = api_client.ApiClient(configuration=config) v1 = core_v1_api.CoreV1Api(client) v1extention = extensions_v1beta1_api.ExtensionsV1beta1Api(client) clients = {'v1': v1, 'v1extention': v1extention} return clients
def test_create_daemonset(self): client = api_client.ApiClient('http://127.0.0.1:8080/') api = extensions_v1beta1_api.ExtensionsV1beta1Api(client) name = 'nginx-app-' + str(uuid.uuid4()) daemonset = { 'apiVersion': 'extensions/v1beta1', 'kind': 'DaemonSet', 'metadata': { 'labels': { 'app': 'nginx' }, 'name': '%s' % name, }, 'spec': { 'template': { 'metadata': { 'labels': { 'app': 'nginx' }, 'name': name }, 'spec': { 'containers': [ { 'name': 'nginx-app', 'image': 'nginx:1.10' }, ], }, }, 'updateStrategy': { 'type': 'RollingUpdate', }, } } resp = api.create_namespaced_daemon_set('default', body=daemonset) resp = api.read_namespaced_daemon_set(name, 'default') self.assertIsNotNone(resp) options = v1_delete_options.V1DeleteOptions() resp = api.delete_namespaced_daemon_set(name, 'default', body=options)
def get_k8s_clients(conf): config = k8s_config.Configuration() config.host = conf.kubernetes.kube_host if conf.kubernetes.use_api_certificate: config.ssl_ca_cert = conf.kubernetes.ssl_ca_cert config.cert_file = conf.kubernetes.cert_file config.key_file = conf.kubernetes.key_file else: config.verify_ssl = False client = api_client.ApiClient(configuration=config) v1 = core_v1_api.CoreV1Api(client) v1extension = extensions_v1beta1_api.ExtensionsV1beta1Api(client) # apps_v1 = apps_v1_api.AppsV1Api(client) clients = { 'v1': v1, # 'apps_v1': apps_v1 'v1extension': v1extension } return clients
def undeploy(args): try: dp = deployment.get_deployment(args.namespace, args.name) except Exception as e: stderr.write('cannot load deployment {0}: {1}\n'.format( args.name, kubeutil.get_error(e))) exit(1) resources = None try: resources = json.loads(dp['metadata']['annotations'] ['kdtool.torchbox.com/attached-resources']) except KeyError: pass except ValueError as e: stderr.write( "error: could not decode kdtool.torchbox.com/attached-resources annotation: {0}\n" .format(str(e))) exit(1) stdout.write("\nthis deployment will be removed:\n") stdout.write("- {0}/{1}\n".format( dp['metadata']['namespace'], dp['metadata']['name'], )) if len(resources): if args.all: stdout.write( "\nthe following attached resources will also be deleted:\n") for res in resources: extra = '' if res['kind'] == 'database': extra = ' (database will be dropped)' elif res['kind'] == 'volume': extra = ' (contents will be deleted)' stdout.write("- {0}: {1}{2}\n".format(res['kind'], res['name'], extra)) else: stdout.write( "\nthe following attached resources will NOT be deleted (use --all):\n" ) for res in resources: stdout.write("- {0}: {1}\n".format( res['kind'], res['name'], )) stdout.write('\n') if not args.force: pr = input('continue [y/N]? ') if pr.lower() not in ['yes', 'y']: stdout.write("okay, aborting\n") exit(0) client = kubeutil.get_client() extv1beta1 = extensions_v1beta1_api.ExtensionsV1beta1Api(client) v1 = core_v1_api.CoreV1Api(client) stdout.write('deleting deployment <{}/{}>: '.format( args.namespace, args.name)) extv1beta1.delete_namespaced_deployment(args.name, args.namespace, body={}) stdout.write('ok\n') if not args.all: exit(0) for res in resources: stdout.write('deleting {} <{}>: '.format(res['kind'], res['name'])) if res['kind'] == 'volume': v1.delete_namespaced_persistent_volume_claim(res['name'], args.namespace, body={}) elif res['kind'] == 'secret': v1.delete_namespaced_secret(res['name'], args.namespace, body={}) elif res['kind'] == 'database': resource_path = ('/apis/torchbox.com/v1/namespaces/' + dp['metadata']['namespace'] + '/databases/' + res['name']) header_params = {} header_params['Accept'] = client.select_header_accept( ['application/json']) header_params['Content-Type'] = client.select_header_content_type( ['*/*']) header_params.update(kubeutil.config.api_key) (resp, code, header) = client.call_api(resource_path, 'DELETE', {}, {}, header_params, None, [], _preload_content=False) elif res['kind'] == 'service': v1.delete_namespaced_service(res['name'], args.namespace) elif res['kind'] == 'ingress': extv1beta1.delete_namespaced_ingress(res['name'], args.namespace, body={}) stdout.write('ok\n')
def status(args): try: dp = deployment.get_deployment(args.namespace, args.name) replicasets = deployment.get_replicasets(dp) except Exception as e: stderr.write('cannot load deployment {0}: {1}\n'.format( args.name, kubeutil.get_error(e))) exit(1) try: generation = dp['metadata']['annotations'][ 'deployment.kubernetes.io/revision'] except KeyError: generation = '?' stdout.write("deployment {0}/{1}:\n".format( dp['metadata']['namespace'], dp['metadata']['name'], )) stdout.write( " current generation is {0}, {2} replicas configured, {1} active replica sets\n" .format( generation, len(replicasets), dp['spec']['replicas'], )) stdout.write( "\n active replicasets (status codes: * current, ! error):\n") for rs in replicasets: pods = deployment.get_rs_pods(rs) error = ' ' try: revision = rs['metadata']['annotations'][ 'deployment.kubernetes.io/revision'] except KeyError: revision = '?' if str(revision) == str(generation): active = '*' else: active = ' ' try: nready = rs['status']['readyReplicas'] except KeyError: error = '!' nready = 0 errors = [] try: for condition in rs['status']['conditions']: if condition['type'] == 'ReplicaFailure' and condition[ 'status'] == 'True': errors.append(condition['message']) error = '!' except KeyError: pass stdout.write( " {4}{5}generation {1} is replicaset {0}, {2} replicas configured, {3} ready\n" .format(rs['metadata']['name'], revision, rs['spec']['replicas'], nready, active, error)) for container in rs['spec']['template']['spec']['containers']: stdout.write(" container {0}: image {1}\n".format( container['name'], container['image'], )) for error in errors: stdout.write(" {0}\n".format(error)) for pod in pods: try: phase = pod['status']['phase'] except KeyError: phase = '?' stdout.write(" pod {0}: {1}\n".format( pod['metadata']['name'], phase, )) if 'status' in pod and 'containerStatuses' in pod['status']: for cs in pod['status']['containerStatuses']: if 'waiting' in cs['state']: try: message = cs['state']['waiting']['message'] except KeyError: message = '(no reason)' stdout.write(" {0}: {1}\n".format( cs['state']['waiting']['reason'], message, )) resources = None try: resources = json.loads(dp['metadata']['annotations'] ['kdtool.torchbox.com/attached-resources']) except KeyError: exit(0) except ValueError as e: stderr.write( "warning: could not decode kdtool.torchbox.com/attached-resources annotation: {0}\n" .format(str(e))) exit(0) if len(resources) == 0: exit(0) stdout.write("\nattached resources:\n") client = kubeutil.get_client() v1 = core_v1_api.CoreV1Api(client) extv1beta1 = extensions_v1beta1_api.ExtensionsV1beta1Api(client) services = [ resource['name'] for resource in resources if resource['kind'] == 'service' ] for svc_name in services: service = v1.read_namespaced_service(svc_name, args.namespace) stdout.write(" service {0}: selector is ({1})\n".format( service.metadata.name, ", ".join([k + "=" + v for k, v in service.spec.selector.items()]), )) for port in service.spec.ports: stdout.write(" port {0}: {1}/{2} -> {3}\n".format( port.name, port.port, port.protocol, port.target_port)) ingresses = [ resource['name'] for resource in resources if resource['kind'] == 'ingress' ] for ing_name in ingresses: ingress = extv1beta1.read_namespaced_ingress(ing_name, args.namespace) stdout.write(" ingress {0}:\n".format(ingress.metadata.name)) for rule in ingress.spec.rules: stdout.write(" http[s]://{0} -> {1}/{2}:{3}\n".format( rule.host, ingress.metadata.namespace, rule.http.paths[0].backend.service_name, rule.http.paths[0].backend.service_port, )) volumes = [ resource['name'] for resource in resources if resource['kind'] == 'volume' ] for vol_name in volumes: volume = v1.read_namespaced_persistent_volume_claim( vol_name, args.namespace) if volume.status: stdout.write( " volume {0}: mode is {1}, size {2}, phase {3}\n".format( volume.metadata.name, ",".join(volume.status.access_modes), volume.status.capacity['storage'], volume.status.phase, )) else: stdout.write(" volume {0} is unknown (not provisioned)\n".format( volume.metadata.name, )) databases = [ resource['name'] for resource in resources if resource['kind'] == 'database' ] for db_name in databases: resource_path = ('/apis/torchbox.com/v1/namespaces/' + dp['metadata']['namespace'] + '/databases/' + db_name) header_params = {} header_params['Accept'] = client.select_header_accept( ['application/json']) header_params['Content-Type'] = client.select_header_content_type( ['*/*']) header_params.update(kubeutil.config.api_key) (resp, code, header) = client.call_api(resource_path, 'GET', {}, {}, header_params, None, [], _preload_content=False) database = json.loads(resp.data.decode('utf-8')) if 'status' in database: stdout.write( " database {0}: type {1}, phase {2} (on server {3})\n".format( database['metadata']['name'], database['spec']['type'], database['status']['phase'], database['status']['server'], )) else: stdout.write( " database {0}: type {1}, unknown (not provisioned)\n".format( database['metadata']['name'], database['spec']['type'], ))