blob: 4f3ced44f27800520e85ea209c337583c411bd04 [file] [log] [blame]
garciadeblas017c4fb2018-02-13 11:58:29 +01001# 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"""
18OSM SDN controller API handling
19"""
20
21from osmclient.common import utils
kuuse5da3f202019-05-30 09:42:05 +020022from osmclient.common import wait as WaitForStatus
garciadeblas017c4fb2018-02-13 11:58:29 +010023from osmclient.common.exceptions import ClientException
24from osmclient.common.exceptions import NotFound
garciadeblasf1571282018-05-14 16:06:22 +020025import json
garciadeblas017c4fb2018-02-13 11:58:29 +010026
27
28class SdnController(object):
29 def __init__(self, http=None, client=None):
30 self._http = http
31 self._client = client
32 self._apiName = '/admin'
33 self._apiVersion = '/v1'
garciadeblas170b8fd2018-05-10 14:34:13 +020034 self._apiResource = '/sdns'
garciadeblas017c4fb2018-02-13 11:58:29 +010035 self._apiBase = '{}{}{}'.format(self._apiName,
36 self._apiVersion, self._apiResource)
garciadeblas69910012018-05-29 14:15:43 +020037
kuuse5da3f202019-05-30 09:42:05 +020038 # SDNC '--wait' option
39 def _wait(self, id, deleteFlag=False):
pinoa93012ad2019-11-05 14:28:15 +010040 self._client.get_token()
kuuse5da3f202019-05-30 09:42:05 +020041 # Endpoint to get operation status
42 apiUrlStatus = '{}{}{}'.format(self._apiName, self._apiVersion, '/sdns')
43 # Wait for status for SDN instance creation/update/deletion
44 WaitForStatus.wait_for_status(
45 'SDNC',
46 str(id),
47 WaitForStatus.TIMEOUT_SDNC_OPERATION,
48 apiUrlStatus,
49 self._http.get2_cmd,
50 deleteFlag=deleteFlag)
51
52 def _get_id_for_wait(self, name):
53 # Returns id of name, or the id itself if given as argument
54 for sdnc in self.list():
kuuse5da3f202019-05-30 09:42:05 +020055 if name == sdnc['_id']:
56 return sdnc['_id']
kuuse5de571e2019-05-31 12:25:42 +020057 for sdnc in self.list():
58 if name == sdnc['name']:
59 return sdnc['_id']
kuuse5da3f202019-05-30 09:42:05 +020060 return ''
61
62 def create(self, name, sdn_controller, wait=False):
pinoa93012ad2019-11-05 14:28:15 +010063 self._client.get_token()
garciadeblasf1571282018-05-14 16:06:22 +020064 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
garciadeblas017c4fb2018-02-13 11:58:29 +010065 postfields_dict=sdn_controller)
garciadeblas09fa3d42019-10-08 18:30:46 +020066 #print('HTTP CODE: {}'.format(http_code))
67 #print('RESP: {}'.format(resp))
garciadeblas061856b2018-05-22 00:49:13 +020068 if http_code in (200, 201, 202, 204):
69 if resp:
70 resp = json.loads(resp)
71 if not resp or 'id' not in resp:
72 raise ClientException('unexpected response from server - {}'.format(
73 resp))
kuuse5da3f202019-05-30 09:42:05 +020074 if wait:
75 # Wait for status for SDNC instance creation
76 self._wait(resp.get('id'))
peustermbe960962018-06-14 21:32:55 +020077 print(resp['id'])
garciadeblas061856b2018-05-22 00:49:13 +020078 else:
79 msg = ""
80 if resp:
81 try:
82 msg = json.loads(resp)
83 except ValueError:
84 msg = resp
85 raise ClientException("failed to create SDN controller {} - {}".format(name, msg))
garciadeblas170b8fd2018-05-10 14:34:13 +020086
kuuse5da3f202019-05-30 09:42:05 +020087 def update(self, name, sdn_controller, wait=False):
pinoa93012ad2019-11-05 14:28:15 +010088 self._client.get_token()
garciadeblas170b8fd2018-05-10 14:34:13 +020089 sdnc = self.get(name)
kuuse5da3f202019-05-30 09:42:05 +020090 sdnc_id_for_wait = self._get_id_for_wait(name)
garciadeblas0eefdeb2019-11-22 22:18:09 +010091 http_code, resp = self._http.patch_cmd(endpoint='{}/{}'.format(self._apiBase,sdnc['_id']),
garciadeblas170b8fd2018-05-10 14:34:13 +020092 postfields_dict=sdn_controller)
garciadeblas09fa3d42019-10-08 18:30:46 +020093 # print('HTTP CODE: {}'.format(http_code))
94 # print('RESP: {}'.format(resp))
garciadeblas061856b2018-05-22 00:49:13 +020095 if http_code in (200, 201, 202, 204):
kuuse5da3f202019-05-30 09:42:05 +020096 if wait:
kuuse5de571e2019-05-31 12:25:42 +020097 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
98 # Use the previously obtained id instead.
99 wait_id = sdnc_id_for_wait
100 # Wait for status for VI instance update
101 self._wait(wait_id)
102 else:
103 pass
garciadeblas061856b2018-05-22 00:49:13 +0200104 else:
105 msg = ""
106 if resp:
107 try:
108 msg = json.loads(resp)
109 except ValueError:
110 msg = resp
111 raise ClientException("failed to update SDN controller {} - {}".format(name, msg))
garciadeblas017c4fb2018-02-13 11:58:29 +0100112
kuuse5da3f202019-05-30 09:42:05 +0200113 def delete(self, name, force=False, wait=False):
pinoa93012ad2019-11-05 14:28:15 +0100114 self._client.get_token()
garciadeblas017c4fb2018-02-13 11:58:29 +0100115 sdn_controller = self.get(name)
kuuse5da3f202019-05-30 09:42:05 +0200116 sdnc_id_for_wait = self._get_id_for_wait(name)
garciadeblas6d10e042018-05-16 17:21:59 +0200117 querystring = ''
118 if force:
119 querystring = '?FORCE=True'
120 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
121 sdn_controller['_id'], querystring))
garciadeblas09fa3d42019-10-08 18:30:46 +0200122 #print('HTTP CODE: {}'.format(http_code))
123 #print('RESP: {}'.format(resp))
garciadeblas74341f02018-05-03 18:46:46 +0200124 if http_code == 202:
kuuse5da3f202019-05-30 09:42:05 +0200125 if wait:
126 # Wait for status for SDNC instance deletion
127 self._wait(sdnc_id_for_wait, deleteFlag=True)
128 else:
129 print('Deletion in progress')
garciadeblas74341f02018-05-03 18:46:46 +0200130 elif http_code == 204:
peustermbe960962018-06-14 21:32:55 +0200131 print('Deleted')
garciadeblas061856b2018-05-22 00:49:13 +0200132 elif resp and 'result' in resp:
peustermbe960962018-06-14 21:32:55 +0200133 print('Deleted')
garciadeblas74341f02018-05-03 18:46:46 +0200134 else:
garciadeblas061856b2018-05-22 00:49:13 +0200135 msg = ""
136 if resp:
137 try:
138 msg = json.loads(resp)
139 except ValueError:
140 msg = resp
141 raise ClientException("failed to delete SDN controller {} - {}".format(name, msg))
garciadeblas017c4fb2018-02-13 11:58:29 +0100142
143 def list(self, filter=None):
144 """Returns a list of SDN controllers
145 """
pinoa93012ad2019-11-05 14:28:15 +0100146 self._client.get_token()
garciadeblas017c4fb2018-02-13 11:58:29 +0100147 filter_string = ''
148 if filter:
149 filter_string = '?{}'.format(filter)
150 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
garciadeblas09fa3d42019-10-08 18:30:46 +0200151 #print('RESP: {}'.format(resp))
garciadeblas017c4fb2018-02-13 11:58:29 +0100152 if resp:
153 return resp
154 return list()
155
156 def get(self, name):
157 """Returns an SDN controller based on name or id
158 """
pinoa93012ad2019-11-05 14:28:15 +0100159 self._client.get_token()
garciadeblas017c4fb2018-02-13 11:58:29 +0100160 if utils.validate_uuid4(name):
161 for sdnc in self.list():
162 if name == sdnc['_id']:
163 return sdnc
164 else:
165 for sdnc in self.list():
166 if name == sdnc['name']:
167 return sdnc
168 raise NotFound("SDN controller {} not found".format(name))
169
170