From 893344a0f83e70715e28b71dfc890b1804847587 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Tue, 6 Sep 2016 18:11:46 -0700 Subject: [PATCH] Cleanup resource and resource-template Currently the service name is required and has a strange ordering: kolla-kubernetes resource-template create openvswitch pod vswitchd This has been hard to keep track of as two things that usually go together, service and name are seperated by something else. This will be a minor, but ongoing source of pain for operators. This patchset changes it to look like: kolla-kubernetes resource-template create pod openvswitch-vswitchd Putting service and name together. Partially-Implements: blueprint redundant-cli-info Implements: blueprint resource-magic Change-Id: I3609c874429fa5fef42daaa63cb7903e1afee2dd --- doc/source/multi-node.rst | 106 +++++++++++----------- kolla_kubernetes/commands/cmd_resource.py | 83 +++++++++++------ kolla_kubernetes/kube_service_status.py | 4 +- kolla_kubernetes/service_resources.py | 29 +++++- kolla_kubernetes/tests/test_templates.py | 25 +++++ 5 files changed, 159 insertions(+), 88 deletions(-) diff --git a/doc/source/multi-node.rst b/doc/source/multi-node.rst index c25bdf20d..813e60114 100644 --- a/doc/source/multi-node.rst +++ b/doc/source/multi-node.rst @@ -171,7 +171,7 @@ Operator Create Resources kolla-kubernetes bootstrap ceph # adds ceph secret, no-op for storage_provider!=ceph kolla-kubernetes bootstrap mariadb sleep 30 # wait for mariadb bootstrap to finish - kolla-kubernetes resource delete mariadb bootstrap # workaround known issue #1 + kolla-kubernetes resource delete bootstrap mariadb # workaround known issue #1 kolla-kubernetes run mariadb kolla-kubernetes run memcached sleep 30 # wait for mariadb and memcached to start up @@ -190,28 +190,28 @@ bits of logic. :: - kolla-kubernetes resource create mariadb disk - kolla-kubernetes resource create mariadb pv - kolla-kubernetes resource create mariadb pvc - kolla-kubernetes resource create mariadb svc - kolla-kubernetes resource create mariadb configmap - kolla-kubernetes resource create mariadb bootstrap + kolla-kubernetes resource create disk mariadb + kolla-kubernetes resource create pv mariadb + kolla-kubernetes resource create pvc mariadb + kolla-kubernetes resource create svc mariadb + kolla-kubernetes resource create configmap mariadb + kolla-kubernetes resource create bootstrap mariadb sleep 30 # wait for mariadb bootstrap to finish - kolla-kubernetes resource delete mariadb bootstrap # workaround known issue #1 - kolla-kubernetes resource create mariadb pod - kolla-kubernetes resource create memcached svc - kolla-kubernetes resource create memcached configmap - kolla-kubernetes resource create memcached pod - kolla-kubernetes resource create keystone svc - kolla-kubernetes resource create keystone configmap + kolla-kubernetes resource delete bootstap mariadb # workaround known issue #1 + kolla-kubernetes resource create pod mariadb + kolla-kubernetes resource create svc memcached + kolla-kubernetes resource create configmap memcached + kolla-kubernetes resource create pod memcached + kolla-kubernetes resource create svc keystone + kolla-kubernetes resource create configmap keystone sleep 30 # wait for mariadb and memcached to start up - kolla-kubernetes resource create keystone bootstrap + kolla-kubernetes resource create bootstrap keystone sleep 30 # wait for keystone to bootstrap in mariadb - kolla-kubernetes resource create keystone pod - kolla-kubernetes resource create horizon svc - kolla-kubernetes resource create horizon configmap + kolla-kubernetes resource create pod keystone + kolla-kubernetes resource create svc horizon + kolla-kubernetes resource create configmap horizon sleep 30 # wait for keystone to start up - kolla-kubernetes resource create horizon pod + kolla-kubernetes resource create pod horizon Check Status of all Kolla-Kubernetes Resources @@ -221,23 +221,23 @@ Checking status is the same whether for operators or workflow engine. :: - kolla-kubernetes resource status mariadb disk - kolla-kubernetes resource status mariadb pv - kolla-kubernetes resource status mariadb pvc - kolla-kubernetes resource status mariadb svc - kolla-kubernetes resource status mariadb configmap - kolla-kubernetes resource status mariadb bootstrap - kolla-kubernetes resource status mariadb pod - kolla-kubernetes resource status memcached svc - kolla-kubernetes resource status memcached configmap - kolla-kubernetes resource status memcached pod - kolla-kubernetes resource status keystone svc - kolla-kubernetes resource status keystone configmap - kolla-kubernetes resource status keystone bootstrap - kolla-kubernetes resource status keystone pod - kolla-kubernetes resource status horizon svc - kolla-kubernetes resource status horizon configmap - kolla-kubernetes resource status horizon pod + kolla-kubernetes resource status disk mariadb + kolla-kubernetes resource status pv mariadb + kolla-kubernetes resource status pvc mariadb + kolla-kubernetes resource status svc mariadb + kolla-kubernetes resource status configmap mariadb + kolla-kubernetes resource status bootstrap mariadb + kolla-kubernetes resource status pod mariadb + kolla-kubernetes resource status svc memcached + kolla-kubernetes resource status configmap memcached + kolla-kubernetes resource status pod memcached + kolla-kubernetes resource status svc keystone + kolla-kubernetes resource status configmap keystone + kolla-kubernetes resource status bootstrap keystone + kolla-kubernetes resource status pod keystone + kolla-kubernetes resource status svc horizon + kolla-kubernetes resource status configmap horizon + kolla-kubernetes resource status pod horizon Delete all Kolla-Kubernetes Resources @@ -263,20 +263,20 @@ Workflow Engine Delete Resources :: - kolla-kubernetes resource delete horizon pod - kolla-kubernetes resource delete horizon configmap - kolla-kubernetes resource delete horizon svc - kolla-kubernetes resource delete keystone pod - kolla-kubernetes resource delete keystone bootstrap - kolla-kubernetes resource delete keystone configmap - kolla-kubernetes resource delete keystone svc - kolla-kubernetes resource delete memcached pod - kolla-kubernetes resource delete memcached configmap - kolla-kubernetes resource delete memcached svc - kolla-kubernetes resource delete mariadb pod - kolla-kubernetes resource delete mariadb bootstrap - kolla-kubernetes resource delete mariadb configmap - kolla-kubernetes resource delete mariadb svc - kolla-kubernetes resource delete mariadb pvc - kolla-kubernetes resource delete mariadb pv - kolla-kubernetes resource delete mariadb disk + kolla-kubernetes resource delete pod horizon + kolla-kubernetes resource delete configmap horizon + kolla-kubernetes resource delete svc horizon + kolla-kubernetes resource delete pod keystone + kolla-kubernetes resource delete bootstrap keystone + kolla-kubernetes resource delete configmap keystone + kolla-kubernetes resource delete svc keystone + kolla-kubernetes resource delete pod memcached + kolla-kubernetes resource delete configmap memcached + kolla-kubernetes resource delete svc memcached + kolla-kubernetes resource delete pod mariadb + kolla-kubernetes resource delete bootstrap mariadb + kolla-kubernetes resource delete configmap mariadb + kolla-kubernetes resource delete svc mariadb + kolla-kubernetes resource delete pvc mariadb + kolla-kubernetes resource delete pv mariadb + kolla-kubernetes resource delete disk mariadb diff --git a/kolla_kubernetes/commands/cmd_resource.py b/kolla_kubernetes/commands/cmd_resource.py index 04591eb19..ccd15c14b 100644 --- a/kolla_kubernetes/commands/cmd_resource.py +++ b/kolla_kubernetes/commands/cmd_resource.py @@ -11,7 +11,10 @@ # limitations under the License. from __future__ import print_function +import subprocess import sys +import tempfile +import yaml from oslo_log import log @@ -26,21 +29,16 @@ LOG = log.getLogger(__name__) KKR = KollaKubernetesResources.Get() -class Resource(KollaKubernetesBaseCommand): +class ResourceBase(KollaKubernetesBaseCommand): """Create, delete, or query status for kolla-kubernetes resources""" def get_parser(self, prog_name): - parser = super(Resource, self).get_parser(prog_name) + parser = super(ResourceBase, self).get_parser(prog_name) parser.add_argument( "action", metavar="", help=("One of [%s]" % ("|".join(Service.VALID_ACTIONS))) ) - parser.add_argument( - "service_name", - metavar="", - help=("One of [%s]" % ("|".join(KKR.getServices().keys()))) - ) parser.add_argument( "resource_type", metavar="", @@ -48,38 +46,20 @@ class Resource(KollaKubernetesBaseCommand): ) return parser - def take_action(self, args): - self.validate_args(args) - service = KKR.getServiceByName(args.service_name) - service.do_apply(args.action, args.resource_type) - def validate_args(self, args): if args.action not in Service.VALID_ACTIONS: msg = ("action [{}] not in valid actions [{}]".format( args.action, "|".join(Service.VALID_ACTIONS))) raise Exception(msg) - if args.service_name not in KKR.getServices().keys(): - msg = ("service_name [{}] not in valid service_names [{}]".format( - args.service_name, - "|".join(KKR.getServices().keys()))) - raise Exception(msg) if args.resource_type not in Service.VALID_RESOURCE_TYPES: msg = ("resource_type [{}] not in valid resource_types [{}]" .format(args.resource_type, "|".join(Service.VALID_RESOURCE_TYPES))) raise Exception(msg) - service = KKR.getServiceByName(args.service_name) - if (args.resource_type != 'configmap') and ( - len(service.getResourceTemplatesByType(args.resource_type)) == 0): - msg = ("service_name [{}] has no resource" - " files defined for type [{}]".format( - args.service_name, args.resource_type)) - raise Exception(msg) - -class ResourceTemplate(Resource): +class ResourceTemplate(ResourceBase): """Jinja process kolla-kubernetes resource template files""" # This command adds the CLI params as part of the Jinja vars for processing @@ -125,12 +105,13 @@ class ResourceTemplate(Resource): msg = ("resource-template subcommand for resource-type {} " "is not yet supported".format(args.resource_type)) raise Exception(msg) - - service = KKR.getServiceByName(args.service_name) + service_name = KKR.getServiceNameByResourceTypeName(args.resource_type, + args.resource_name) + service = KKR.getServiceByName(service_name) rt = service.getResourceTemplateByTypeAndName( args.resource_type, args.resource_name) - variables = KKR.GetJinjaDict(service.getName(), vars(args), + variables = KKR.GetJinjaDict(service_name, vars(args), args.print_jinja_keys_regex) # Merge the template vars with the jinja vars before processing @@ -152,6 +133,50 @@ class ResourceTemplate(Resource): print(res) +class Resource(ResourceTemplate): + """Create kolla-kubernetes resources""" + + def validate_args(self, args): + super(Resource, self).validate_args(args) + if args.action not in ['create', 'delete', 'status']: + msg = ("action [{}] currently not supported".format( + args.action)) + raise Exception(msg) + + def take_action(self, args): + t = super(Resource, self).take_action(args, skip_and_return=True) + y = yaml.load(t) + kind = y['kind'] + kind_map = { + 'PetSet': 'petset', + 'Pod': 'pod', + 'ReplicationController': 'rc', + 'DaemonSet': 'daemonset', + 'Job': 'job', + 'Deployment': 'deployment', + } + if kind not in kind_map: + msg = ("unknown template kind [{}].".format(kind)) + raise Exception(msg) + if args.action == 'create': + with tempfile.NamedTemporaryFile() as tf: + tf.write(t) + tf.flush() + subprocess.call("kubectl %s -f %s" % (args.action, tf.name), + shell=True) + tf.close() + elif args.action == "delete": + subprocess.call("kubectl delete %s %s" + % (kind_map[kind], + y['metadata']['name']), + shell=True) + elif args.action == 'status': + subprocess.call("kubectl get %s %s -o yaml" + % (kind_map[kind], + y['metadata']['name']), + shell=True) + + class ResourceMap(KollaKubernetesBaseCommand): """List available kolla-kubernetes resources to be created or deleted""" diff --git a/kolla_kubernetes/kube_service_status.py b/kolla_kubernetes/kube_service_status.py index 390a7405b..b7f46e7ce 100644 --- a/kolla_kubernetes/kube_service_status.py +++ b/kolla_kubernetes/kube_service_status.py @@ -140,8 +140,8 @@ class KubeResourceTemplateStatus(object): def doCheck(self): # Build the templating command - cmd = "kolla-kubernetes resource-template {} {} {} {}".format( - 'create', self.service_obj.getName(), self.resource_type, + cmd = "kolla-kubernetes resource-template {} {} {}".format( + 'create', self.resource_type, self.resource_template_obj.getName()) # Execute the command to get the processed template output diff --git a/kolla_kubernetes/service_resources.py b/kolla_kubernetes/service_resources.py index 25c03e799..900856174 100644 --- a/kolla_kubernetes/service_resources.py +++ b/kolla_kubernetes/service_resources.py @@ -103,8 +103,18 @@ class KollaKubernetesResources(object): self.filename = filename self.y = YamlUtils.yaml_dict_from_file(filename) self.services = collections.OrderedDict() - for i in self.y['kolla-kubernetes']['services']: - self.services[i['name']] = Service(i) + self.rtn2sn = {} + for service in self.y['kolla-kubernetes']['services']: + self.services[service['name']] = Service(service) + # This code creates a record: + # rtn2sn[resource_type][resource_name] = service_name + # for all resources + for (resource_type, value) in service['resources'].items(): + resource_table = self.rtn2sn.get(resource_type) + if resource_table is None: + self.rtn2sn[resource_type] = resource_table = {} + for resource in value: + resource_table[resource['name']] = service['name'] def getServices(self): return self.services @@ -116,6 +126,17 @@ class KollaKubernetesResources(object): sys.exit(1) return r[name] + def getServiceNameByResourceTypeName(self, resource_type, resource_name): + t = self.rtn2sn.get(resource_type) + if t is None: + print("unable to find resource_type={}", resource_type) + sys.exit(1) + service_name = t.get(resource_name) + if service_name is None: + print("unable to find resource_name={}", resource_name) + sys.exit(1) + return service_name + def __str__(self): s = self.__class__.__name__ for k, v in self.getServices().items(): @@ -268,8 +289,8 @@ class Service(object): for resourceTemplate in resourceTemplates: # Build the command based on if shell script or not. If # shell script, pipe to sh. Else, pipe to kubectl - cmd = "kolla-kubernetes resource-template {} {} {} {}".format( - action, self.getName(), resource_type, + cmd = "kolla-kubernetes resource-template {} {} {}".format( + action, resource_type, resourceTemplate.getName()) if resourceTemplate.getTemplatePath().endswith('.sh.j2'): cmd += " | sh" diff --git a/kolla_kubernetes/tests/test_templates.py b/kolla_kubernetes/tests/test_templates.py index ddcc1286a..bfee86663 100644 --- a/kolla_kubernetes/tests/test_templates.py +++ b/kolla_kubernetes/tests/test_templates.py @@ -53,6 +53,31 @@ def on_each_template(func): class TestTemplatesTest(base.BaseTestCase): + def test_validate_names(self): + service_names = {} + template_names = {} + for service_name in KKR.getServices(): + service_names[service_name] = True + service = KKR.getServiceByName(service_name) + for resource_type in RESOURCE_TYPES: + tnprt = template_names.get(resource_type) + if tnprt is None: + template_names[resource_type] = tnprt = {} + templates = service.getResourceTemplatesByType(resource_type) + for template in templates: + template_name = template.getName() + if service_names.get(template_name, False) and \ + len(templates) != 1: + s = "Resource name %s matches service name and" \ + " there are more then one resource." \ + % template_name + raise Exception(s) + if tnprt.get(template_name, False): + s = "Resource name %s matches another template name" \ + % template_name + raise Exception(s) + tnprt[template_name] = True + def test_validate_templates(self): def func(argobj, o): # Check if template is yaml