new commands: ns-op-list, ns-op-show, ns-action
[osm/osmclient.git] / osmclient / sol005 / ns.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
17 """
18 OSM ns API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common.exceptions import NotFound
24 import yaml
25 import json
26
27
28 class Ns(object):
29
30 def __init__(self, http=None, client=None):
31 self._http = http
32 self._client = client
33 self._apiName = '/nslcm'
34 self._apiVersion = '/v1'
35 self._apiResource = '/ns_instances_content'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38
39 def list(self, filter=None):
40 """Returns a list of NS
41 """
42 filter_string = ''
43 if filter:
44 filter_string = '?{}'.format(filter)
45 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
46 if resp:
47 return resp
48 return list()
49
50 def get(self, name):
51 """Returns an NS based on name or id
52 """
53 if utils.validate_uuid4(name):
54 for ns in self.list():
55 if name == ns['_id']:
56 return ns
57 else:
58 for ns in self.list():
59 if name == ns['name']:
60 return ns
61 raise NotFound("ns {} not found".format(name))
62
63 def get_individual(self, name):
64 ns_id = name
65 if not utils.validate_uuid4(name):
66 for ns in self.list():
67 if name == ns['name']:
68 ns_id = ns['_id']
69 break
70 resp = self._http.get_cmd('{}/{}'.format(self._apiBase, ns_id))
71 #resp = self._http.get_cmd('{}/{}/nsd_content'.format(self._apiBase, ns_id))
72 #print yaml.safe_dump(resp)
73 if resp:
74 return resp
75 raise NotFound("ns {} not found".format(name))
76
77 def delete(self, name):
78 ns = self.get(name)
79 http_code, resp = self._http.delete_cmd('{}/{}'.format(self._apiBase,ns['_id']))
80 #print 'RESP: {}'.format(resp)
81 if http_code == 202:
82 print 'Deletion in progress'
83 elif http_code == 204:
84 print 'Deleted'
85 else:
86 raise ClientException("failed to delete ns {}: {}".format(name, resp))
87
88 def create(self, nsd_name, nsr_name, account, config=None,
89 ssh_keys=None, description='default description',
90 admin_status='ENABLED'):
91
92 nsd = self._client.nsd.get(nsd_name)
93
94 vim_account_id = {}
95
96 def get_vim_account_id(vim_account):
97 if vim_account_id.get(vim_account):
98 return vim_account_id[vim_account]
99
100 vim = self._client.vim.get(vim_account)
101 if vim is None:
102 raise NotFound("cannot find vim account '{}'".format(vim_account))
103 vim_account_id[vim_account] = vim['_id']
104 return vim['_id']
105
106 ns = {}
107 ns['nsdId'] = nsd['_id']
108 ns['nsName'] = nsr_name
109 ns['nsDescription'] = description
110 ns['vimAccountId'] = get_vim_account_id(account)
111 #ns['userdata'] = {}
112 #ns['userdata']['key1']='value1'
113 #ns['userdata']['key2']='value2'
114
115 if ssh_keys is not None:
116 # ssh_keys is comma separate list
117 # ssh_keys_format = []
118 # for key in ssh_keys.split(','):
119 # ssh_keys_format.append({'key-pair-ref': key})
120 #
121 # ns['ssh-authorized-key'] = ssh_keys_format
122 ns['ssh-authorized-key'] = ssh_keys.split(',')
123 if config:
124 ns_config = yaml.load(config)
125 if "vim-network-name" in ns_config:
126 ns_config["vld"] = ns_config.pop("vim-network-name")
127 if "vld" in ns_config:
128 for vld in ns_config["vld"]:
129 if vld.get("vim-network-name"):
130 if isinstance(vld["vim-network-name"], dict):
131 vim_network_name_dict = {}
132 for vim_account, vim_net in vld["vim-network-name"].items():
133 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
134 vld["vim-network-name"] = vim_network_name_dict
135 ns["vld"] = ns_config["vld"]
136 if "vnf" in ns_config:
137 for vnf in ns_config["vnf"]:
138 if vnf.get("vim_account"):
139 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
140
141 ns["vnf"] = ns_config["vnf"]
142
143 #print yaml.safe_dump(ns)
144 try:
145 self._apiResource = '/ns_instances_content'
146 self._apiBase = '{}{}{}'.format(self._apiName,
147 self._apiVersion, self._apiResource)
148 resp = self._http.post_cmd(endpoint=self._apiBase,
149 postfields_dict=ns)
150 #print 'RESP: {}'.format(resp)
151 if not resp or 'id' not in resp:
152 raise ClientException('unexpected response from server: '.format(
153 resp))
154 else:
155 print resp['id']
156 except ClientException as exc:
157 message="failed to create ns: {} nsd: {}\nerror:\n{}".format(
158 nsr_name,
159 nsd_name,
160 exc.message)
161 raise ClientException(message)
162
163 def list_op(self, name, filter=None):
164 """Returns the list of operations of a NS
165 """
166 ns = self.get(name)
167 try:
168 self._apiResource = '/ns_lcm_op_occs'
169 self._apiBase = '{}{}{}'.format(self._apiName,
170 self._apiVersion, self._apiResource)
171 filter_string = ''
172 if filter:
173 filter_string = '&{}'.format(filter)
174 http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(self._apiBase, ns['_id'],
175 filter_string) )
176 resp = json.loads(resp.decode())
177 #print 'RESP: {}'.format(resp)
178 if http_code == 200:
179 return resp
180 else:
181 raise ClientException('{}'.format(resp['detail']))
182
183 except ClientException as exc:
184 message="failed to get operation list of NS {}:\nerror:\n{}".format(
185 name,
186 exc.message)
187 raise ClientException(message)
188
189 def get_op(self, operationId):
190 """Returns the status of an operation
191 """
192 try:
193 self._apiResource = '/ns_lcm_op_occs'
194 self._apiBase = '{}{}{}'.format(self._apiName,
195 self._apiVersion, self._apiResource)
196 http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
197 resp = json.loads(resp.decode())
198 #print 'RESP: {}'.format(resp)
199 if http_code == 200:
200 return resp
201 else:
202 raise ClientException("{}".format(resp['detail']))
203 except ClientException as exc:
204 message="failed to get status of operation {}:\nerror:\n{}".format(
205 operationId,
206 exc.message)
207 raise ClientException(message)
208
209 def exec_op(self, name, op_name, op_data=None):
210 """Executes an operation on a NS
211 """
212 ns = self.get(name)
213 try:
214 self._apiResource = '/ns_instances'
215 self._apiBase = '{}{}{}'.format(self._apiName,
216 self._apiVersion, self._apiResource)
217 endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
218 #print 'OP_NAME: {}'.format(op_name)
219 #print 'OP_DATA: {}'.format(json.dumps(op_data))
220 resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
221 #print 'RESP: {}'.format(resp)
222 if not resp or 'id' not in resp:
223 raise ClientException('unexpected response from server: '.format(
224 resp))
225 else:
226 print resp['id']
227 except ClientException as exc:
228 message="failed to exec operation {}:\nerror:\n{}".format(
229 name,
230 exc.message)
231 raise ClientException(message)
232