Create independent sm-api client

1. use sm-api.conf for sm-api configuration
2. create sm-api client code and command line entry
3. add keystone authentication for accessing sm-api
4. removed dead sm-api client code

Story: 2002827
Task: 22744

Depends-On: I743f6b0f09c06325d3c9dc6e11902420882e7931
Change-Id: I861a6fa144494e135f6eb67d96e874d25f4db5d4
Signed-off-by: Bin Qian <bin.qian@windriver.com>
This commit is contained in:
Bin Qian 2018-06-29 14:09:55 -04:00
parent e7d2713327
commit 045a37c672
40 changed files with 546 additions and 751 deletions

View File

@ -1,4 +1,4 @@
SRC_DIR=sm-api SRC_DIR=sm-api
TAR_NAME=sm-api TAR_NAME=sm-api
VERSION=1.0 VERSION=1.0
TIS_PATCH_VER=2 TIS_PATCH_VER=4

View File

@ -36,11 +36,13 @@ Requires: cgts-mtce-common-pmon
install -d %{buildroot}/etc/sm install -d %{buildroot}/etc/sm
install -d %{buildroot}/etc/init.d install -d %{buildroot}/etc/init.d
install -d %{buildroot}/etc/pmon.d install -d %{buildroot}/etc/pmon.d
install -d %{buildroot}/etc/sm-api
install -d %{buildroot}%{_unitdir} install -d %{buildroot}%{_unitdir}
install -m 644 %{_buildsubdir}/scripts/sm_api.ini %{buildroot}/etc/sm install -m 644 %{_buildsubdir}/scripts/sm_api.ini %{buildroot}/etc/sm
install -m 755 %{_buildsubdir}/scripts/sm-api %{buildroot}/etc/init.d 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.service %{buildroot}%{_unitdir}
install -m 644 %{_buildsubdir}/scripts/sm-api.conf %{buildroot}/etc/pmon.d 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 %description
Service Management API Service Management API
@ -72,6 +74,7 @@ Service Management API
%dir "/etc/sm" %dir "/etc/sm"
"/etc/init.d/sm-api" "/etc/init.d/sm-api"
"/etc/pmon.d/sm-api.conf" "/etc/pmon.d/sm-api.conf"
"/etc/sm-api/policy.json"
"/etc/sm/sm_api.ini" "/etc/sm/sm_api.ini"
%{_unitdir}/* %{_unitdir}/*

View File

@ -0,0 +1,5 @@
{
"admin": "role:admin or role:administrator",
"admin_api": "is_admin:True",
"default": "rule:admin_api"
}

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# #
# Copyright (c) 2014 Wind River Systems, Inc. # Copyright (c) 2014-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -32,6 +32,7 @@ LSB_NOT_RUNNING=7
SM_API_NAME="sm-api" SM_API_NAME="sm-api"
SM_API="/usr/bin/${SM_API_NAME}" 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" daemon_pidfile="/var/run/${SM_API_NAME}.pid"
@ -51,7 +52,7 @@ case "$1" in
echo -n "is already running " echo -n "is already running "
RETVAL=0 RETVAL=0
else 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=$? RETVAL=$?
fi fi
if [ ${RETVAL} -eq 0 ] ; then if [ ${RETVAL} -eq 0 ] ; then

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -11,16 +11,16 @@ Application
from oslo_config import cfg from oslo_config import cfg
import pecan import pecan
from sm_api.api import acl
from sm_api.api import config from sm_api.api import config
from sm_api.api import hooks from sm_api.api import hooks
from sm_api.api import acl
from sm_api.api import middleware from sm_api.api import middleware
from sm_api.common import policy
auth_opts = [ auth_opts = [
cfg.StrOpt('auth_strategy', cfg.StrOpt('auth_strategy',
default='noauth', default='keystone',
help='Method to use for auth: noauth or 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): def setup_app(pecan_config=None, extra_hooks=None):
policy.init()
app_hooks = [hooks.ConfigHook(), app_hooks = [hooks.ConfigHook(),
hooks.DatabaseHook(), hooks.DatabaseHook(),
hooks.ContextHook(pecan_config.app.acl_public_routes), hooks.ContextHook(pecan_config.app.acl_public_routes),

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -12,6 +12,6 @@ app = {'root': 'sm_api.api.controllers.root.RootController',
'modules': ['sm_api'], 'modules': ['sm_api'],
'static_root': '', 'static_root': '',
'debug': False, 'debug': False,
'enable_acl': False, 'enable_acl': True,
'acl_public_routes': ['/', '/v1'] 'acl_public_routes': ['/', '/v1']
} }

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -28,14 +28,20 @@ class Version1(wsme_types.Base):
links = [link.Link] links = [link.Link]
"Links that point to a specific URL for this version and documentation" "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" "Links to the SM service-group resource"
services = [link.Link]
"Links to the SM service resource"
servicenode = [link.Link] servicenode = [link.Link]
"Links to the SM service node resource" "Links to the SM node operation resource"
sm_sda = [link.Link] sm_sda = [link.Link]
"Links to the SM service domain assignments resource " "Links to the SM service domain assignement resource"
@classmethod @classmethod
def convert(cls): def convert(cls):
@ -43,6 +49,14 @@ class Version1(wsme_types.Base):
v1.id = "v1" v1.id = "v1"
v1.links = [link.Link.make_link('self', pecan.request.host_url, v1.links = [link.Link.make_link('self', pecan.request.host_url,
'v1', '', bookmark=True)] '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', v1.service_groups = [link.Link.make_link('self',
pecan.request.host_url, pecan.request.host_url,
'service_groups', ''), 'service_groups', ''),
@ -65,7 +79,6 @@ class Version1(wsme_types.Base):
pecan.request.host_url, pecan.request.host_url,
'servicenode', '', 'servicenode', '',
bookmark=True)] bookmark=True)]
v1.sm_sda = [link.Link.make_link('self', v1.sm_sda = [link.Link.make_link('self',
pecan.request.host_url, pecan.request.host_url,
'sm_sda', ''), 'sm_sda', ''),
@ -74,14 +87,6 @@ class Version1(wsme_types.Base):
'sm_sda', '', 'sm_sda', '',
bookmark=True)] 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)]
return v1 return v1

View File

@ -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 # 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 collection
from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import link
from sm_api.api.controllers.v1 import utils from sm_api.api.controllers.v1 import utils
from sm_api.common import exception
from sm_api.common import log from sm_api.common import log
from sm_api import objects from sm_api import objects
@ -112,7 +112,10 @@ class NodesController(rest.RestController):
@wsme_pecan.wsexpose(Nodes, unicode) @wsme_pecan.wsexpose(Nodes, unicode)
def get_one(self, uuid): def get_one(self, uuid):
try:
rpc_sg = objects.sm_node.get_by_uuid(pecan.request.context, uuid) rpc_sg = objects.sm_node.get_by_uuid(pecan.request.context, uuid)
except exception.ServerNotFound:
return None
return Nodes.convert_with_links(rpc_sg) return Nodes.convert_with_links(rpc_sg)

View File

@ -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 # 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 collection
from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import link
from sm_api.api.controllers.v1 import utils from sm_api.api.controllers.v1 import utils
from sm_api.common import exception
from sm_api.common import log from sm_api.common import log
from sm_api import objects from sm_api import objects
@ -43,27 +43,32 @@ class ServiceGroupCommandResult(wsme_types.Base):
class ServiceGroup(base.APIBase): 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 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] 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): def __init__(self, **kwargs):
self.fields = objects.service_groups.fields.keys() self.fields = objects.sm_sda.fields.keys()
for k in self.fields: for k in self.fields:
setattr(self, k, kwargs.get(k)) setattr(self, k, kwargs.get(k))
@classmethod @classmethod
def convert_with_links(cls, rpc_service_groups, expand=True): 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 fields = minimum_fields if not expand else None
service_groups = ServiceGroup.from_rpc_object( service_groups = ServiceGroup.from_rpc_object(
rpc_service_groups, fields) rpc_service_groups, fields)
@ -104,18 +109,27 @@ class ServiceGroupController(rest.RestController):
sort_dir = utils.validate_sort_dir(sort_dir) sort_dir = utils.validate_sort_dir(sort_dir)
marker_obj = None marker_obj = None
if marker: if marker:
marker_obj = objects.service_groups.get_by_uuid( marker_obj = objects.sm_sda.get_by_uuid(pecan.request.context,
pecan.request.context, marker) marker)
service_groups = pecan.request.dbapi.iservicegroup_get_list(limit, sm_sdas = pecan.request.dbapi.sm_sda_get_list(limit,
marker_obj, marker_obj,
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) sort_dir=sort_dir)
return service_groups
# 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) @wsme_pecan.wsexpose(ServiceGroup, unicode)
def get_one(self, uuid): 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)
@ -134,23 +148,6 @@ class ServiceGroupController(rest.RestController):
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) 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, @wsme_pecan.wsexpose(ServiceGroupCommandResult, unicode,
body=ServiceGroupCommand) body=ServiceGroupCommand)
def put(self, hostname, command): def put(self, hostname, command):

View File

@ -118,8 +118,6 @@ LOCAL_HOST_NAME = socket.gethostname()
def rest_api_request(token, method, api_cmd, api_cmd_headers=None, def rest_api_request(token, method, api_cmd, api_cmd_headers=None,
api_cmd_payload=None, timeout=10): api_cmd_payload=None, timeout=10):
""" """
Make a rest-api request Make a rest-api request
Returns: response as a dictionary 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 = urllib2.Request(api_cmd)
request_info.get_method = lambda: method request_info.get_method = lambda: method
if token: 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") request_info.add_header("Accept", "application/json")
if api_cmd_headers is not None: 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) LOG.info("Response=%s" % response)
except urllib2.HTTPError as e: 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)) LOG.warn("HTTP Error e.code=%s e=%s" % (e.code, e))
if hasattr(e, 'msg') and e.msg: if hasattr(e, 'msg') and e.msg:
response = json.loads(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['Content-type'] = "application/json"
api_cmd_headers['Accept'] = "application/json" api_cmd_headers['Accept'] = "application/json"
api_cmd_headers['User-Agent'] = "sm/1.0" api_cmd_headers['User-Agent'] = "sm/1.0"
auth_token = pecan.request.context.auth_token
response = rest_api_request(None, "GET", api_cmd, api_cmd_headers, None) response = rest_api_request(auth_token,
"GET",
api_cmd,
api_cmd_headers,
None)
return response return response

View File

@ -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 collection
from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import link
from sm_api.api.controllers.v1 import utils from sm_api.api.controllers.v1 import utils
from sm_api.common import exception
from sm_api.common import log from sm_api.common import log
from sm_api import objects from sm_api import objects
LOG = log.get_logger(__name__) LOG = log.get_logger(__name__)
@ -112,12 +111,19 @@ class ServicesController(rest.RestController):
@wsme_pecan.wsexpose(Services, unicode) @wsme_pecan.wsexpose(Services, unicode)
def get_one(self, uuid): def get_one(self, uuid):
try:
rpc_sg = objects.service.get_by_uuid(pecan.request.context, uuid) rpc_sg = objects.service.get_by_uuid(pecan.request.context, uuid)
except exception.ServerNotFound:
return None
return Services.convert_with_links(rpc_sg) return Services.convert_with_links(rpc_sg)
@wsme_pecan.wsexpose(Services, unicode) @wsme_pecan.wsexpose(Services, unicode)
def get_service(self, name): def get_service(self, name):
try:
rpc_sg = objects.service.get_by_name(pecan.request.context, name) rpc_sg = objects.service.get_by_name(pecan.request.context, name)
except exception.ServerNotFound:
return None
return Services.convert_with_links(rpc_sg) return Services.convert_with_links(rpc_sg)
@wsme_pecan.wsexpose(ServicesCollection, unicode, int, @wsme_pecan.wsexpose(ServicesCollection, unicode, int,

View File

@ -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 # 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 collection
from sm_api.api.controllers.v1 import link from sm_api.api.controllers.v1 import link
from sm_api.api.controllers.v1 import utils from sm_api.api.controllers.v1 import utils
from sm_api.common import exception
from sm_api.common import log from sm_api.common import log
from sm_api import objects from sm_api import objects
@ -125,12 +125,10 @@ class SmSdaController(rest.RestController):
@wsme_pecan.wsexpose(SmSda, unicode) @wsme_pecan.wsexpose(SmSda, unicode)
def get_one(self, uuid): def get_one(self, uuid):
try:
rpc_sda = objects.sm_sda.get_by_uuid(pecan.request.context, uuid) rpc_sda = objects.sm_sda.get_by_uuid(pecan.request.context, uuid)
except exception.ServerNotFound:
# temp: remap OpenStack_Services to Cloud_Services return None
if rpc_sda.service_group_name.lower() == "openstack_services":
rpc_sda.service_group_name = "Cloud_Services"
return SmSda.convert_with_links(rpc_sda) return SmSda.convert_with_links(rpc_sda)

View File

@ -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 # 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 from sm_api.openstack.common import policy
class ConfigHook(hooks.PecanHook): class ConfigHook(hooks.PecanHook):
def __init__(self): def __init__(self):
super(ConfigHook, self).__init__() super(ConfigHook, self).__init__()
@ -76,7 +74,7 @@ class ContextHook(hooks.PecanHook):
auth_token = state.request.headers.get('X-Auth-Token', None) auth_token = state.request.headers.get('X-Auth-Token', None)
creds = {'roles': state.request.headers.get('X-Roles', '').split(',')} 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, '/') path = utils.safe_rstrip(state.request.path, '/')
is_public_api = path in self.public_api_routes is_public_api = path in self.public_api_routes

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -21,6 +21,7 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
""" """
def __init__(self, app, conf, public_api_routes=[]): def __init__(self, app, conf, public_api_routes=[]):
self.smapi_app = app
self.public_api_routes = set(public_api_routes) self.public_api_routes = set(public_api_routes)
super(AuthTokenMiddleware, self).__init__(app, conf) super(AuthTokenMiddleware, self).__init__(app, conf)
@ -29,6 +30,6 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
path = utils.safe_rstrip(env.get('PATH_INFO'), '/') path = utils.safe_rstrip(env.get('PATH_INFO'), '/')
if path in self.public_api_routes: 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) return super(AuthTokenMiddleware, self).__call__(env, start_response)

View File

@ -66,14 +66,13 @@ def main():
# Parse config file and command line options, then start logging # Parse config file and command line options, then start logging
# Periodically check every minute for want_sm_config # Periodically check every minute for want_sm_config
while os.path.exists("/etc/sm/.not_want_sm_config"): LOG = log.getLogger(__name__)
time.sleep(60)
sm_api_service.prepare_service(sys.argv) sm_api_service.prepare_service(sys.argv)
# Build and start the WSGI app # Build and start the WSGI app
host = socket.gethostname() host = CONF.sm_api_bind_ip or socket.gethostname()
port = 7777 port = CONF.sm_api_port
addrinfo_list = socket.getaddrinfo(host, port) addrinfo_list = socket.getaddrinfo(host, port)
addrinfo = addrinfo_list[0] addrinfo = addrinfo_list[0]
@ -88,7 +87,6 @@ def main():
server_class=server_cls, server_class=server_cls,
handler_class=get_handler_cls()) handler_class=get_handler_cls())
LOG = log.getLogger(__name__)
LOG.info("Serving on http://%(host)s:%(port)s" % LOG.info("Serving on http://%(host)s:%(port)s" %
{'host': host, 'port': port}) {'host': host, 'port': port})
LOG.info("Configuration:") LOG.info("Configuration:")

View File

@ -76,7 +76,7 @@ def model_query(model, *args, **kwargs):
return query 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. """Adds an identity filter to a query.
Filters results by ID, if supplied value is a valid integer. 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. :param value: Value for filtering results by.
:return: Modified query. :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) 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) return query.filter_by(uuid=value)
else: else:
if use_name: if use_name:
@ -129,7 +129,8 @@ class Connection(api.Connection):
@objects.objectify(objects.service_groups) @objects.objectify(objects.service_groups)
def iservicegroup_get(self, server): def iservicegroup_get(self, server):
query = model_query(models.iservicegroup) 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: try:
result = query.one() 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 may be passed as a string. It may be uuid or Int.
# server = int(server) # server = int(server)
query = model_query(models.service) 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: try:
result = query.one() result = query.one()
@ -191,7 +193,8 @@ class Connection(api.Connection):
@objects.objectify(objects.sm_sda) @objects.objectify(objects.sm_sda)
def sm_sda_get(self, server): def sm_sda_get(self, server):
query = model_query(models.sm_sda) 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: try:
result = query.one() result = query.one()
@ -215,7 +218,8 @@ class Connection(api.Connection):
@objects.objectify(objects.sm_node) @objects.objectify(objects.sm_node)
def sm_node_get(self, server): def sm_node_get(self, server):
query = model_query(models.sm_node) 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: try:
result = query.one() 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 may be passed as a string. It may be uuid or Int.
# server = int(server) # server = int(server)
query = model_query(models.service) 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: try:
result = query.one() result = query.one()

View File

@ -1,4 +1,4 @@
SRC_DIR=sm-client SRC_DIR=sm-client
TAR_NAME=sm-client TAR_NAME=sm-client
VERSION=1.0 VERSION=1.0
TIS_PATCH_VER=1 TIS_PATCH_VER=2

View File

@ -23,6 +23,8 @@ Requires: python-libs
%install %install
%global _buildsubdir %{_builddir}/%{name}-%{version} %global _buildsubdir %{_builddir}/%{name}-%{version}
%{__python2} setup.py install -O1 --skip-build --root %{buildroot} %{__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 %description
Service Management Client and CLI Service Management Client and CLI
@ -46,6 +48,7 @@ Service Management Client and CLI
%defattr(-,root,root,-) %defattr(-,root,root,-)
%dir "/usr/lib/python2.7/site-packages/sm_client" %dir "/usr/lib/python2.7/site-packages/sm_client"
/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" %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/* /usr/lib/python2.7/site-packages/sm_client-1.0.0-py2.7.egg-info/*

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
from sm_client.common import utils 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): def _get_ksclient(**kwargs):
"""Get an endpoint and auth token from Keystone. """Get an endpoint and auth token from Keystone.
@ -21,17 +20,19 @@ def _get_ksclient(**kwargs):
""" """
return ksclient.Client(username=kwargs.get('username'), return ksclient.Client(username=kwargs.get('username'),
password=kwargs.get('password'), password=kwargs.get('password'),
tenant_id=kwargs.get('tenant_id'), user_domain_name=kwargs.get('user_domain_name'),
tenant_name=kwargs.get('tenant_name'), project_domain_name=kwargs.get('project_domain_name'),
project_name=kwargs.get('project_name'),
auth_url=kwargs.get('auth_url'), auth_url=kwargs.get('auth_url'),
cacert=kwargs.get('os_cacert'),
insecure=kwargs.get('insecure')) insecure=kwargs.get('insecure'))
def _get_endpoint(client, **kwargs): def _get_endpoint(client, **kwargs):
"""Get an endpoint using the provided keystone client.""" """Get an endpoint using the provided keystone client."""
return client.service_catalog.url_for( return client.service_catalog.url_for(
service_type=kwargs.get('service_type') or 'baremetal', service_type=kwargs.get('service_name') or 'smapi',
endpoint_type=kwargs.get('endpoint_type') or 'publicURL', endpoint_type=kwargs.get('endpoint_type') or 'public',
region_name=kwargs.get('os_region_name') or 'RegionOne') 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'): if kwargs.get('os_auth_token') and kwargs.get('smc_url'):
token = kwargs.get('os_auth_token') token = kwargs.get('os_auth_token')
endpoint = kwargs.get('smc_url') endpoint = kwargs.get('smc_url')
auth_ref = None
elif (kwargs.get('os_username') and elif (kwargs.get('os_username') and
kwargs.get('os_password') and kwargs.get('os_password') and
kwargs.get('os_auth_url') and kwargs.get('os_auth_url')):
(kwargs.get('os_tenant_id') or kwargs.get('os_tenant_name'))):
ks_kwargs = { ks_kwargs = {
'username': kwargs.get('os_username'), 'username': kwargs.get('os_username'),
'password': kwargs.get('os_password'), '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'), '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'), 'service_type': kwargs.get('os_service_type'),
'endpoint_type': kwargs.get('os_endpoint_type'), 'endpoint_type': kwargs.get('os_endpoint_type'),
'insecure': kwargs.get('insecure'), 'insecure': kwargs.get('insecure'),
} }
_ksclient = _get_ksclient(**ks_kwargs) _ksclient = _get_ksclient(**ks_kwargs)
token = ((lambda: kwargs.get('os_auth_token')) token = kwargs.get('os_auth_token') if kwargs.get('os_auth_token') else _ksclient.auth_ref.auth_token
if kwargs.get('os_auth_token')
else (lambda: _ksclient.auth_token))
ep_kwargs = { ep_kwargs = {
'username': kwargs.get('os_username'), 'username': kwargs.get('os_username'),
'password': kwargs.get('os_password'), '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'), 'auth_url': kwargs.get('os_auth_url'),
'service_type': kwargs.get('os_service_type'), 'service_type': kwargs.get('os_service_type'),
'endpoint_type': kwargs.get('os_endpoint_type'), 'endpoint_type': kwargs.get('os_endpoint_type'),
@ -89,8 +89,7 @@ def get_client(api_version, **kwargs):
endpoint = kwargs.get('smc_url') or \ endpoint = kwargs.get('smc_url') or \
_get_endpoint(_ksclient, **ep_kwargs) _get_endpoint(_ksclient, **ep_kwargs)
#region_name=kwargs.get('os_region_name') or 'RegionOne' auth_ref = _ksclient.auth_ref
# neutron_endpoint = _get_endpoint(_ksclient, service_type='network', endpoint_type='internalURL', region_name=region_name )
cli_kwargs = { cli_kwargs = {
'token': token, 'token': token,
@ -99,7 +98,8 @@ def get_client(api_version, **kwargs):
'ca_file': kwargs.get('ca_file'), 'ca_file': kwargs.get('ca_file'),
'cert_file': kwargs.get('cert_file'), 'cert_file': kwargs.get('cert_file'),
'key_file': kwargs.get('key_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) return Client(api_version, endpoint, **cli_kwargs)

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # 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() 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'], pt = prettytable.PrettyTable([dict_property, 'Value'],
caching=False, print_empty=False) caching=False, print_empty=False)
pt.align = 'l' 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 # convert dict to str to check length
if isinstance(v, dict): if isinstance(v, dict):
v = str(v) v = str(v)

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -14,7 +14,7 @@ class BaseException(Exception):
self.message = message self.message = message
def __str__(self): def __str__(self):
return self.message or self.__class__.__doc__ return str(self.message) or self.__class__.__doc__
class CommandError(BaseException): class CommandError(BaseException):
@ -41,7 +41,7 @@ class HTTPException(ClientException):
self.details = details self.details = details
def __str__(self): def __str__(self):
return self.details or "%s (HTTP %s)" % (self.__class__.__name__, return str(self.details) or "%s (HTTP %s)" % (self.__class__.__name__,
self.code) self.code)
@ -143,10 +143,11 @@ for obj_name in dir(sys.modules[__name__]):
_code_map[obj.code] = obj _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.""" """Return an instance of an HTTPException based on httplib response."""
cls = _code_map.get(response.status, HTTPException) cls = _code_map.get(response.status, HTTPException)
return cls(error) return cls(message)
class NoTokenLookupException(Exception): class NoTokenLookupException(Exception):
@ -159,8 +160,18 @@ class EndpointNotFound(Exception):
pass pass
class AmbiguousAuthSystem(ClientException):
"""Could not obtain token and endpoint using provided credentials."""
pass
# Alias for backwards compatibility
AmbigiousAuthSystem = AmbiguousAuthSystem
class InvalidAttribute(ClientException): class InvalidAttribute(ClientException):
pass pass
class InvalidAttributeValue(ClientException): class InvalidAttributeValue(ClientException):
pass pass
#

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -12,6 +12,7 @@ Command-line interface for Service Manager (SM)
import argparse import argparse
import httplib2 import httplib2
import logging import logging
import socket
import sys import sys
import sm_client import sm_client
@ -97,20 +98,6 @@ class SmcShell(object):
parser.add_argument('--os_password', parser.add_argument('--os_password',
help=argparse.SUPPRESS) 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', parser.add_argument('--os-auth-url',
default=utils.env('OS_AUTH_URL'), default=utils.env('OS_AUTH_URL'),
help='Defaults to env[OS_AUTH_URL]') help='Defaults to env[OS_AUTH_URL]')
@ -132,9 +119,11 @@ class SmcShell(object):
parser.add_argument('--os_auth_token', parser.add_argument('--os_auth_token',
help=argparse.SUPPRESS) help=argparse.SUPPRESS)
smc_url = "http://{host}:{port}".format(
host=socket.gethostname(), port=7777)
parser.add_argument('--smc-url', parser.add_argument('--smc-url',
# default=utils.env('SMC_URL'), # default=utils.env('SMC_URL'),
default="http://localhost:7777", default=smc_url,
help='Defaults to env[SMC_URL]') help='Defaults to env[SMC_URL]')
parser.add_argument('--smc_url', parser.add_argument('--smc_url',
@ -163,6 +152,36 @@ class SmcShell(object):
parser.add_argument('--os_endpoint_type', parser.add_argument('--os_endpoint_type',
help=argparse.SUPPRESS) 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 return parser
def get_subcommand_parser(self, version): def get_subcommand_parser(self, version):
@ -223,11 +242,6 @@ class SmcShell(object):
"either --os-password or via " "either --os-password or via "
"env[OS_PASSWORD]") "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: if not args.os_auth_url:
raise exc.CommandError("You must provide an auth url via " raise exc.CommandError("You must provide an auth url via "
"either --os-auth-url or via " "either --os-auth-url or via "

View File

@ -13,16 +13,16 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # 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.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 sm_sda
from sm_client.v1 import smservicenode
from sm_client.v1 import sm_nodes 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): class Client(http.HTTPClient):
@ -38,8 +38,8 @@ class Client(http.HTTPClient):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Initialize a new client for the Smc v1 API.""" """Initialize a new client for the Smc v1 API."""
super(Client, self).__init__(*args, **kwargs) 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_sda = sm_sda.Sm_SdaManager(self)
self.sm_nodes = sm_nodes.Sm_NodesManager(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)

View File

@ -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 "<iService %s>" % 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)

View File

@ -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='<iservice id>', 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='<servicename>',
help='servicename of the service [REQUIRED]')
@utils.arg('-n', '--hostname',
metavar='<hostname>',
help='hostname of the service [REQUIRED]')
@utils.arg('-s', '--state',
metavar='<state>',
help='state of the service [REQUIRED]')
@utils.arg('-a', '--activity',
metavar="<key=value>",
action='append',
help="Record activity key/value metadata. ")
@utils.arg('-r', '--reason',
metavar="<key=value>",
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='<iservice id>',
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='<iservice id>',
help="ID of iservice")
@utils.arg('attributes',
metavar='<path=value>',
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)

View File

@ -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 "<iService %s>" % 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)

View File

@ -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='<servicegroup id>',
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='<name>',
help='name of the service group [REQUIRED]')
@utils.arg('-s', '--state',
metavar='<state>',
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='<iservicegroup id>',
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='<iservicegroup id>',
help="ID of iservicegroup")
@utils.arg('attributes',
metavar='<path=value>',
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)

View File

@ -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 # SPDX-License-Identifier: Apache-2.0
# #
@ -8,18 +8,14 @@
from sm_client.common import utils from sm_client.common import utils
from sm_client.v1 import iservicegroup_shell from sm_client.v1 import smc_service_shell
from sm_client.v1 import iservice_shell from sm_client.v1 import smc_service_node_shell
from sm_client.v1 import smservicenode_shell from sm_client.v1 import smc_servicegroup_shell
from sm_client.v1 import sm_sda_shell
from sm_client.v1 import sm_nodes_shell
COMMAND_MODULES = [ COMMAND_MODULES = [
iservicegroup_shell, smc_service_shell,
iservice_shell, smc_service_node_shell,
smservicenode_shell, smc_servicegroup_shell,
sm_sda_shell,
sm_nodes_shell
] ]

View File

@ -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='<node uuid>',
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)

View File

@ -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='<sm_sda uuid>',
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)

View File

@ -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 "<SmcService %s>" % 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]

View File

@ -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 "<SmcNode %s>" % 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

View File

@ -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='<node uuid>',
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)

View File

@ -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='<service id>', 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)

View File

@ -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 "<smc_Servicegroup %s>" % 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

View File

@ -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='<servicegroup uuid>',
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)

View File

@ -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 "<smService %s>" % 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)

View File

@ -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='<hostname>',
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='<smservicenode uuid>',
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)

View File

@ -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())