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
This commit is contained in:
Kevin Fox 2016-09-06 18:11:46 -07:00
parent 6c8c231bda
commit 893344a0f8
5 changed files with 159 additions and 88 deletions

View File

@ -171,7 +171,7 @@ Operator Create Resources
kolla-kubernetes bootstrap ceph # adds ceph secret, no-op for storage_provider!=ceph kolla-kubernetes bootstrap ceph # adds ceph secret, no-op for storage_provider!=ceph
kolla-kubernetes bootstrap mariadb kolla-kubernetes bootstrap mariadb
sleep 30 # wait for mariadb bootstrap to finish 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 mariadb
kolla-kubernetes run memcached kolla-kubernetes run memcached
sleep 30 # wait for mariadb and memcached to start up 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 disk mariadb
kolla-kubernetes resource create mariadb pv kolla-kubernetes resource create pv mariadb
kolla-kubernetes resource create mariadb pvc kolla-kubernetes resource create pvc mariadb
kolla-kubernetes resource create mariadb svc kolla-kubernetes resource create svc mariadb
kolla-kubernetes resource create mariadb configmap kolla-kubernetes resource create configmap mariadb
kolla-kubernetes resource create mariadb bootstrap kolla-kubernetes resource create bootstrap mariadb
sleep 30 # wait for mariadb bootstrap to finish sleep 30 # wait for mariadb bootstrap to finish
kolla-kubernetes resource delete mariadb bootstrap # workaround known issue #1 kolla-kubernetes resource delete bootstap mariadb # workaround known issue #1
kolla-kubernetes resource create mariadb pod kolla-kubernetes resource create pod mariadb
kolla-kubernetes resource create memcached svc kolla-kubernetes resource create svc memcached
kolla-kubernetes resource create memcached configmap kolla-kubernetes resource create configmap memcached
kolla-kubernetes resource create memcached pod kolla-kubernetes resource create pod memcached
kolla-kubernetes resource create keystone svc kolla-kubernetes resource create svc keystone
kolla-kubernetes resource create keystone configmap kolla-kubernetes resource create configmap keystone
sleep 30 # wait for mariadb and memcached to start up 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 sleep 30 # wait for keystone to bootstrap in mariadb
kolla-kubernetes resource create keystone pod kolla-kubernetes resource create pod keystone
kolla-kubernetes resource create horizon svc kolla-kubernetes resource create svc horizon
kolla-kubernetes resource create horizon configmap kolla-kubernetes resource create configmap horizon
sleep 30 # wait for keystone to start up 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 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 disk mariadb
kolla-kubernetes resource status mariadb pv kolla-kubernetes resource status pv mariadb
kolla-kubernetes resource status mariadb pvc kolla-kubernetes resource status pvc mariadb
kolla-kubernetes resource status mariadb svc kolla-kubernetes resource status svc mariadb
kolla-kubernetes resource status mariadb configmap kolla-kubernetes resource status configmap mariadb
kolla-kubernetes resource status mariadb bootstrap kolla-kubernetes resource status bootstrap mariadb
kolla-kubernetes resource status mariadb pod kolla-kubernetes resource status pod mariadb
kolla-kubernetes resource status memcached svc kolla-kubernetes resource status svc memcached
kolla-kubernetes resource status memcached configmap kolla-kubernetes resource status configmap memcached
kolla-kubernetes resource status memcached pod kolla-kubernetes resource status pod memcached
kolla-kubernetes resource status keystone svc kolla-kubernetes resource status svc keystone
kolla-kubernetes resource status keystone configmap kolla-kubernetes resource status configmap keystone
kolla-kubernetes resource status keystone bootstrap kolla-kubernetes resource status bootstrap keystone
kolla-kubernetes resource status keystone pod kolla-kubernetes resource status pod keystone
kolla-kubernetes resource status horizon svc kolla-kubernetes resource status svc horizon
kolla-kubernetes resource status horizon configmap kolla-kubernetes resource status configmap horizon
kolla-kubernetes resource status horizon pod kolla-kubernetes resource status pod horizon
Delete all Kolla-Kubernetes Resources Delete all Kolla-Kubernetes Resources
@ -263,20 +263,20 @@ Workflow Engine Delete Resources
:: ::
kolla-kubernetes resource delete horizon pod kolla-kubernetes resource delete pod horizon
kolla-kubernetes resource delete horizon configmap kolla-kubernetes resource delete configmap horizon
kolla-kubernetes resource delete horizon svc kolla-kubernetes resource delete svc horizon
kolla-kubernetes resource delete keystone pod kolla-kubernetes resource delete pod keystone
kolla-kubernetes resource delete keystone bootstrap kolla-kubernetes resource delete bootstrap keystone
kolla-kubernetes resource delete keystone configmap kolla-kubernetes resource delete configmap keystone
kolla-kubernetes resource delete keystone svc kolla-kubernetes resource delete svc keystone
kolla-kubernetes resource delete memcached pod kolla-kubernetes resource delete pod memcached
kolla-kubernetes resource delete memcached configmap kolla-kubernetes resource delete configmap memcached
kolla-kubernetes resource delete memcached svc kolla-kubernetes resource delete svc memcached
kolla-kubernetes resource delete mariadb pod kolla-kubernetes resource delete pod mariadb
kolla-kubernetes resource delete mariadb bootstrap kolla-kubernetes resource delete bootstrap mariadb
kolla-kubernetes resource delete mariadb configmap kolla-kubernetes resource delete configmap mariadb
kolla-kubernetes resource delete mariadb svc kolla-kubernetes resource delete svc mariadb
kolla-kubernetes resource delete mariadb pvc kolla-kubernetes resource delete pvc mariadb
kolla-kubernetes resource delete mariadb pv kolla-kubernetes resource delete pv mariadb
kolla-kubernetes resource delete mariadb disk kolla-kubernetes resource delete disk mariadb

View File

@ -11,7 +11,10 @@
# limitations under the License. # limitations under the License.
from __future__ import print_function from __future__ import print_function
import subprocess
import sys import sys
import tempfile
import yaml
from oslo_log import log from oslo_log import log
@ -26,21 +29,16 @@ LOG = log.getLogger(__name__)
KKR = KollaKubernetesResources.Get() KKR = KollaKubernetesResources.Get()
class Resource(KollaKubernetesBaseCommand): class ResourceBase(KollaKubernetesBaseCommand):
"""Create, delete, or query status for kolla-kubernetes resources""" """Create, delete, or query status for kolla-kubernetes resources"""
def get_parser(self, prog_name): 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( parser.add_argument(
"action", "action",
metavar="<action>", metavar="<action>",
help=("One of [%s]" % ("|".join(Service.VALID_ACTIONS))) help=("One of [%s]" % ("|".join(Service.VALID_ACTIONS)))
) )
parser.add_argument(
"service_name",
metavar="<service-name>",
help=("One of [%s]" % ("|".join(KKR.getServices().keys())))
)
parser.add_argument( parser.add_argument(
"resource_type", "resource_type",
metavar="<resource-type>", metavar="<resource-type>",
@ -48,38 +46,20 @@ class Resource(KollaKubernetesBaseCommand):
) )
return parser 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): def validate_args(self, args):
if args.action not in Service.VALID_ACTIONS: if args.action not in Service.VALID_ACTIONS:
msg = ("action [{}] not in valid actions [{}]".format( msg = ("action [{}] not in valid actions [{}]".format(
args.action, args.action,
"|".join(Service.VALID_ACTIONS))) "|".join(Service.VALID_ACTIONS)))
raise Exception(msg) 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: if args.resource_type not in Service.VALID_RESOURCE_TYPES:
msg = ("resource_type [{}] not in valid resource_types [{}]" msg = ("resource_type [{}] not in valid resource_types [{}]"
.format(args.resource_type, .format(args.resource_type,
"|".join(Service.VALID_RESOURCE_TYPES))) "|".join(Service.VALID_RESOURCE_TYPES)))
raise Exception(msg) 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(ResourceBase):
class ResourceTemplate(Resource):
"""Jinja process kolla-kubernetes resource template files""" """Jinja process kolla-kubernetes resource template files"""
# This command adds the CLI params as part of the Jinja vars for processing # 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 {} " msg = ("resource-template subcommand for resource-type {} "
"is not yet supported".format(args.resource_type)) "is not yet supported".format(args.resource_type))
raise Exception(msg) raise Exception(msg)
service_name = KKR.getServiceNameByResourceTypeName(args.resource_type,
service = KKR.getServiceByName(args.service_name) args.resource_name)
service = KKR.getServiceByName(service_name)
rt = service.getResourceTemplateByTypeAndName( rt = service.getResourceTemplateByTypeAndName(
args.resource_type, args.resource_name) 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) args.print_jinja_keys_regex)
# Merge the template vars with the jinja vars before processing # Merge the template vars with the jinja vars before processing
@ -152,6 +133,50 @@ class ResourceTemplate(Resource):
print(res) 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): class ResourceMap(KollaKubernetesBaseCommand):
"""List available kolla-kubernetes resources to be created or deleted""" """List available kolla-kubernetes resources to be created or deleted"""

View File

@ -140,8 +140,8 @@ class KubeResourceTemplateStatus(object):
def doCheck(self): def doCheck(self):
# Build the templating command # Build the templating command
cmd = "kolla-kubernetes resource-template {} {} {} {}".format( cmd = "kolla-kubernetes resource-template {} {} {}".format(
'create', self.service_obj.getName(), self.resource_type, 'create', self.resource_type,
self.resource_template_obj.getName()) self.resource_template_obj.getName())
# Execute the command to get the processed template output # Execute the command to get the processed template output

View File

@ -103,8 +103,18 @@ class KollaKubernetesResources(object):
self.filename = filename self.filename = filename
self.y = YamlUtils.yaml_dict_from_file(filename) self.y = YamlUtils.yaml_dict_from_file(filename)
self.services = collections.OrderedDict() self.services = collections.OrderedDict()
for i in self.y['kolla-kubernetes']['services']: self.rtn2sn = {}
self.services[i['name']] = Service(i) 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): def getServices(self):
return self.services return self.services
@ -116,6 +126,17 @@ class KollaKubernetesResources(object):
sys.exit(1) sys.exit(1)
return r[name] 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): def __str__(self):
s = self.__class__.__name__ s = self.__class__.__name__
for k, v in self.getServices().items(): for k, v in self.getServices().items():
@ -268,8 +289,8 @@ class Service(object):
for resourceTemplate in resourceTemplates: for resourceTemplate in resourceTemplates:
# Build the command based on if shell script or not. If # Build the command based on if shell script or not. If
# shell script, pipe to sh. Else, pipe to kubectl # shell script, pipe to sh. Else, pipe to kubectl
cmd = "kolla-kubernetes resource-template {} {} {} {}".format( cmd = "kolla-kubernetes resource-template {} {} {}".format(
action, self.getName(), resource_type, action, resource_type,
resourceTemplate.getName()) resourceTemplate.getName())
if resourceTemplate.getTemplatePath().endswith('.sh.j2'): if resourceTemplate.getTemplatePath().endswith('.sh.j2'):
cmd += " | sh" cmd += " | sh"

View File

@ -53,6 +53,31 @@ def on_each_template(func):
class TestTemplatesTest(base.BaseTestCase): 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 test_validate_templates(self):
def func(argobj, o): def func(argobj, o):
# Check if template is yaml # Check if template is yaml