| Mike Marchetti | e304ced | 2017-04-18 11:56:04 -0400 | [diff] [blame] | 1 | from io import BytesIO |
| 2 | import pycurl |
| 3 | import json |
| 4 | import pprint |
| 5 | import uuid |
| 6 | from prettytable import PrettyTable |
| 7 | import time |
| 8 | |
| 9 | class OsmAPI(): |
| 10 | def __init__(self,host,upload_port=8443): |
| 11 | if host is None: |
| 12 | raise Exception('missing host specifier') |
| 13 | |
| 14 | self._user='admin' |
| 15 | self._password='admin' |
| 16 | self._host=host |
| 17 | self._upload_port=upload_port |
| 18 | self._url = 'https://{}/'.format(self._host) |
| 19 | self._upload_url = 'https://{}:{}/'.format(self._host.split(':')[0],self._upload_port) |
| 20 | |
| 21 | def get_curl_cmd(self,url): |
| 22 | curl_cmd = pycurl.Curl() |
| 23 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 24 | curl_cmd.setopt(pycurl.URL, self._url + url ) |
| 25 | curl_cmd.setopt(pycurl.SSL_VERIFYPEER,0) |
| 26 | curl_cmd.setopt(pycurl.SSL_VERIFYHOST,0) |
| 27 | curl_cmd.setopt(pycurl.USERPWD, '{}:{}'.format(self._user,self._password)) |
| 28 | curl_cmd.setopt(pycurl.HTTPHEADER, ['Accept: application/vnd.yand.data+json','Content-Type": "application/vnd.yang.data+json']) |
| 29 | return curl_cmd |
| 30 | |
| 31 | def get_curl_upload_cmd(self,filename): |
| 32 | curl_cmd = pycurl.Curl() |
| 33 | curl_cmd.setopt(pycurl.HTTPPOST,[(('package',(pycurl.FORM_FILE,filename)))]) |
| 34 | curl_cmd.setopt(pycurl.URL, self._upload_url + 'composer/upload?api_server=https://localhost&upload_server=https://' + self._host.split(':')[0]) |
| 35 | curl_cmd.setopt(pycurl.SSL_VERIFYPEER,0) |
| 36 | curl_cmd.setopt(pycurl.SSL_VERIFYHOST,0) |
| 37 | curl_cmd.setopt(pycurl.USERPWD, '{}:{}'.format(self._user,self._password)) |
| 38 | return curl_cmd |
| 39 | |
| 40 | def get_ns_opdata(self,id): |
| 41 | data = BytesIO() |
| 42 | curl_cmd=self.get_curl_cmd('api/operational/ns-instance-opdata/nsr/{}?deep'.format(id)) |
| 43 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 44 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 45 | curl_cmd.perform() |
| 46 | curl_cmd.close() |
| 47 | if data.getvalue(): |
| 48 | return json.loads(data.getvalue().decode()) |
| 49 | return None |
| 50 | |
| 51 | def get_ns_catalog(self): |
| 52 | data = BytesIO() |
| 53 | curl_cmd=self.get_curl_cmd('api/running/nsd-catalog/nsd') |
| 54 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 55 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 56 | curl_cmd.perform() |
| 57 | curl_cmd.close() |
| 58 | if data.getvalue(): |
| 59 | resp = json.loads(data.getvalue().decode()) |
| 60 | return resp |
| 61 | return {'nsd:nsd': []} |
| 62 | |
| 63 | def get_config_agents(self): |
| 64 | data = BytesIO() |
| 65 | curl_cmd=self.get_curl_cmd('api/config/config-agent') |
| 66 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 67 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 68 | curl_cmd.perform() |
| 69 | curl_cmd.close() |
| 70 | if data.getvalue(): |
| 71 | resp = json.loads(data.getvalue().decode()) |
| 72 | if 'rw-config-agent:config-agent' in resp: |
| 73 | return resp['rw-config-agent:config-agent']['account'] |
| 74 | return list() |
| 75 | |
| 76 | def delete_config_agent(self,name): |
| 77 | data = BytesIO() |
| 78 | curl_cmd=self.get_curl_cmd('api/config/config-agent/account/'+name) |
| 79 | curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE") |
| 80 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 81 | curl_cmd.perform() |
| 82 | curl_cmd.close() |
| 83 | resp = json.loads(data.getvalue().decode()) |
| 84 | pprint.pprint(resp) |
| 85 | |
| 86 | def add_config_agent(self,name,account_type,server,user,secret): |
| 87 | data = BytesIO() |
| 88 | curl_cmd=self.get_curl_cmd('api/config/config-agent') |
| 89 | curl_cmd.setopt(pycurl.POST,1) |
| 90 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 91 | |
| 92 | postdata={} |
| 93 | postdata['account'] = list() |
| 94 | |
| 95 | account={} |
| 96 | account['name'] = name |
| 97 | account['account-type'] = account_type |
| 98 | account['juju'] = {} |
| 99 | account['juju']['user'] = user |
| 100 | account['juju']['secret'] = secret |
| 101 | account['juju']['ip-address'] = server |
| 102 | postdata['account'].append(account) |
| 103 | |
| 104 | jsondata=json.dumps(postdata) |
| 105 | curl_cmd.setopt(pycurl.POSTFIELDS,jsondata) |
| 106 | curl_cmd.perform() |
| 107 | curl_cmd.close() |
| 108 | resp = json.loads(data.getvalue().decode()) |
| 109 | pprint.pprint(resp) |
| 110 | |
| 111 | def get_ns_instance_list(self): |
| 112 | data = BytesIO() |
| 113 | curl_cmd=self.get_curl_cmd('api/running/ns-instance-config') |
| 114 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 115 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 116 | curl_cmd.perform() |
| 117 | curl_cmd.close() |
| 118 | resp = json.loads(data.getvalue().decode()) |
| 119 | return resp['nsr:ns-instance-config'] |
| 120 | |
| 121 | def get_vnf_catalog(self): |
| 122 | data = BytesIO() |
| 123 | curl_cmd=self.get_curl_cmd('api/running/vnfd-catalog/vnfd') |
| 124 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 125 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 126 | curl_cmd.perform() |
| 127 | curl_cmd.close() |
| 128 | if data.getvalue(): |
| 129 | resp = json.loads(data.getvalue().decode()) |
| 130 | return resp |
| 131 | return {'vnfd:vnfd': []} |
| 132 | |
| 133 | def get_vcs_info(self): |
| 134 | data = BytesIO() |
| 135 | curl_cmd=self.get_curl_cmd('api/operational/vcs/info') |
| 136 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 137 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 138 | curl_cmd.perform() |
| 139 | curl_cmd.close() |
| 140 | if data.getvalue(): |
| 141 | resp = json.loads(data.getvalue().decode()) |
| 142 | return resp['rw-base:info']['components']['component_info'] |
| 143 | return list() |
| 144 | |
| 145 | def get_vnfr_catalog(self): |
| 146 | data = BytesIO() |
| 147 | curl_cmd=self.get_curl_cmd('v1/api/operational/vnfr-catalog/vnfr') |
| 148 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 149 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 150 | curl_cmd.perform() |
| 151 | curl_cmd.close() |
| 152 | if data.getvalue(): |
| 153 | resp = json.loads(data.getvalue().decode()) |
| 154 | return resp |
| 155 | return None |
| 156 | |
| 157 | def get_vnf(self,vnf_name): |
| 158 | vnfs=self.get_vnfr_catalog() |
| 159 | for vnf in vnfs['vnfr:vnfr']: |
| 160 | if vnf_name == vnf['name']: |
| 161 | return vnf |
| 162 | return None |
| 163 | |
| 164 | def get_vnf_monitoring(self,vnf_name): |
| 165 | vnf=self.get_vnf(vnf_name) |
| 166 | if vnf is not None: |
| 167 | if 'monitoring-param' in vnf: |
| 168 | return vnf['monitoring-param'] |
| 169 | return None |
| 170 | |
| 171 | def get_ns_monitoring(self,ns_name): |
| 172 | ns=self.get_ns(ns_name) |
| 173 | if ns is None: |
| 174 | raise Exception('cannot find ns {}'.format(ns_name)) |
| 175 | |
| 176 | vnfs=self.get_vnfr_catalog() |
| 177 | if vnfs is None: |
| 178 | return None |
| 179 | mon_list={} |
| 180 | for vnf in vnfs['vnfr:vnfr']: |
| 181 | if ns['id'] == vnf['nsr-id-ref']: |
| 182 | if 'monitoring-param' in vnf: |
| 183 | mon_list[vnf['name']] = vnf['monitoring-param'] |
| 184 | |
| 185 | return mon_list |
| 186 | |
| 187 | def list_key_pair(self): |
| 188 | data = BytesIO() |
| 189 | curl_cmd=self.get_curl_cmd('v1/api/config/key-pair?deep') |
| 190 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 191 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 192 | curl_cmd.perform() |
| 193 | curl_cmd.close() |
| 194 | resp = json.loads(data.getvalue().decode()) |
| 195 | if 'nsr:key-pair' in resp: |
| 196 | return resp['nsr:key-pair'] |
| 197 | return list() |
| 198 | |
| 199 | def list_ns_catalog(self): |
| 200 | resp = self.get_ns_catalog() |
| 201 | table=PrettyTable(['nsd name','id']) |
| 202 | for ns in resp['nsd:nsd']: |
| 203 | table.add_row([ns['name'],ns['id']]) |
| 204 | table.align='l' |
| 205 | print(table) |
| 206 | |
| 207 | def list_ns_instance(self): |
| 208 | resp = self.get_ns_instance_list() |
| 209 | table=PrettyTable(['ns instance name','id','catalog name','operational status','config status']) |
| 210 | if 'nsr' in resp: |
| 211 | for ns in resp['nsr']: |
| 212 | nsopdata=self.get_ns_opdata(ns['id']) |
| 213 | nsr=nsopdata['nsr:nsr'] |
| 214 | table.add_row([nsr['name-ref'],nsr['ns-instance-config-ref'],nsr['nsd-name-ref'],nsr['operational-status'],nsr['config-status']]) |
| 215 | table.align='l' |
| 216 | print(table) |
| 217 | |
| 218 | def get_nsd(self,name): |
| 219 | resp = self.get_ns_catalog() |
| 220 | for ns in resp['nsd:nsd']: |
| 221 | if name == ns['name']: |
| 222 | return ns |
| 223 | return None |
| 224 | |
| 225 | def get_vnfd(self,name): |
| 226 | resp = self.get_vnf_catalog() |
| 227 | for vnf in resp['vnfd:vnfd']: |
| 228 | if name == vnf['name']: |
| 229 | return vnf |
| 230 | return None |
| 231 | |
| 232 | def get_ns(self,name): |
| 233 | resp=self.get_ns_instance_list() |
| 234 | for ns in resp['nsr']: |
| 235 | if name == ns['name']: |
| 236 | return ns |
| 237 | return None |
| 238 | |
| 239 | def instantiate_ns(self,nsd_name,nsr_name,account,vim_network_prefix=None,ssh_keys=None,description='default description',admin_status='ENABLED'): |
| 240 | data = BytesIO() |
| 241 | curl_cmd=self.get_curl_cmd('api/config/ns-instance-config/nsr') |
| 242 | curl_cmd.setopt(pycurl.POST,1) |
| 243 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 244 | |
| 245 | postdata={} |
| 246 | postdata['nsr'] = list() |
| 247 | nsr={} |
| 248 | nsr['id']=str(uuid.uuid1()) |
| 249 | |
| 250 | nsd=self.get_nsd(nsd_name) |
| 251 | if nsd is None: |
| 252 | raise Exception('cannot find nsd {}'.format(nsd_name)) |
| 253 | |
| 254 | datacenter=self.get_datacenter(account) |
| 255 | if datacenter is None: |
| 256 | raise Exception('cannot find datacenter account {}'.format(account)) |
| 257 | |
| 258 | nsr['nsd']=nsd |
| 259 | nsr['name']=nsr_name |
| 260 | nsr['short-name']=nsr_name |
| 261 | nsr['description']=description |
| 262 | nsr['admin-status']=admin_status |
| 263 | nsr['om-datacenter']=datacenter['uuid'] |
| 264 | |
| 265 | if ssh_keys is not None: |
| 266 | # ssh_keys is comma separate list |
| 267 | ssh_keys_format=[] |
| 268 | for key in ssh_keys.split(','): |
| 269 | ssh_keys_format.append({'key-pair-ref':key}) |
| 270 | |
| 271 | nsr['ssh-authorized-key']=ssh_keys_format |
| 272 | |
| 273 | if vim_network_prefix is not None: |
| 274 | for index,vld in enumerate(nsr['nsd']['vld']): |
| 275 | network_name = vld['name'] |
| 276 | nsr['nsd']['vld'][index]['vim-network-name'] = '{}-{}'.format(vim_network_prefix,network_name) |
| 277 | |
| 278 | postdata['nsr'].append(nsr) |
| 279 | jsondata=json.dumps(postdata) |
| 280 | curl_cmd.setopt(pycurl.POSTFIELDS,jsondata) |
| 281 | curl_cmd.perform() |
| 282 | curl_cmd.close() |
| 283 | resp = json.loads(data.getvalue().decode()) |
| 284 | pprint.pprint(resp) |
| 285 | |
| 286 | def delete_nsd(self,nsd_name): |
| 287 | nsd=self.get_nsd(nsd_name) |
| 288 | if nsd is None: |
| 289 | raise Exception('cannot find nsd {}'.format(nsd_name)) |
| 290 | data = BytesIO() |
| 291 | curl_cmd=self.get_curl_cmd('api/running/nsd-catalog/nsd/'+nsd['id']) |
| 292 | curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE") |
| 293 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 294 | curl_cmd.perform() |
| 295 | curl_cmd.close() |
| 296 | resp = json.loads(data.getvalue().decode()) |
| 297 | pprint.pprint(resp) |
| 298 | |
| 299 | def delete_vnfd(self,vnfd_name): |
| 300 | vnfd=self.get_vnfd(vnfd_name) |
| 301 | if vnfd is None: |
| 302 | raise Exception('cannot find vnfd {}'.format(vnfd_name)) |
| 303 | data = BytesIO() |
| 304 | curl_cmd=self.get_curl_cmd('api/running/vnfd-catalog/vnfd/'+vnfd['id']) |
| 305 | curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE") |
| 306 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 307 | curl_cmd.perform() |
| 308 | curl_cmd.close() |
| 309 | resp = json.loads(data.getvalue().decode()) |
| 310 | pprint.pprint(resp) |
| 311 | |
| 312 | def terminate_ns(self,ns_name): |
| 313 | ns=self.get_ns(ns_name) |
| 314 | if ns is None: |
| 315 | raise Exception('cannot find ns {}'.format(ns_name)) |
| 316 | |
| 317 | data = BytesIO() |
| 318 | curl_cmd=self.get_curl_cmd('api/config/ns-instance-config/nsr/'+ns['id']) |
| 319 | curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE") |
| 320 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 321 | curl_cmd.perform() |
| 322 | curl_cmd.close() |
| 323 | resp = json.loads(data.getvalue().decode()) |
| 324 | pprint.pprint(resp) |
| 325 | |
| 326 | def upload_package(self,filename): |
| 327 | data = BytesIO() |
| 328 | curl_cmd=self.get_curl_upload_cmd(filename) |
| 329 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 330 | curl_cmd.perform() |
| 331 | curl_cmd.close() |
| 332 | resp = json.loads(data.getvalue().decode()) |
| 333 | pprint.pprint(resp) |
| 334 | |
| 335 | def add_vim_account(self,name,user_name,secret,auth_url,tenant,mgmt_network,float_ip_pool,account_type='openstack'): |
| 336 | data = BytesIO() |
| 337 | curl_cmd=self.get_curl_cmd('api/config/cloud') |
| 338 | curl_cmd.setopt(pycurl.POST,1) |
| 339 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 340 | vim_account={} |
| 341 | vim_account['account']={} |
| 342 | |
| 343 | vim_account['account']['name'] = name |
| 344 | vim_account['account']['account-type'] = account_type |
| 345 | vim_account['account'][account_type] = {} |
| 346 | vim_account['account'][account_type]['key'] = user_name |
| 347 | vim_account['account'][account_type]['secret'] = secret |
| 348 | vim_account['account'][account_type]['auth_url'] = auth_url |
| 349 | vim_account['account'][account_type]['tenant'] = tenant |
| 350 | vim_account['account'][account_type]['mgmt-network'] = mgmt_network |
| 351 | vim_account['account'][account_type]['floating-ip-pool'] = float_ip_pool |
| 352 | |
| 353 | jsondata=json.dumps(vim_account) |
| 354 | curl_cmd.setopt(pycurl.POSTFIELDS,jsondata) |
| 355 | curl_cmd.perform() |
| 356 | curl_cmd.close() |
| 357 | resp = json.loads(data.getvalue().decode()) |
| 358 | pprint.pprint(resp) |
| 359 | |
| 360 | def list_vim_accounts(self): |
| 361 | data = BytesIO() |
| 362 | curl_cmd=self.get_curl_cmd('v1/api/operational/datacenters') |
| 363 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 364 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 365 | curl_cmd.perform() |
| 366 | curl_cmd.close() |
| 367 | resp = json.loads(data.getvalue().decode()) |
| 368 | datacenters=resp['rw-launchpad:datacenters'] |
| 369 | if 'ro-accounts' in datacenters: |
| 370 | return datacenters['ro-accounts'] |
| 371 | return list() |
| 372 | |
| 373 | def get_datacenter(self,name): |
| 374 | data = BytesIO() |
| 375 | curl_cmd=self.get_curl_cmd('v1/api/operational/datacenters') |
| 376 | curl_cmd.setopt(pycurl.HTTPGET,1) |
| 377 | curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write) |
| 378 | curl_cmd.perform() |
| 379 | curl_cmd.close() |
| 380 | resp = json.loads(data.getvalue().decode()) |
| 381 | datacenters=resp['rw-launchpad:datacenters'] |
| 382 | if 'ro-accounts' in datacenters: |
| 383 | for roaccount in datacenters['ro-accounts']: |
| 384 | if not 'datacenters' in roaccount: |
| 385 | continue |
| 386 | for datacenter in roaccount['datacenters']: |
| 387 | if datacenter['name'] == name: |
| 388 | return datacenter |
| 389 | return None |
| 390 | |
| 391 | def show_ns(self,ns_name): |
| 392 | resp = self.get_ns_instance_list() |
| 393 | table=PrettyTable(['attribute','value']) |
| 394 | |
| 395 | if 'nsr' in resp: |
| 396 | for ns in resp['nsr']: |
| 397 | if ns_name == ns['name']: |
| 398 | # dump ns config |
| 399 | for k,v in ns.items(): |
| 400 | table.add_row([k,json.dumps(v,indent=2)]) |
| 401 | |
| 402 | nsopdata=self.get_ns_opdata(ns['id']) |
| 403 | nsr_optdata=nsopdata['nsr:nsr'] |
| 404 | for k,v in nsr_optdata.items(): |
| 405 | table.add_row([k,json.dumps(v,indent=2)]) |
| 406 | table.align='l' |
| 407 | print(table) |
| 408 | |
| 409 | def show_ns_scaling(self,ns_name): |
| 410 | resp = self.get_ns_instance_list() |
| 411 | |
| 412 | table=PrettyTable(['instance-id','operational status','create-time','vnfr ids']) |
| 413 | |
| 414 | if 'nsr' in resp: |
| 415 | for ns in resp['nsr']: |
| 416 | if ns_name == ns['name']: |
| 417 | nsopdata=self.get_ns_opdata(ns['id']) |
| 418 | scaling_records=nsopdata['nsr:nsr']['scaling-group-record'] |
| 419 | for record in scaling_records: |
| 420 | if 'instance' in record: |
| 421 | instances=record['instance'] |
| 422 | for inst in instances: |
| 423 | table.add_row([inst['instance-id'],inst['op-status'],time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(inst['create-time'])),inst['vnfrs']]) |
| 424 | table.align='l' |
| 425 | print(table) |
| 426 | |
| 427 | def list_vnfr(self): |
| 428 | return self.get_vnfr_catalog() |
| 429 | |
| 430 | def list_vnf_catalog(self): |
| 431 | resp = self.get_vnf_catalog() |
| 432 | table=PrettyTable(['vnfd name','id']) |
| 433 | for ns in resp['vnfd:vnfd']: |
| 434 | table.add_row([ns['name'],ns['id']]) |
| 435 | table.align='l' |
| 436 | print(table) |