ssh key injection enabled with ns-create in sol005 client
[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'] = []
123 for pubkeyfile in ssh_keys.split(','):
124 with open(pubkeyfile, 'r') as f:
125 ns['ssh-authorized-key'].append(f.read())
126 if config:
127 ns_config = yaml.load(config)
128 if "vim-network-name" in ns_config:
129 ns_config["vld"] = ns_config.pop("vim-network-name")
130 if "vld" in ns_config:
131 for vld in ns_config["vld"]:
132 if vld.get("vim-network-name"):
133 if isinstance(vld["vim-network-name"], dict):
134 vim_network_name_dict = {}
135 for vim_account, vim_net in vld["vim-network-name"].items():
136 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
137 vld["vim-network-name"] = vim_network_name_dict
138 ns["vld"] = ns_config["vld"]
139 if "vnf" in ns_config:
140 for vnf in ns_config["vnf"]:
141 if vnf.get("vim_account"):
142 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
143
144 ns["vnf"] = ns_config["vnf"]
145
146 #print yaml.safe_dump(ns)
147 try:
148 self._apiResource = '/ns_instances_content'
149 self._apiBase = '{}{}{}'.format(self._apiName,
150 self._apiVersion, self._apiResource)
151 resp = self._http.post_cmd(endpoint=self._apiBase,
152 postfields_dict=ns)
153 #print 'RESP: {}'.format(resp)
154 if not resp or 'id' not in resp:
155 raise ClientException('unexpected response from server: '.format(
156 resp))
157 else:
158 print resp['id']
159 except ClientException as exc:
160 message="failed to create ns: {} nsd: {}\nerror:\n{}".format(
161 nsr_name,
162 nsd_name,
163 exc.message)
164 raise ClientException(message)
165
166 def list_op(self, name, filter=None):
167 """Returns the list of operations of a NS
168 """
169 ns = self.get(name)
170 try:
171 self._apiResource = '/ns_lcm_op_occs'
172 self._apiBase = '{}{}{}'.format(self._apiName,
173 self._apiVersion, self._apiResource)
174 filter_string = ''
175 if filter:
176 filter_string = '&{}'.format(filter)
177 http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(self._apiBase, ns['_id'],
178 filter_string) )
179 resp = json.loads(resp.decode())
180 #print 'RESP: {}'.format(resp)
181 if http_code == 200:
182 return resp
183 else:
184 raise ClientException('{}'.format(resp['detail']))
185
186 except ClientException as exc:
187 message="failed to get operation list of NS {}:\nerror:\n{}".format(
188 name,
189 exc.message)
190 raise ClientException(message)
191
192 def get_op(self, operationId):
193 """Returns the status of an operation
194 """
195 try:
196 self._apiResource = '/ns_lcm_op_occs'
197 self._apiBase = '{}{}{}'.format(self._apiName,
198 self._apiVersion, self._apiResource)
199 http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
200 resp = json.loads(resp.decode())
201 #print 'RESP: {}'.format(resp)
202 if http_code == 200:
203 return resp
204 else:
205 raise ClientException("{}".format(resp['detail']))
206 except ClientException as exc:
207 message="failed to get status of operation {}:\nerror:\n{}".format(
208 operationId,
209 exc.message)
210 raise ClientException(message)
211
212 def exec_op(self, name, op_name, op_data=None):
213 """Executes an operation on a NS
214 """
215 ns = self.get(name)
216 try:
217 self._apiResource = '/ns_instances'
218 self._apiBase = '{}{}{}'.format(self._apiName,
219 self._apiVersion, self._apiResource)
220 endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
221 #print 'OP_NAME: {}'.format(op_name)
222 #print 'OP_DATA: {}'.format(json.dumps(op_data))
223 resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
224 #print 'RESP: {}'.format(resp)
225 if not resp or 'id' not in resp:
226 raise ClientException('unexpected response from server: '.format(
227 resp))
228 else:
229 print resp['id']
230 except ClientException as exc:
231 message="failed to exec operation {}:\nerror:\n{}".format(
232 name,
233 exc.message)
234 raise ClientException(message)
235