new commands: ns-op-list, ns-op-show, ns-action
authorgarciadeblas <gerardo.garciadeblas@telefonica.com>
Fri, 4 May 2018 12:15:04 +0000 (14:15 +0200)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Sat, 5 May 2018 21:31:39 +0000 (23:31 +0200)
Change-Id: Ie19c0f88d85cffbad41d5e71a3cb29ccd21473d4
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
osmclient/scripts/osm.py
osmclient/sol005/http.py
osmclient/sol005/ns.py
osmclient/sol005/nsd.py
osmclient/sol005/vnfd.py

index 75b3be2..23f258e 100755 (executable)
@@ -243,6 +243,27 @@ def vnf_list(ctx):
     table.align = 'l'
     print(table)
 
+@cli.command(name='ns-op-list')
+@click.argument('name')
+@click.pass_context
+def ns_op_list(ctx, name):
+    '''shows the history of operations over a NS instance
+
+    NAME: name or ID of the NS instance
+    '''
+    try:
+        check_client_version(ctx.obj, ctx.command.name)
+        resp = ctx.obj.ns.list_op(name)
+    except ClientException as inst:
+        print(inst.message)
+        exit(1)
+
+    table = PrettyTable(['id', 'operation', 'status'])
+    for op in resp:
+         table.add_row([op['id'], op['lcmOperationType'],
+                        op['operationState']])
+    table.align = 'l'
+    print(table)
 
 ####################
 # SHOW operations
@@ -451,6 +472,29 @@ def ns_monitoring_show(ctx, ns_name):
     table.align = 'l'
     print(table)
 
+@cli.command(name='ns-op-show', short_help='shows the info of an operation')
+@click.argument('id')
+@click.option('--filter', default=None)
+@click.pass_context
+def ns_op_show(ctx, id, filter):
+    '''shows the detailed info of an operation
+
+    ID: operation identifier
+    '''
+    try:
+        check_client_version(ctx.obj, ctx.command.name)
+        op_info = ctx.obj.ns.get_op(id)
+    except ClientException as inst:
+        print(inst.message)
+        exit(1)
+
+    table = PrettyTable(['field', 'value'])
+    for k, v in op_info.items():
+        if filter is None or filter in k:
+            table.add_row([k, json.dumps(v, indent=2)])
+    table.align = 'l'
+    print(table)
+
 
 ####################
 # CREATE operations
@@ -1020,5 +1064,33 @@ def vcs_list(ctx):
     print(table)
 
 
+@cli.command(name='ns-action')
+@click.argument('ns_name')
+@click.option('--vnf_name', default=None)
+@click.option('--action_name', prompt=True)
+@click.option('--params', prompt=True)
+@click.pass_context
+def ns_action(ctx,
+              ns_name,
+              vnf_name,
+              params):
+    '''executes an action/primitive over a NS instance
+
+    NS_NAME: name or ID of the NS instance
+    '''
+    try:
+        check_client_version(ctx.obj, ctx.command.name)
+        op_data={}
+        if vnf_name:
+            op_data['vnf_member_index'] = vnf_name
+        op_data['primitive'] = action_name
+        op_data['primitive_params'] = yaml.load(params)
+        ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
+
+    except ClientException as inst:
+        print(inst.message)
+        exit(1)
+
+
 if __name__ == '__main__':
     cli()
index 20593b8..d76e41e 100644 (file)
@@ -120,6 +120,9 @@ class Http(http.Http):
         curl_cmd.setopt(pycurl.HTTPGET, 1)
         curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
         curl_cmd.perform()
+        http_code = curl_cmd.getinfo(pycurl.HTTP_CODE)
         curl_cmd.close()
-        return data.getvalue()
+        if data.getvalue():
+            return http_code, data.getvalue()
+        return http_code, None
 
index 590cdb1..99fb83e 100644 (file)
@@ -22,6 +22,7 @@ from osmclient.common import utils
 from osmclient.common.exceptions import ClientException
 from osmclient.common.exceptions import NotFound
 import yaml
+import json
 
 
 class Ns(object):
@@ -144,9 +145,9 @@ class Ns(object):
             self._apiResource = '/ns_instances_content'
             self._apiBase = '{}{}{}'.format(self._apiName,
                                             self._apiVersion, self._apiResource)
-            #print resp
             resp = self._http.post_cmd(endpoint=self._apiBase,
                                        postfields_dict=ns)
+            #print 'RESP: {}'.format(resp)
             if not resp or 'id' not in resp:
                 raise ClientException('unexpected response from server: '.format(
                                       resp))
@@ -159,3 +160,73 @@ class Ns(object):
                     exc.message)
             raise ClientException(message)
 
+    def list_op(self, name, filter=None):
+        """Returns the list of operations of a NS
+        """
+        ns = self.get(name)
+        try:
+            self._apiResource = '/ns_lcm_op_occs'
+            self._apiBase = '{}{}{}'.format(self._apiName,
+                                      self._apiVersion, self._apiResource)
+            filter_string = ''
+            if filter:
+                filter_string = '&{}'.format(filter)
+            http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(self._apiBase, ns['_id'],
+                                                                  filter_string) )
+            resp = json.loads(resp.decode())
+            #print 'RESP: {}'.format(resp)
+            if http_code == 200:
+                return resp
+            else:
+                raise ClientException('{}'.format(resp['detail']))
+
+        except ClientException as exc:
+            message="failed to get operation list of NS {}:\nerror:\n{}".format(
+                    name,
+                    exc.message)
+            raise ClientException(message)
+
+    def get_op(self, operationId):
+        """Returns the status of an operation
+        """
+        try:
+            self._apiResource = '/ns_lcm_op_occs'
+            self._apiBase = '{}{}{}'.format(self._apiName,
+                                      self._apiVersion, self._apiResource)
+            http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
+            resp = json.loads(resp.decode())
+            #print 'RESP: {}'.format(resp)
+            if http_code == 200:
+                return resp
+            else:
+                raise ClientException("{}".format(resp['detail']))
+        except ClientException as exc:
+            message="failed to get status of operation {}:\nerror:\n{}".format(
+                    operationId,
+                    exc.message)
+            raise ClientException(message)
+
+    def exec_op(self, name, op_name, op_data=None):
+        """Executes an operation on a NS
+        """
+        ns = self.get(name)
+        try:
+            self._apiResource = '/ns_instances'
+            self._apiBase = '{}{}{}'.format(self._apiName,
+                                            self._apiVersion, self._apiResource)
+            endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
+            #print 'OP_NAME: {}'.format(op_name)
+            #print 'OP_DATA: {}'.format(json.dumps(op_data))
+            resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
+            #print 'RESP: {}'.format(resp)
+            if not resp or 'id' not in resp:
+                raise ClientException('unexpected response from server: '.format(
+                                      resp))
+            else:
+                print resp['id']
+        except ClientException as exc:
+            message="failed to exec operation {}:\nerror:\n{}".format(
+                    name,
+                    exc.message)
+            raise ClientException(message)
+
index dac0adc..95fc92a 100644 (file)
@@ -73,7 +73,7 @@ class Nsd(object):
         nsd = self.get(name)
         headers = self._client._headers
         headers['Accept'] = 'application/binary'
-        resp2 = self._http.get2_cmd('{}/{}/{}'.format(self._apiBase, nsd['_id'], thing))
+        http_code, resp2 = self._http.get2_cmd('{}/{}/{}'.format(self._apiBase, nsd['_id'], thing))
         #print yaml.safe_dump(resp2)
         if resp2:
             #store in a file
index 28ded17..6b09a1f 100644 (file)
@@ -72,7 +72,7 @@ class Vnfd(object):
         vnfd = self.get(name)
         headers = self._client._headers
         headers['Accept'] = 'application/binary'
-        resp2 = self._http.get2_cmd('{}/{}/{}'.format(self._apiBase, vnfd['_id'], thing))
+        http_code, resp2 = self._http.get2_cmd('{}/{}/{}'.format(self._apiBase, vnfd['_id'], thing))
         #print yaml.safe_dump(resp2)
         if resp2:
             #store in a file