diff --git a/service-mgmt-api/centos/build_srpm.data b/service-mgmt-api/centos/build_srpm.data index 896b6864..f0784868 100644 --- a/service-mgmt-api/centos/build_srpm.data +++ b/service-mgmt-api/centos/build_srpm.data @@ -1,4 +1,4 @@ SRC_DIR=sm-api TAR_NAME=sm-api VERSION=1.0 -TIS_PATCH_VER=2 +TIS_PATCH_VER=4 diff --git a/service-mgmt-api/centos/sm-api.spec b/service-mgmt-api/centos/sm-api.spec index a6970787..041970ea 100644 --- a/service-mgmt-api/centos/sm-api.spec +++ b/service-mgmt-api/centos/sm-api.spec @@ -36,11 +36,13 @@ Requires: cgts-mtce-common-pmon install -d %{buildroot}/etc/sm install -d %{buildroot}/etc/init.d install -d %{buildroot}/etc/pmon.d +install -d %{buildroot}/etc/sm-api install -d %{buildroot}%{_unitdir} install -m 644 %{_buildsubdir}/scripts/sm_api.ini %{buildroot}/etc/sm install -m 755 %{_buildsubdir}/scripts/sm-api %{buildroot}/etc/init.d install -m 644 %{_buildsubdir}/scripts/sm-api.service %{buildroot}%{_unitdir} install -m 644 %{_buildsubdir}/scripts/sm-api.conf %{buildroot}/etc/pmon.d +install -m 644 %{_buildsubdir}/etc/sm-api/policy.json %{buildroot}/etc/sm-api %description Service Management API @@ -72,6 +74,7 @@ Service Management API %dir "/etc/sm" "/etc/init.d/sm-api" "/etc/pmon.d/sm-api.conf" +"/etc/sm-api/policy.json" "/etc/sm/sm_api.ini" %{_unitdir}/* diff --git a/service-mgmt-api/sm-api/etc/sm-api/policy.json b/service-mgmt-api/sm-api/etc/sm-api/policy.json new file mode 100644 index 00000000..94ac3a5b --- /dev/null +++ b/service-mgmt-api/sm-api/etc/sm-api/policy.json @@ -0,0 +1,5 @@ +{ + "admin": "role:admin or role:administrator", + "admin_api": "is_admin:True", + "default": "rule:admin_api" +} diff --git a/service-mgmt-api/sm-api/scripts/sm-api b/service-mgmt-api/sm-api/scripts/sm-api index 54e93ac6..10950564 100755 --- a/service-mgmt-api/sm-api/scripts/sm-api +++ b/service-mgmt-api/sm-api/scripts/sm-api @@ -1,6 +1,6 @@ #! /bin/sh # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -32,6 +32,7 @@ LSB_NOT_RUNNING=7 SM_API_NAME="sm-api" SM_API="/usr/bin/${SM_API_NAME}" +SM_API_CONFIG_FILE="/etc/sm-api/sm-api.conf" daemon_pidfile="/var/run/${SM_API_NAME}.pid" @@ -51,7 +52,7 @@ case "$1" in echo -n "is already running " RETVAL=0 else - /bin/sh -c "${SM_API} --debug --verbose --use-syslog --syslog-log-facility local1"' >> /dev/null 2>&1 & echo $!' > ${daemon_pidfile} + /bin/sh -c "${SM_API} --config-file=${SM_API_CONFIG_FILE} --verbose --use-syslog --syslog-log-facility local1"' >> /dev/null 2>&1 & echo $!' > ${daemon_pidfile} RETVAL=$? fi if [ ${RETVAL} -eq 0 ] ; then diff --git a/service-mgmt-api/sm-api/sm_api/api/app.py b/service-mgmt-api/sm-api/sm_api/api/app.py index 1f134738..4802e21a 100644 --- a/service-mgmt-api/sm-api/sm_api/api/app.py +++ b/service-mgmt-api/sm-api/sm_api/api/app.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -11,16 +11,16 @@ Application from oslo_config import cfg import pecan +from sm_api.api import acl from sm_api.api import config from sm_api.api import hooks - -from sm_api.api import acl from sm_api.api import middleware +from sm_api.common import policy auth_opts = [ cfg.StrOpt('auth_strategy', - default='noauth', + default='keystone', help='Method to use for auth: noauth or keystone.'), ] @@ -52,6 +52,8 @@ def create_app(): def setup_app(pecan_config=None, extra_hooks=None): + policy.init() + app_hooks = [hooks.ConfigHook(), hooks.DatabaseHook(), hooks.ContextHook(pecan_config.app.acl_public_routes), diff --git a/service-mgmt-api/sm-api/sm_api/api/config.py b/service-mgmt-api/sm-api/sm_api/api/config.py index fb5113d4..7e097e94 100644 --- a/service-mgmt-api/sm-api/sm_api/api/config.py +++ b/service-mgmt-api/sm-api/sm_api/api/config.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -12,6 +12,6 @@ app = {'root': 'sm_api.api.controllers.root.RootController', 'modules': ['sm_api'], 'static_root': '', 'debug': False, - 'enable_acl': False, + 'enable_acl': True, 'acl_public_routes': ['/', '/v1'] } diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/__init__.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/__init__.py index 109021da..79c1d5b5 100644 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/__init__.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/__init__.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -28,14 +28,20 @@ class Version1(wsme_types.Base): links = [link.Link] "Links that point to a specific URL for this version and documentation" - service_group = [link.Link] + nodes = [link.Link] + "Links to the SM node resource" + + service_groups = [link.Link] "Links to the SM service-group resource" + services = [link.Link] + "Links to the SM service resource" + servicenode = [link.Link] - "Links to the SM service node resource" + "Links to the SM node operation resource" sm_sda = [link.Link] - "Links to the SM service domain assignments resource " + "Links to the SM service domain assignement resource" @classmethod def convert(cls): @@ -43,6 +49,14 @@ class Version1(wsme_types.Base): v1.id = "v1" v1.links = [link.Link.make_link('self', pecan.request.host_url, 'v1', '', bookmark=True)] + v1.nodes = [link.Link.make_link('self', + pecan.request.host_url, + 'nodes', ''), + link.Link.make_link('bookmark', + pecan.request.host_url, + 'nodes', '', + bookmark=True)] + v1.service_groups = [link.Link.make_link('self', pecan.request.host_url, 'service_groups', ''), @@ -61,26 +75,17 @@ class Version1(wsme_types.Base): v1.servicenode = [link.Link.make_link('self', pecan.request.host_url, 'servicenode', ''), - link.Link.make_link('bookmark', - pecan.request.host_url, - 'servicenode', '', - bookmark=True)] - + link.Link.make_link('bookmark', + pecan.request.host_url, + 'servicenode', '', + bookmark=True)] v1.sm_sda = [link.Link.make_link('self', pecan.request.host_url, 'sm_sda', ''), - link.Link.make_link('bookmark', - pecan.request.host_url, - 'sm_sda', '', - bookmark=True)] - - v1.nodes = [link.Link.make_link('self', + link.Link.make_link('bookmark', pecan.request.host_url, - 'nodes', ''), - link.Link.make_link('bookmark', - pecan.request.host_url, - 'nodes', '', - bookmark=True)] + 'sm_sda', '', + bookmark=True)] return v1 diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/nodes.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/nodes.py index 54345da5..fdf76fd1 100644 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/nodes.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/nodes.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -15,7 +15,7 @@ from sm_api.api.controllers.v1 import base from sm_api.api.controllers.v1 import collection from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import utils - +from sm_api.common import exception from sm_api.common import log from sm_api import objects @@ -112,7 +112,10 @@ class NodesController(rest.RestController): @wsme_pecan.wsexpose(Nodes, unicode) def get_one(self, uuid): - rpc_sg = objects.sm_node.get_by_uuid(pecan.request.context, uuid) + try: + rpc_sg = objects.sm_node.get_by_uuid(pecan.request.context, uuid) + except exception.ServerNotFound: + return None return Nodes.convert_with_links(rpc_sg) diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/service_groups.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/service_groups.py index 8cb8edab..973f9d03 100644 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/service_groups.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/service_groups.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -15,7 +15,7 @@ from sm_api.api.controllers.v1 import base from sm_api.api.controllers.v1 import collection from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import utils - +from sm_api.common import exception from sm_api.common import log from sm_api import objects @@ -43,27 +43,32 @@ class ServiceGroupCommandResult(wsme_types.Base): class ServiceGroup(base.APIBase): - name = wsme_types.text - state = wsme_types.text - status = wsme_types.text - - # JKUNG new - uuid = wsme_types.text - "The UUID of the service_groups" - id = int + uuid = wsme_types.text + "The UUID of the sm_sda" + + name = wsme_types.text + node_name = wsme_types.text + service_group_name = wsme_types.text + state = wsme_types.text + desired_state = wsme_types.text + status = wsme_types.text + condition = wsme_types.text links = [link.Link] - "A list containing a self link and associated service_groups links" + "A list containing a self link and associated sm_sda links" def __init__(self, **kwargs): - self.fields = objects.service_groups.fields.keys() + self.fields = objects.sm_sda.fields.keys() for k in self.fields: setattr(self, k, kwargs.get(k)) @classmethod def convert_with_links(cls, rpc_service_groups, expand=True): - minimum_fields = ['id', 'name', 'state', 'status'] + minimum_fields = ['id', 'uuid', 'name', 'node_name', + 'service_group_name', 'desired_state', + 'state', 'status', 'condition'] + fields = minimum_fields if not expand else None service_groups = ServiceGroup.from_rpc_object( rpc_service_groups, fields) @@ -86,7 +91,7 @@ class ServiceGroupCollection(collection.Collection): collection = ServiceGroupCollection() collection.service_groups = [ ServiceGroup.convert_with_links(ch, expand) - for ch in service_groups] + for ch in service_groups] url = url or None collection.next = collection.get_next(limit, url=url, **kwargs) return collection @@ -104,20 +109,29 @@ class ServiceGroupController(rest.RestController): sort_dir = utils.validate_sort_dir(sort_dir) marker_obj = None if marker: - marker_obj = objects.service_groups.get_by_uuid( - pecan.request.context, marker) + marker_obj = objects.sm_sda.get_by_uuid(pecan.request.context, + marker) - service_groups = pecan.request.dbapi.iservicegroup_get_list(limit, - marker_obj, - sort_key=sort_key, - sort_dir=sort_dir) - return service_groups + sm_sdas = pecan.request.dbapi.sm_sda_get_list(limit, + marker_obj, + sort_key=sort_key, + sort_dir=sort_dir) + + # Remap OpenStack_Services to Cloud_Services + for sm_sda in sm_sdas: + if sm_sda.service_group_name.lower() == "openstack_services": + sm_sda.service_group_name = "Cloud_Services" + + return sm_sdas @wsme_pecan.wsexpose(ServiceGroup, unicode) def get_one(self, uuid): - rpc_sg = objects.service_groups.get_by_uuid(pecan.request.context, uuid) + try: + rpc_sg = objects.sm_sda.get_by_uuid(pecan.request.context, uuid) + except exception.ServerNotFound: + return None - return ServiceGroup.convert_with_links(rpc_sg) + return ServiceGroup.convert_with_links(rpc_sg) @wsme_pecan.wsexpose(ServiceGroupCollection, unicode, int, unicode, unicode) @@ -134,23 +148,6 @@ class ServiceGroupController(rest.RestController): sort_key=sort_key, sort_dir=sort_dir) - # cursor = pecan.request.database.cursor() - - # cursor.execute("SELECT name, state from service_groups") - - # data = cursor.fetchall() - - # if data is not None: - # service_groups = [] - - # for row in data: - # service_groups.append({'name': row[0], 'state': row[1]}) - - # return ServiceGroups(service_groups=json.dumps(service_groups)) - - #return wsme.api.Response(ServiceGroups(service_groups=json.dumps([])), - # status_code=404) - @wsme_pecan.wsexpose(ServiceGroupCommandResult, unicode, body=ServiceGroupCommand) def put(self, hostname, command): diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/servicenode.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/servicenode.py index 85f97832..b3abb19f 100755 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/servicenode.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/servicenode.py @@ -118,8 +118,6 @@ LOCAL_HOST_NAME = socket.gethostname() def rest_api_request(token, method, api_cmd, api_cmd_headers=None, api_cmd_payload=None, timeout=10): - - """ Make a rest-api request Returns: response as a dictionary @@ -133,7 +131,7 @@ def rest_api_request(token, method, api_cmd, api_cmd_headers=None, request_info = urllib2.Request(api_cmd) request_info.get_method = lambda: method if token: - request_info.add_header("X-Auth-Token", token.get_id()) + request_info.add_header("X-Auth-Token", token) request_info.add_header("Accept", "application/json") if api_cmd_headers is not None: @@ -155,9 +153,6 @@ def rest_api_request(token, method, api_cmd, api_cmd_headers=None, LOG.info("Response=%s" % response) except urllib2.HTTPError as e: - if 401 == e.code: - if token: - token.set_expired() LOG.warn("HTTP Error e.code=%s e=%s" % (e.code, e)) if hasattr(e, 'msg') and e.msg: response = json.loads(e.msg) @@ -438,8 +433,12 @@ class ServiceNodeController(rest.RestController): api_cmd_headers['Content-type'] = "application/json" api_cmd_headers['Accept'] = "application/json" api_cmd_headers['User-Agent'] = "sm/1.0" - - response = rest_api_request(None, "GET", api_cmd, api_cmd_headers, None) + auth_token = pecan.request.context.auth_token + response = rest_api_request(auth_token, + "GET", + api_cmd, + api_cmd_headers, + None) return response diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/services.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/services.py index 6b47f1b0..391f072a 100644 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/services.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/services.py @@ -15,11 +15,10 @@ from sm_api.api.controllers.v1 import base from sm_api.api.controllers.v1 import collection from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import utils - +from sm_api.common import exception from sm_api.common import log from sm_api import objects - LOG = log.get_logger(__name__) @@ -112,12 +111,19 @@ class ServicesController(rest.RestController): @wsme_pecan.wsexpose(Services, unicode) def get_one(self, uuid): - rpc_sg = objects.service.get_by_uuid(pecan.request.context, uuid) + try: + rpc_sg = objects.service.get_by_uuid(pecan.request.context, uuid) + except exception.ServerNotFound: + return None + return Services.convert_with_links(rpc_sg) @wsme_pecan.wsexpose(Services, unicode) def get_service(self, name): - rpc_sg = objects.service.get_by_name(pecan.request.context, name) + try: + rpc_sg = objects.service.get_by_name(pecan.request.context, name) + except exception.ServerNotFound: + return None return Services.convert_with_links(rpc_sg) @wsme_pecan.wsexpose(ServicesCollection, unicode, int, diff --git a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/sm_sda.py b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/sm_sda.py index 42707213..5a5a8500 100755 --- a/service-mgmt-api/sm-api/sm_api/api/controllers/v1/sm_sda.py +++ b/service-mgmt-api/sm-api/sm_api/api/controllers/v1/sm_sda.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -15,7 +15,7 @@ from sm_api.api.controllers.v1 import base from sm_api.api.controllers.v1 import collection from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import utils - +from sm_api.common import exception from sm_api.common import log from sm_api import objects @@ -125,12 +125,10 @@ class SmSdaController(rest.RestController): @wsme_pecan.wsexpose(SmSda, unicode) def get_one(self, uuid): - - rpc_sda = objects.sm_sda.get_by_uuid(pecan.request.context, uuid) - - # temp: remap OpenStack_Services to Cloud_Services - if rpc_sda.service_group_name.lower() == "openstack_services": - rpc_sda.service_group_name = "Cloud_Services" + try: + rpc_sda = objects.sm_sda.get_by_uuid(pecan.request.context, uuid) + except exception.ServerNotFound: + return None return SmSda.convert_with_links(rpc_sda) diff --git a/service-mgmt-api/sm-api/sm_api/api/hooks.py b/service-mgmt-api/sm-api/sm_api/api/hooks.py index 17490aad..84f94ad9 100644 --- a/service-mgmt-api/sm-api/sm_api/api/hooks.py +++ b/service-mgmt-api/sm-api/sm_api/api/hooks.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2014 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -19,8 +19,6 @@ from sm_api.db import api as dbapi from sm_api.openstack.common import policy - - class ConfigHook(hooks.PecanHook): def __init__(self): super(ConfigHook, self).__init__() @@ -76,7 +74,7 @@ class ContextHook(hooks.PecanHook): auth_token = state.request.headers.get('X-Auth-Token', None) creds = {'roles': state.request.headers.get('X-Roles', '').split(',')} - is_admin = policy.check('is_admin', state.request.headers, creds) + is_admin = policy.check('admin', state.request.headers, creds) path = utils.safe_rstrip(state.request.path, '/') is_public_api = path in self.public_api_routes diff --git a/service-mgmt-api/sm-api/sm_api/api/middleware/auth_token.py b/service-mgmt-api/sm-api/sm_api/api/middleware/auth_token.py index 0229a833..dfac8535 100644 --- a/service-mgmt-api/sm-api/sm_api/api/middleware/auth_token.py +++ b/service-mgmt-api/sm-api/sm_api/api/middleware/auth_token.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -21,6 +21,7 @@ class AuthTokenMiddleware(auth_token.AuthProtocol): """ def __init__(self, app, conf, public_api_routes=[]): + self.smapi_app = app self.public_api_routes = set(public_api_routes) super(AuthTokenMiddleware, self).__init__(app, conf) @@ -29,6 +30,6 @@ class AuthTokenMiddleware(auth_token.AuthProtocol): path = utils.safe_rstrip(env.get('PATH_INFO'), '/') if path in self.public_api_routes: - return self.app(env, start_response) + return self.smapi_app(env, start_response) return super(AuthTokenMiddleware, self).__call__(env, start_response) diff --git a/service-mgmt-api/sm-api/sm_api/cmd/api.py b/service-mgmt-api/sm-api/sm_api/cmd/api.py index b44b90ac..36fb90cb 100644 --- a/service-mgmt-api/sm-api/sm_api/cmd/api.py +++ b/service-mgmt-api/sm-api/sm_api/cmd/api.py @@ -66,14 +66,13 @@ def main(): # Parse config file and command line options, then start logging # Periodically check every minute for want_sm_config - while os.path.exists("/etc/sm/.not_want_sm_config"): - time.sleep(60) + LOG = log.getLogger(__name__) sm_api_service.prepare_service(sys.argv) # Build and start the WSGI app - host = socket.gethostname() - port = 7777 + host = CONF.sm_api_bind_ip or socket.gethostname() + port = CONF.sm_api_port addrinfo_list = socket.getaddrinfo(host, port) addrinfo = addrinfo_list[0] @@ -88,7 +87,6 @@ def main(): server_class=server_cls, handler_class=get_handler_cls()) - LOG = log.getLogger(__name__) LOG.info("Serving on http://%(host)s:%(port)s" % {'host': host, 'port': port}) LOG.info("Configuration:") diff --git a/service-mgmt-api/sm-api/sm_api/db/sqlalchemy/api.py b/service-mgmt-api/sm-api/sm_api/db/sqlalchemy/api.py index 11f2e783..fd5ab963 100755 --- a/service-mgmt-api/sm-api/sm_api/db/sqlalchemy/api.py +++ b/service-mgmt-api/sm-api/sm_api/db/sqlalchemy/api.py @@ -76,7 +76,7 @@ def model_query(model, *args, **kwargs): return query -def add_identity_filter(query, value, use_name=False): +def add_identity_filter(query, value, model, use_name=False): """Adds an identity filter to a query. Filters results by ID, if supplied value is a valid integer. @@ -86,9 +86,9 @@ def add_identity_filter(query, value, use_name=False): :param value: Value for filtering results by. :return: Modified query. """ - if utils.is_int_like(value): + if utils.is_int_like(value) and hasattr(model, "id"): return query.filter_by(id=value) - elif uuidutils.is_uuid_like(value): + elif uuidutils.is_uuid_like(value) and hasattr(model, "uuid"): return query.filter_by(uuid=value) else: if use_name: @@ -129,7 +129,8 @@ class Connection(api.Connection): @objects.objectify(objects.service_groups) def iservicegroup_get(self, server): query = model_query(models.iservicegroup) - query = add_identity_filter(query, server, use_name=True) + query = add_identity_filter( + query, server, models.iservicegroup, use_name=True) try: result = query.one() @@ -149,7 +150,8 @@ class Connection(api.Connection): # server may be passed as a string. It may be uuid or Int. # server = int(server) query = model_query(models.service) - query = add_identity_filter(query, server, use_name=True) + query = add_identity_filter( + query, server, models.service, use_name=True) try: result = query.one() @@ -191,7 +193,8 @@ class Connection(api.Connection): @objects.objectify(objects.sm_sda) def sm_sda_get(self, server): query = model_query(models.sm_sda) - query = add_identity_filter(query, server, use_name=True) + query = add_identity_filter( + query, server, models.sm_sda, use_name=True) try: result = query.one() @@ -215,7 +218,8 @@ class Connection(api.Connection): @objects.objectify(objects.sm_node) def sm_node_get(self, server): query = model_query(models.sm_node) - query = add_identity_filter(query, server, use_name=True) + query = add_identity_filter( + query, server, models.sm_node, use_name=True) try: result = query.one() @@ -240,7 +244,8 @@ class Connection(api.Connection): # server may be passed as a string. It may be uuid or Int. # server = int(server) query = model_query(models.service) - query = add_identity_filter(query, server, use_name=True) + query = add_identity_filter( + query, server, models.service, use_name=True) try: result = query.one() diff --git a/service-mgmt-client/centos/build_srpm.data b/service-mgmt-client/centos/build_srpm.data index fbbec207..2f139812 100644 --- a/service-mgmt-client/centos/build_srpm.data +++ b/service-mgmt-client/centos/build_srpm.data @@ -1,4 +1,4 @@ SRC_DIR=sm-client TAR_NAME=sm-client VERSION=1.0 -TIS_PATCH_VER=1 +TIS_PATCH_VER=2 diff --git a/service-mgmt-client/centos/sm-client.spec b/service-mgmt-client/centos/sm-client.spec index 8e207155..2bb525e0 100644 --- a/service-mgmt-client/centos/sm-client.spec +++ b/service-mgmt-client/centos/sm-client.spec @@ -23,6 +23,8 @@ Requires: python-libs %install %global _buildsubdir %{_builddir}/%{name}-%{version} %{__python2} setup.py install -O1 --skip-build --root %{buildroot} +install -d %{buildroot}/usr/bin +install -m 755 %{_buildsubdir}/usr/bin/smc %{buildroot}/usr/bin %description Service Management Client and CLI @@ -46,6 +48,7 @@ Service Management Client and CLI %defattr(-,root,root,-) %dir "/usr/lib/python2.7/site-packages/sm_client" /usr/lib/python2.7/site-packages/sm_client/* +"/usr/bin/smc" %dir "/usr/lib/python2.7/site-packages/sm_client-1.0.0-py2.7.egg-info" /usr/lib/python2.7/site-packages/sm_client-1.0.0-py2.7.egg-info/* diff --git a/service-mgmt-client/sm-client/sm_client/client.py b/service-mgmt-client/sm-client/sm_client/client.py index 8fb21bc2..ae77e387 100644 --- a/service-mgmt-client/sm-client/sm_client/client.py +++ b/service-mgmt-client/sm-client/sm_client/client.py @@ -1,13 +1,12 @@ # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # from sm_client.common import utils -from keystoneclient.v2_0 import client as ksclient - +from keystoneclient.v3 import client as ksclient def _get_ksclient(**kwargs): """Get an endpoint and auth token from Keystone. @@ -21,17 +20,19 @@ def _get_ksclient(**kwargs): """ return ksclient.Client(username=kwargs.get('username'), password=kwargs.get('password'), - tenant_id=kwargs.get('tenant_id'), - tenant_name=kwargs.get('tenant_name'), + user_domain_name=kwargs.get('user_domain_name'), + project_domain_name=kwargs.get('project_domain_name'), + project_name=kwargs.get('project_name'), auth_url=kwargs.get('auth_url'), + cacert=kwargs.get('os_cacert'), insecure=kwargs.get('insecure')) def _get_endpoint(client, **kwargs): """Get an endpoint using the provided keystone client.""" return client.service_catalog.url_for( - service_type=kwargs.get('service_type') or 'baremetal', - endpoint_type=kwargs.get('endpoint_type') or 'publicURL', + service_type=kwargs.get('service_name') or 'smapi', + endpoint_type=kwargs.get('endpoint_type') or 'public', region_name=kwargs.get('os_region_name') or 'RegionOne') @@ -54,31 +55,30 @@ def get_client(api_version, **kwargs): if kwargs.get('os_auth_token') and kwargs.get('smc_url'): token = kwargs.get('os_auth_token') endpoint = kwargs.get('smc_url') + auth_ref = None elif (kwargs.get('os_username') and kwargs.get('os_password') and - kwargs.get('os_auth_url') and - (kwargs.get('os_tenant_id') or kwargs.get('os_tenant_name'))): + kwargs.get('os_auth_url')): ks_kwargs = { 'username': kwargs.get('os_username'), 'password': kwargs.get('os_password'), - 'tenant_id': kwargs.get('os_tenant_id'), - 'tenant_name': kwargs.get('os_tenant_name'), 'auth_url': kwargs.get('os_auth_url'), + 'project_id': kwargs.get('os_project_id'), + 'project_name': kwargs.get('os_project_name'), + 'user_domain_id': kwargs.get('os_user_domain_id'), + 'user_domain_name': kwargs.get('os_user_domain_name'), + 'project_domain_id': kwargs.get('os_project_domain_id'), + 'project_domain_name': kwargs.get('os_project_domain_name'), 'service_type': kwargs.get('os_service_type'), 'endpoint_type': kwargs.get('os_endpoint_type'), 'insecure': kwargs.get('insecure'), } _ksclient = _get_ksclient(**ks_kwargs) - token = ((lambda: kwargs.get('os_auth_token')) - if kwargs.get('os_auth_token') - else (lambda: _ksclient.auth_token)) - + token = kwargs.get('os_auth_token') if kwargs.get('os_auth_token') else _ksclient.auth_ref.auth_token ep_kwargs = { 'username': kwargs.get('os_username'), 'password': kwargs.get('os_password'), - 'tenant_id': kwargs.get('os_tenant_id'), - 'tenant_name': kwargs.get('os_tenant_name'), 'auth_url': kwargs.get('os_auth_url'), 'service_type': kwargs.get('os_service_type'), 'endpoint_type': kwargs.get('os_endpoint_type'), @@ -89,8 +89,7 @@ def get_client(api_version, **kwargs): endpoint = kwargs.get('smc_url') or \ _get_endpoint(_ksclient, **ep_kwargs) - #region_name=kwargs.get('os_region_name') or 'RegionOne' - # neutron_endpoint = _get_endpoint(_ksclient, service_type='network', endpoint_type='internalURL', region_name=region_name ) + auth_ref = _ksclient.auth_ref cli_kwargs = { 'token': token, @@ -99,7 +98,8 @@ def get_client(api_version, **kwargs): 'ca_file': kwargs.get('ca_file'), 'cert_file': kwargs.get('cert_file'), 'key_file': kwargs.get('key_file'), - # 'neutron_endpoint': neutron_endpoint, + 'auth_ref': auth_ref, + 'auth_url': kwargs.get('os_auth_url'), } return Client(api_version, endpoint, **cli_kwargs) diff --git a/service-mgmt-client/sm-client/sm_client/common/utils.py b/service-mgmt-client/sm-client/sm_client/common/utils.py index 9b596ced..1f4af8a8 100644 --- a/service-mgmt-client/sm-client/sm_client/common/utils.py +++ b/service-mgmt-client/sm-client/sm_client/common/utils.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # @@ -118,11 +118,42 @@ def print_tuple_list(tuples, tuple_labels=[]): print pt.get_string() -def print_dict(d, dict_property="Property", wrap=0): +def print_mapping(data, fields, dict_property="Property", wrap=0): pt = prettytable.PrettyTable([dict_property, 'Value'], caching=False, print_empty=False) pt.align = 'l' - for k, v in d.iteritems(): + for k in fields: + if hasattr(data, k): + v = getattr(data, k, '') + else: + v = '' + # convert dict to str to check length + if isinstance(v, dict): + v = str(v) + if wrap > 0: + v = textwrap.fill(str(v), wrap) + # if value has a newline, add in multiple rows + # e.g. fault with stacktrace + if v and isinstance(v, basestring) and r'\n' in v: + lines = v.strip().split(r'\n') + col1 = k + for line in lines: + pt.add_row([col1, line]) + col1 = '' + else: + pt.add_row([k, v]) + print pt.get_string() + +def print_dict(d, fields, dict_property="Property", wrap=0): + pt = prettytable.PrettyTable([dict_property, 'Value'], + caching=False, print_empty=False) + pt.align = 'l' + for k in fields: + if k in d: + v = d[k] + else: + v = '' + # convert dict to str to check length if isinstance(v, dict): v = str(v) diff --git a/service-mgmt-client/sm-client/sm_client/exc.py b/service-mgmt-client/sm-client/sm_client/exc.py index 5486b01e..87b44bbb 100644 --- a/service-mgmt-client/sm-client/sm_client/exc.py +++ b/service-mgmt-client/sm-client/sm_client/exc.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -14,7 +14,7 @@ class BaseException(Exception): self.message = message def __str__(self): - return self.message or self.__class__.__doc__ + return str(self.message) or self.__class__.__doc__ class CommandError(BaseException): @@ -41,8 +41,8 @@ class HTTPException(ClientException): self.details = details def __str__(self): - return self.details or "%s (HTTP %s)" % (self.__class__.__name__, - self.code) + return str(self.details) or "%s (HTTP %s)" % (self.__class__.__name__, + self.code) class HTTPMultipleChoices(HTTPException): @@ -134,7 +134,7 @@ class HTTPServiceUnavailable(ServiceUnavailable): pass -#NOTE(bcwaldon): Build a mapping of HTTP codes to corresponding exception +# NOTE(bcwaldon): Build a mapping of HTTP codes to corresponding exception # classes _code_map = {} for obj_name in dir(sys.modules[__name__]): @@ -143,10 +143,11 @@ for obj_name in dir(sys.modules[__name__]): _code_map[obj.code] = obj -def from_response(response, error=None): +def from_response(response, message=None, traceback=None, + method=None, url=None): """Return an instance of an HTTPException based on httplib response.""" cls = _code_map.get(response.status, HTTPException) - return cls(error) + return cls(message) class NoTokenLookupException(Exception): @@ -159,8 +160,18 @@ class EndpointNotFound(Exception): pass +class AmbiguousAuthSystem(ClientException): + """Could not obtain token and endpoint using provided credentials.""" + pass + +# Alias for backwards compatibility +AmbigiousAuthSystem = AmbiguousAuthSystem + + class InvalidAttribute(ClientException): pass + class InvalidAttributeValue(ClientException): pass +# diff --git a/service-mgmt-client/sm-client/sm_client/shell.py b/service-mgmt-client/sm-client/sm_client/shell.py index c9bdba79..b25d51be 100644 --- a/service-mgmt-client/sm-client/sm_client/shell.py +++ b/service-mgmt-client/sm-client/sm_client/shell.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2015 Wind River Systems, Inc. +# Copyright (c) 2014-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -12,6 +12,7 @@ Command-line interface for Service Manager (SM) import argparse import httplib2 import logging +import socket import sys import sm_client @@ -97,20 +98,6 @@ class SmcShell(object): parser.add_argument('--os_password', help=argparse.SUPPRESS) - parser.add_argument('--os-tenant-id', - default=utils.env('OS_TENANT_ID'), - help='Defaults to env[OS_TENANT_ID]') - - parser.add_argument('--os_tenant_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-tenant-name', - default=utils.env('OS_TENANT_NAME'), - help='Defaults to env[OS_TENANT_NAME]') - - parser.add_argument('--os_tenant_name', - help=argparse.SUPPRESS) - parser.add_argument('--os-auth-url', default=utils.env('OS_AUTH_URL'), help='Defaults to env[OS_AUTH_URL]') @@ -132,9 +119,11 @@ class SmcShell(object): parser.add_argument('--os_auth_token', help=argparse.SUPPRESS) + smc_url = "http://{host}:{port}".format( + host=socket.gethostname(), port=7777) parser.add_argument('--smc-url', # default=utils.env('SMC_URL'), - default="http://localhost:7777", + default=smc_url, help='Defaults to env[SMC_URL]') parser.add_argument('--smc_url', @@ -163,6 +152,36 @@ class SmcShell(object): parser.add_argument('--os_endpoint_type', help=argparse.SUPPRESS) + parser.add_argument('--os-user-domain-id', + default=utils.env('OS_USER_DOMAIN_ID'), + help='Defaults to env[OS_USER_DOMAIN_ID].') + + parser.add_argument('--os-user-domain-name', + default=utils.env('OS_USER_DOMAIN_NAME'), + help='Defaults to env[OS_USER_DOMAIN_NAME].') + + parser.add_argument('--os-project-id', + default=utils.env('OS_PROJECT_ID'), + help='Another way to specify tenant ID. ' + 'This option is mutually exclusive with ' + ' --os-tenant-id. ' + 'Defaults to env[OS_PROJECT_ID].') + + parser.add_argument('--os-project-name', + default=utils.env('OS_PROJECT_NAME'), + help='Another way to specify tenant name. ' + 'This option is mutually exclusive with ' + ' --os-tenant-name. ' + 'Defaults to env[OS_PROJECT_NAME].') + + parser.add_argument('--os-project-domain-id', + default=utils.env('OS_PROJECT_DOMAIN_ID'), + help='Defaults to env[OS_PROJECT_DOMAIN_ID].') + + parser.add_argument('--os-project-domain-name', + default=utils.env('OS_PROJECT_DOMAIN_NAME'), + help='Defaults to env[OS_PROJECT_DOMAIN_NAME].') + return parser def get_subcommand_parser(self, version): @@ -223,11 +242,6 @@ class SmcShell(object): "either --os-password or via " "env[OS_PASSWORD]") - if not (args.os_tenant_id or args.os_tenant_name): - raise exc.CommandError("You must provide a tenant_id via " - "either --os-tenant-id or via " - "env[OS_TENANT_ID]") - if not args.os_auth_url: raise exc.CommandError("You must provide an auth url via " "either --os-auth-url or via " diff --git a/service-mgmt-client/sm-client/sm_client/v1/client.py b/service-mgmt-client/sm-client/sm_client/v1/client.py index 51ba4fcd..c1d6d614 100644 --- a/service-mgmt-client/sm-client/sm_client/v1/client.py +++ b/service-mgmt-client/sm-client/sm_client/v1/client.py @@ -13,16 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # from sm_client.common import http -from sm_client.v1 import iservice -from sm_client.v1 import iservicegroup from sm_client.v1 import sm_sda -from sm_client.v1 import smservicenode from sm_client.v1 import sm_nodes +from sm_client.v1 import smc_service +from sm_client.v1 import smc_service_node +from sm_client.v1 import smc_servicegroup class Client(http.HTTPClient): @@ -38,8 +38,8 @@ class Client(http.HTTPClient): def __init__(self, *args, **kwargs): """Initialize a new client for the Smc v1 API.""" super(Client, self).__init__(*args, **kwargs) - self.iservice = iservice.iServiceManager(self) - self.iservicegroup = iservicegroup.iServiceGroupManager(self) self.sm_sda = sm_sda.Sm_SdaManager(self) self.sm_nodes = sm_nodes.Sm_NodesManager(self) - self.smservicenode = smservicenode.smServiceNodeManager(self) + self.smc_service = smc_service.SmcServiceManager(self) + self.smc_service_node = smc_service_node.SmcNodeManager(self) + self.smc_servicegroup = smc_servicegroup.SmcServiceGroupManager(self) diff --git a/service-mgmt-client/sm-client/sm_client/v1/iservice.py b/service-mgmt-client/sm-client/sm_client/v1/iservice.py deleted file mode 100644 index 88698f59..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/iservice.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright © 2013 Red Hat, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import base -from sm_client import exc - - -CREATION_ATTRIBUTES = ['name', 'hostname', 'state', 'activity', 'reason'] -# missing forihostid - - -class iService(base.Resource): - def __repr__(self): - return "" % self._info - - -class iServiceManager(base.Manager): - resource_class = iService - - @staticmethod - def _path(id=None): - return '/v1/services/%s' % id if id else '/v1/services' - - def list(self): - return self._list(self._path(), "services") - - def get(self, iservice_id): - try: - return self._list(self._path(iservice_id))[0] - except IndexError: - return None - - def create(self, **kwargs): - new = {} - for (key, value) in kwargs.items(): - if key in CREATION_ATTRIBUTES: - new[key] = value - else: - raise exc.InvalidAttribute() - return self._create(self._path(), new) - - def delete(self, iservice_id): - return self._delete(self._path(iservice_id)) - - def update(self, iservice_id, patch): - return self._update(self._path(iservice_id), patch) diff --git a/service-mgmt-client/sm-client/sm_client/v1/iservice_shell.py b/service-mgmt-client/sm-client/sm_client/v1/iservice_shell.py deleted file mode 100644 index ed850abe..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/iservice_shell.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import utils -from sm_client import exc - - -def _print_iservice_show(iservice): - fields = ['id', 'name', 'desired_state', 'state', 'status'] - data = dict([(f, getattr(iservice, f, '')) for f in fields]) - utils.print_dict(data, wrap=72) - - -# These are now part of the "system" command -def donot_service_list(cc, args): - """List services.""" - iservice = cc.iservice.list() - fields = ['id', 'name', 'desired_state', 'state', 'status'] - field_labels = ['id', 'name', 'desired_state', 'state', 'status'] - - utils.print_list(iservice, fields, field_labels, sortby=1) - - -@utils.arg('iservice', metavar='', help="ID of iservice") -def donot_service_show(cc, args): - """Show a service.""" - try: - iservice = cc.iservice.get(args.iservice) - except exc.HTTPNotFound: - raise exc.CommandError('service not found: %s' % args.iservice) - else: - _print_iservice_show(iservice) - - -@utils.arg('-c', '--servicename', - metavar='', - help='servicename of the service [REQUIRED]') -@utils.arg('-n', '--hostname', - metavar='', - help='hostname of the service [REQUIRED]') -@utils.arg('-s', '--state', - metavar='', - help='state of the service [REQUIRED]') -@utils.arg('-a', '--activity', - metavar="", - action='append', - help="Record activity key/value metadata. ") -@utils.arg('-r', '--reason', - metavar="", - action='append', - help="Record reason key/value metadata. ") -def donot_service_create(cc, args): - """Create a new service.""" - field_list = ['servicename', 'hostname', 'state', 'activity', 'reason'] - fields = dict((k, v) for (k, v) in vars(args).items() - if k in field_list and not (v is None)) - # fields = utils.args_array_to_dict(fields, 'activity') - fields = utils.args_array_to_dict(fields, 'reason') - iservice = cc.iservice.create(**fields) - - field_list.append('uuid') - data = dict([(f, getattr(iservice, f, '')) for f in field_list]) - utils.print_dict(data, wrap=72) - - -@utils.arg('iservice', - metavar='', - nargs='+', - help="ID of iservice") -def donot_service_delete(cc, args): - """Delete a iservice.""" - for c in args.iservice: - try: - cc.iservice.delete(c) - except exc.HTTPNotFound: - raise exc.CommandError('Service not found: %s' % c) - print 'Deleted service %s' % c - - -@utils.arg('iservice', - metavar='', - help="ID of iservice") -@utils.arg('attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove ") -def donot_service_modify_lab(cc, args): - """LAB ONLY Update a service. """ - # JKUNG comment this out prior to delivery - patch = utils.args_array_to_patch("replace", args.attributes[0]) - try: - iservice = cc.iservice.update(args.iservice, patch) - except exc.HTTPNotFound: - raise exc.CommandError('Service not found: %s' % args.iservice) - _print_iservice_show(iservice) diff --git a/service-mgmt-client/sm-client/sm_client/v1/iservicegroup.py b/service-mgmt-client/sm-client/sm_client/v1/iservicegroup.py deleted file mode 100644 index 76253c9c..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/iservicegroup.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright © 2013 Red Hat, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import base -from sm_client import exc - - -CREATION_ATTRIBUTES = ['servicename', 'state'] - - -class iService(base.Resource): - def __repr__(self): - return "" % self._info - - -class iServiceGroupManager(base.Manager): - resource_class = iService - - @staticmethod - def _path(id=None): - return '/v1/service_groups/%s' % id if id else '/v1/service_groups' - - def list(self): - return self._list(self._path(), "service_groups") - - def get(self, iservicegroup_id): - try: - return self._list(self._path(iservicegroup_id))[0] - except IndexError: - return None - - def create(self, **kwargs): - new = {} - for (key, value) in kwargs.items(): - if key in CREATION_ATTRIBUTES: - new[key] = value - else: - raise exc.InvalidAttribute() - return self._create(self._path(), new) - - def delete(self, iservicegroup_id): - return self._delete(self._path(iservicegroup_id)) - - def update(self, iservicegroup_id, patch): - return self._update(self._path(iservicegroup_id), patch) diff --git a/service-mgmt-client/sm-client/sm_client/v1/iservicegroup_shell.py b/service-mgmt-client/sm-client/sm_client/v1/iservicegroup_shell.py deleted file mode 100644 index b7b61468..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/iservicegroup_shell.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import utils -from sm_client import exc - - -def _print_iservicegroup_show(iservicegroup): - fields = ['id', 'name', 'state', 'status'] - data = dict([(f, getattr(iservicegroup, f, '')) for f in fields]) - utils.print_dict(data, wrap=72) - - -def do_servicegroup_list(cc, args): - """List Service Groups.""" - iservicegroup = cc.iservicegroup.list() - fields = ['id', 'name', 'state', 'status'] - field_labels = ['id', 'name', 'state', 'status'] - utils.print_list(iservicegroup, fields, field_labels, sortby=1) - - -@utils.arg('servicegroup', metavar='', - help="ID of iservicegroup") -def do_servicegroup_show(cc, args): - """Show a Service Group.""" - try: - servicegroup = cc.iservicegroup.get(args.servicegroup) - except exc.HTTPNotFound: - raise exc.CommandError( - 'Service Group not found: %s' % args.servicegroup) - else: - _print_iservicegroup_show(servicegroup) - - -@utils.arg('-n', '--name', - metavar='', - help='name of the service group [REQUIRED]') -@utils.arg('-s', '--state', - metavar='', - help='state of the servicegroup [REQUIRED]') -def donot_servicegroup_create(cc, args): - """Create a new servicegroup.""" - field_list = ['name', 'state'] - fields = dict((k, v) for (k, v) in vars(args).items() - if k in field_list and not (v is None)) - # fields = utils.args_array_to_dict(fields, 'activity') - iservicegroup = cc.iservicegroup.create(**fields) - - field_list.append('uuid') - data = dict([(f, getattr(iservicegroup, f, '')) for f in field_list]) - utils.print_dict(data, wrap=72) - - -@utils.arg('iservicegroup', - metavar='', - nargs='+', - help="ID of iservicegroup") -def donot_servicegroup_delete(cc, args): - """Delete a servicegroup.""" - for c in args.iservicegroup: - try: - cc.iservicegroup.delete(c) - except exc.HTTPNotFound: - raise exc.CommandError('Service not found: %s' % c) - print 'Deleted servicegroup %s' % c - - -@utils.arg('iservicegroup', - metavar='', - help="ID of iservicegroup") -@utils.arg('attributes', - metavar='', - nargs='+', - action='append', - default=[], - help="Attributes to add/replace or remove ") -def donot_servicegroup_modify_labonly(cc, args): - """LAB ONLY Update a servicegroup. """ - # JKUNG comment this out prior to delivery - patch = utils.args_array_to_patch("replace", args.attributes[0]) - try: - iservicegroup = cc.iservicegroup.update(args.iservicegroup, patch) - except exc.HTTPNotFound: - raise exc.CommandError( - 'Service Group not found: %s' % args.iservicegroup) - _print_iservicegroup_show(iservicegroup) diff --git a/service-mgmt-client/sm-client/sm_client/v1/shell.py b/service-mgmt-client/sm-client/sm_client/v1/shell.py index b4ac7422..4f7a556d 100644 --- a/service-mgmt-client/sm-client/sm_client/v1/shell.py +++ b/service-mgmt-client/sm-client/sm_client/v1/shell.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2014 Wind River Systems, Inc. +# Copyright (c) 2013-2018 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -8,19 +8,15 @@ from sm_client.common import utils -from sm_client.v1 import iservicegroup_shell -from sm_client.v1 import iservice_shell -from sm_client.v1 import smservicenode_shell -from sm_client.v1 import sm_sda_shell -from sm_client.v1 import sm_nodes_shell +from sm_client.v1 import smc_service_shell +from sm_client.v1 import smc_service_node_shell +from sm_client.v1 import smc_servicegroup_shell COMMAND_MODULES = [ - iservicegroup_shell, - iservice_shell, - smservicenode_shell, - sm_sda_shell, - sm_nodes_shell -] + smc_service_shell, + smc_service_node_shell, + smc_servicegroup_shell, + ] def enhance_parser(parser, subparsers, cmd_mapper): diff --git a/service-mgmt-client/sm-client/sm_client/v1/sm_nodes_shell.py b/service-mgmt-client/sm-client/sm_client/v1/sm_nodes_shell.py deleted file mode 100644 index 0254164c..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/sm_nodes_shell.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import utils -from sm_client import exc - - -def _print_sm_node_show(node): - fields = ['id', 'name', 'state', 'online'] - data = dict([(f, getattr(node, f, '')) for f in fields]) - utils.print_dict(data, wrap=72) - - -def do_node_list(cc, args): - """List Node(s).""" - node = cc.sm_nodes.list() - fields = ['id', 'name', 'state', 'online'] - field_labels = ['id', 'name', 'state', 'online'] - utils.print_list(node, fields, field_labels, sortby=1) - - -@utils.arg('node', metavar='', - help="uuid of a Service Domain Assignment") -def do_node_show(cc, args): - """Show a Node.""" - try: - node = cc.sm_nodes.get(args.node) - except exc.HTTPNotFound: - raise exc.CommandError( - 'Service Domain Assignment not found: %s' % args.node) - else: - _print_sm_node_show(node) diff --git a/service-mgmt-client/sm-client/sm_client/v1/sm_sda_shell.py b/service-mgmt-client/sm-client/sm_client/v1/sm_sda_shell.py deleted file mode 100755 index cda25cc6..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/sm_sda_shell.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import utils -from sm_client import exc - - -def _print_sm_sda_show(sm_sda): - fields = ['id', 'uuid', 'name', 'node_name', 'service_group_name', - 'desired_state', 'state', 'status', 'condition'] - data = dict([(f, getattr(sm_sda, f, '')) for f in fields]) - utils.print_dict(data, wrap=72) - - -def do_sda_list(cc, args): - """List Service Domain Assignments.""" - sm_sda = cc.sm_sda.list() - fields = ['uuid', 'service_group_name', 'node_name', 'state', 'status', - 'condition'] - field_labels = ['uuid', 'service_group_name', 'node_name', - 'state', 'status', 'condition'] - utils.print_list(sm_sda, fields, field_labels, sortby=1) - - -@utils.arg('sm_sda', metavar='', - help="uuid of a Service Domain Assignment") -def do_sda_show(cc, args): - """Show a Service Domain Assignment.""" - try: - sm_sda = cc.sm_sda.get(args.sm_sda) - except exc.HTTPNotFound: - raise exc.CommandError( - 'Service Domain Assignment not found: %s' % args.sm_sda) - else: - _print_sm_sda_show(sm_sda) diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_service.py b/service-mgmt-client/sm-client/sm_client/v1/smc_service.py new file mode 100644 index 00000000..5a590f90 --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_service.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +from sm_client import exc +from sm_client.common import base + + +class SmcService(base.Resource): + def __repr__(self): + return "" % self._info + + +class SmcServiceManager(base.Manager): + resource_class = SmcService + + @staticmethod + def _path(id=None): + return '/v1/services/%s' % id if id else '/v1/services' + + def list(self): + return self._list(self._path(), "services") + + def get(self, iservice_id): + result = self._list(self._path(iservice_id)) + if len(result) == 0: + return None + else: + return result[0] diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_service_node.py b/service-mgmt-client/sm-client/sm_client/v1/smc_service_node.py new file mode 100644 index 00000000..1e1fc03e --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_service_node.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +from sm_client import exc +from sm_client.common import base + +class SmcNode(base.Resource): + def __repr__(self): + return "" % self._info + + +class SmcNodeManager(base.Manager): + resource_class = SmcNode + + @staticmethod + def _path(id=None): + return '/v1/nodes/%s' % id if id else '/v1/nodes' + + def list(self): + return self._list(self._path(), "nodes") + + def get(self, nodes_id): + result = self._list(self._path(nodes_id)) + if len(result) > 0: + return result[0] + else: + return None diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_service_node_shell.py b/service-mgmt-client/sm-client/sm_client/v1/smc_service_node_shell.py new file mode 100644 index 00000000..2bc9e61d --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_service_node_shell.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +from sm_client import exc +from sm_client.common import utils + + +def _print_sm_service_node_show(node): + fields = ['id', 'name', 'administrative_state', 'operational_state', + 'availability_status', 'ready_state'] + utils.print_mapping(node, fields, wrap=72) + +def do_servicenode_list(cc, args): + """List Service Nodes.""" + try: + node = cc.smc_service_node.list() + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + fields = ['id', 'name', 'administrative_state', 'operational_state', + 'availability_status', 'ready_state'] + field_labels = ['id', 'name', 'administrative', 'operational', + 'availability', 'ready_state'] + utils.print_list(node, fields, field_labels, sortby=1) + + +@utils.arg('node', metavar='', + help="uuid of a Service Node") +def do_servicenode_show(cc, args): + """Show a Service Node's attributes.""" + try: + node = cc.smc_service_node.get(args.node) + except exc.HTTPNotFound: + raise exc.CommandError('Service Node not found: %s' % args.node) + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + if node is None: + print "Service node %s could not be found" % args.node + return + _print_sm_service_node_show(node) diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_service_shell.py b/service-mgmt-client/sm-client/sm_client/v1/smc_service_shell.py new file mode 100644 index 00000000..1edbe0cc --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_service_shell.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +import socket + +from sm_client.common import utils +from sm_client import exc + + +def _print_service_show(service): + fields = ['id', 'service_name', 'hostname', 'state'] + data = dict([(f, getattr(service, f, '')) for f in fields]) + data['hostname'] = getattr(service, 'node_name', '') + utils.print_dict(data, fields, wrap=72) + + +def do_service_list(cc, args): + """List Services.""" + try: + service = cc.smc_service.list() + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + fields = ['id', 'name', 'node_name', 'state'] + field_labels = ['id', 'service_name', 'hostname', 'state'] + # remove the entry in the initial state + clean_list = filter(lambda x: x.state != 'initial', service) + for s in clean_list: + if s.status: + setattr(s, 'state', s.state + '-' + s.status) + if getattr(s, 'node_name', None) is None: + setattr(s, 'node_name', socket.gethostname()) + + utils.print_list(clean_list, fields, field_labels, sortby=1) + + +@utils.arg('service', metavar='', help="ID of service") +def do_service_show(cc, args): + """Show a Service.""" + try: + service = cc.smc_service.get(args.service) + except exc.HTTPNotFound: + raise exc.CommandError('service not found: %s' % args.service) + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + if service is None: + print "Service %s could not be found" % args.service + return + if service.status: + setattr(service, 'state', service.state + '-' + service.status) + setattr(service, 'service_name', service.name) + if getattr(service, 'node_name', None) is None: + setattr(service, 'hostname', socket.gethostname()) + _print_service_show(service) + + diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup.py b/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup.py new file mode 100644 index 00000000..57d851d3 --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +from sm_client import exc +from sm_client.common import base + + +class smc_Servicegroup(base.Resource): + def __repr__(self): + return "" % self._info + + +class SmcServiceGroupManager(base.Manager): + resource_class = smc_Servicegroup + + @staticmethod + def _path(id=None): + return '/v1/service_groups/%s' % id if id else '/v1/service_groups' + + def list(self): + return self._list(self._path(), "service_groups") + + def get(self, sm_servicegroup_id): + try: + result = self._list(self._path(sm_servicegroup_id)) + except IndexError: + return None + + if len(result) > 0: + return result[0] + else: + return None diff --git a/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup_shell.py b/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup_shell.py new file mode 100644 index 00000000..71512075 --- /dev/null +++ b/service-mgmt-client/sm-client/sm_client/v1/smc_servicegroup_shell.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +from sm_client.common import utils +from sm_client import exc + + +def _print_servicegroup_show(servicegroup): + fields = ['uuid', 'name', 'hostname', 'service_group_name', 'state'] + utils.print_mapping(servicegroup, fields, wrap=72) + + +def do_servicegroup_list(cc, args): + """List Service Groups.""" + try: + servicegroup = cc.smc_servicegroup.list() + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + fields = ['uuid', 'service_group_name', 'node_name', 'state'] + field_labels = ['uuid', 'service_group_name', 'hostname', 'state'] + for s in servicegroup: + if s.status: + setattr(s, 'state', s.state + '-' + s.status) + utils.print_list(servicegroup, fields, field_labels, sortby=1) + + +@utils.arg('servicegroup', metavar='', + help="UUID of servicegroup") +def do_servicegroup_show(cc, args): + """Show a Service Group.""" + try: + servicegroup = cc.smc_servicegroup.get(args.servicegroup) + except exc.HTTPNotFound: + raise exc.CommandError('Service Group not found: %s' % args.servicegroup) + except exc.Forbidden: + raise exc.CommandError("Not authorized. The requested action " + "requires 'admin' level") + else: + if servicegroup is None: + print "Service group %s could not be found" % args.servicegroup + return + if servicegroup.status: + setattr(servicegroup, 'state', servicegroup.state + '-' + + servicegroup.status) + setattr(servicegroup, 'hostname', servicegroup.node_name) + _print_servicegroup_show(servicegroup) diff --git a/service-mgmt-client/sm-client/sm_client/v1/smservicenode.py b/service-mgmt-client/sm-client/sm_client/v1/smservicenode.py deleted file mode 100644 index f7dbe01c..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/smservicenode.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright © 2013 Red Hat, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import base -from sm_client import exc - - -CREATION_ATTRIBUTES = ['servicename', 'state'] - - -class smService(base.Resource): - def __repr__(self): - return "" % self._info - - -class smServiceNodeManager(base.Manager): - resource_class = smService - - @staticmethod - def _path(id=None): - return '/v1/servicenode/%s' % id if id else '/v1/servicenode' - - def list(self, hostname): - return self._list(self._path(hostname), "servicenode") - - def get(self, smservicenode_id): - try: - return self._list(self._path(smservicenode_id))[0] - except IndexError: - return None - - def create(self, **kwargs): - new = {} - for (key, value) in kwargs.items(): - if key in CREATION_ATTRIBUTES: - new[key] = value - else: - raise exc.InvalidAttribute() - return self._create(self._path(), new) - - def delete(self, smservicenode_id): - return self._delete(self._path(smservicenode_id)) - - def update(self, smservicenode_id, patch): - return self._update(self._path(smservicenode_id), patch) diff --git a/service-mgmt-client/sm-client/sm_client/v1/smservicenode_shell.py b/service-mgmt-client/sm-client/sm_client/v1/smservicenode_shell.py deleted file mode 100644 index d0791b1a..00000000 --- a/service-mgmt-client/sm-client/sm_client/v1/smservicenode_shell.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Copyright (c) 2013-2014 Wind River Systems, Inc. -# - - -from sm_client.common import utils -from sm_client import exc - - -def _print_smservicenode_show(smservicenode): - fields = ['id', 'uuid', 'name', 'node_name', 'service_group_name', - 'desired_state', 'state', 'status'] - data = dict([(f, getattr(smservicenode, f, '')) for f in fields]) - utils.print_dict(data, wrap=72) - - -@utils.arg('hostname', metavar='', - help="hostname of servicenode") -def donot_servicenode_list(cc, args): - """List sm servicenodes by hostname.""" - smservicenode = cc.smservicenode.list(args.hostname) - fields = ['uuid', 'name', 'node_name', 'service_group_name', - 'state', 'status'] - field_labels = ['uuid', 'name', 'node_name', 'service_group_name', - 'state', 'status'] - utils.print_list(smservicenode, fields, field_labels, sortby=1) - - -@utils.arg('smservicenode', metavar='', - help="uuid of smservicenode") -def donot_servicenode_show(cc, args): - """Show an smservicenode.""" - try: - smservicenode = cc.smservicenode.get(args.smservicenode) - except exc.HTTPNotFound: - raise exc.CommandError( - 'servicenode not found: %s' % args.smservicenode) - else: - _print_smservicenode_show(smservicenode) diff --git a/service-mgmt-client/sm-client/usr/bin/smc b/service-mgmt-client/sm-client/usr/bin/smc new file mode 100644 index 00000000..1b918a76 --- /dev/null +++ b/service-mgmt-client/sm-client/usr/bin/smc @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# + +import sys +from sm_client.shell import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/service-mgmt/sm-1.0.0/src/sm_failover_ss.c b/service-mgmt/sm-1.0.0/src/sm_failover_ss.c new file mode 100644 index 00000000..e69de29b