3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 from rift
.mano
.utils
.project
import DEFAULT_PROJECT
21 from rift
.package
import convert
22 from gi
.repository
import (
23 ProjectNsdYang
as NsdYang
,
24 RwNsdYang
as RwNsdYang
,
25 RwProjectNsdYang
as RwProjectNsdYang
,
26 ProjectVnfdYang
as VnfdYang
,
27 RwVnfdYang
as RwVnfdYang
,
28 RwProjectVnfdYang
as RwProjectVnfdYang
,
32 class OnboardError(Exception):
36 class UpdateError(Exception):
40 class DescriptorOnboarder(object):
41 """ This class is responsible for onboarding descriptors using Restconf"""
43 NsdYang
.YangData_RwProject_Project_NsdCatalog_Nsd
: "nsd-catalog/nsd",
44 RwNsdYang
.YangData_Nsd_NsdCatalog_Nsd
: "nsd-catalog/nsd",
45 RwProjectNsdYang
.YangData_RwProject_Project_NsdCatalog_Nsd
: "nsd-catalog/nsd",
46 VnfdYang
.YangData_RwProject_Project_VnfdCatalog_Vnfd
: "vnfd-catalog/vnfd",
47 RwProjectVnfdYang
.YangData_RwProject_Project_VnfdCatalog_Vnfd
: "vnfd-catalog/vnfd",
48 RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd
: "vnfd-catalog/vnfd"
51 DESC_SERIALIZER_MAP
= {
52 NsdYang
.YangData_RwProject_Project_NsdCatalog_Nsd
: convert
.NsdSerializer(),
53 RwNsdYang
.YangData_Nsd_NsdCatalog_Nsd
: convert
.RwNsdSerializer(),
54 RwProjectNsdYang
.YangData_RwProject_Project_NsdCatalog_Nsd
: convert
.RwNsdSerializer(),
55 VnfdYang
.YangData_RwProject_Project_VnfdCatalog_Vnfd
: convert
.VnfdSerializer(),
56 RwProjectVnfdYang
.YangData_RwProject_Project_VnfdCatalog_Vnfd
: convert
.RwVnfdSerializer(),
57 RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd
: convert
.RwVnfdSerializer()
60 HEADERS
= {"content-type": "application/vnd.yang.data+json"}
62 AUTH
= ('admin', 'admin')
64 def __init__(self
, log
, host
="127.0.0.1", port
=8008, use_ssl
=False, ssl_cert
=None, ssl_key
=None):
68 self
._use
_ssl
= use_ssl
69 self
._ssl
_cert
= ssl_cert
70 self
._ssl
_key
= ssl_key
72 self
.timeout
= DescriptorOnboarder
.TIMEOUT_SECS
75 def _get_headers(cls
):
76 headers
= cls
.HEADERS
.copy()
80 def _get_url(self
, descriptor_msg
, project
=None):
81 if type(descriptor_msg
) not in DescriptorOnboarder
.DESC_SERIALIZER_MAP
:
82 raise TypeError("Invalid descriptor message type")
85 project
= DEFAULT_PROJECT
87 endpoint
= DescriptorOnboarder
.DESC_ENDPOINT_MAP
[type(descriptor_msg
)]
88 ep
= "project/{}/{}".format(project
, endpoint
)
90 url
= "{}://{}:{}/api/config/{}".format(
91 "https" if self
._use
_ssl
else "http",
99 def _make_request_args(self
, descriptor_msg
, auth
=None, project
=None):
100 if type(descriptor_msg
) not in DescriptorOnboarder
.DESC_SERIALIZER_MAP
:
101 raise TypeError("Invalid descriptor message type")
103 serializer
= DescriptorOnboarder
.DESC_SERIALIZER_MAP
[type(descriptor_msg
)]
104 json_data
= serializer
.to_json_string(descriptor_msg
, project_ns
=True)
105 url
= self
._get
_url
(descriptor_msg
, project
=project
)
110 headers
=self
._get
_headers
(),
111 auth
=DescriptorOnboarder
.AUTH
if auth
is None else auth
,
113 cert
=(self
._ssl
_cert
, self
._ssl
_key
) if self
._use
_ssl
else None,
114 timeout
=self
.timeout
,
119 def update(self
, descriptor_msg
, auth
=None, project
=None):
120 """ Update the descriptor config
123 descriptor_msg - A descriptor proto-gi msg
124 auth - the authorization header
127 UpdateError - The descriptor config update failed
129 request_args
= self
._make
_request
_args
(descriptor_msg
, auth
)
131 response
= requests
.put(**request_args
)
132 response
.raise_for_status()
133 except requests
.exceptions
.ConnectionError
as e
:
134 msg
= "Could not connect to restconf endpoint: %s" % str(e
)
136 raise UpdateError(msg
) from e
137 except requests
.exceptions
.HTTPError
as e
:
138 msg
= "PUT request to %s error: %s" % (request_args
["url"], response
.text
)
140 raise UpdateError(msg
) from e
141 except requests
.exceptions
.Timeout
as e
:
142 msg
= "Timed out connecting to restconf endpoint: %s", str(e
)
144 raise UpdateError(msg
) from e
146 def onboard(self
, descriptor_msg
, auth
=None, project
=None):
147 """ Onboard the descriptor config
150 descriptor_msg - A descriptor proto-gi msg
151 auth - the authorization header
154 OnboardError - The descriptor config update failed
157 request_args
= self
._make
_request
_args
(descriptor_msg
, auth
, project
)
159 response
= requests
.post(**request_args
)
160 response
.raise_for_status()
161 except requests
.exceptions
.ConnectionError
as e
:
162 msg
= "Could not connect to restconf endpoint: %s" % str(e
)
164 self
._log
.exception(msg
)
165 raise OnboardError(msg
) from e
166 except requests
.exceptions
.HTTPError
as e
:
167 msg
= "POST request to %s error: %s" % (request_args
["url"], response
.text
)
169 self
._log
.exception(msg
)
170 raise OnboardError(msg
) from e
171 except requests
.exceptions
.Timeout
as e
:
172 msg
= "Timed out connecting to restconf endpoint: %s", str(e
)
174 self
._log
.exception(msg
)
175 raise OnboardError(msg
) from e
177 def get_updated_descriptor(self
, descriptor_msg
, project_name
, auth
=None):
178 """ Get updated descriptor file
181 descriptor_msg - A descriptor proto-gi msg
182 auth - the authorization header
185 OnboardError - The descriptor retrieval failed
188 if type(descriptor_msg
) not in DescriptorOnboarder
.DESC_SERIALIZER_MAP
:
189 raise TypeError("Invalid descriptor message type")
191 endpoint
= DescriptorOnboarder
.DESC_ENDPOINT_MAP
[type(descriptor_msg
)]
193 url
= "{}://{}:{}/api/config/project/{}/{}/{}".format(
194 "https" if self
._use
_ssl
else "http",
202 hdrs
= self
._get
_headers
()
203 hdrs
.update({'Accept': 'application/json'})
207 auth
=DescriptorOnboarder
.AUTH
,
209 cert
=(self
._ssl
_cert
, self
._ssl
_key
) if self
._use
_ssl
else None,
210 timeout
=self
.timeout
,
215 response
= requests
.get(**request_args
)
216 response
.raise_for_status()
217 except requests
.exceptions
.ConnectionError
as e
:
218 msg
= "Could not connect to restconf endpoint: %s" % str(e
)
220 raise OnboardError(msg
) from e
221 except requests
.exceptions
.HTTPError
as e
:
222 msg
= "GET request to %s error: %s" % (request_args
["url"], response
.text
)
224 raise OnboardError(msg
) from e
225 except requests
.exceptions
.Timeout
as e
:
226 msg
= "Timed out connecting to restconf endpoint: %s", str(e
)
228 raise OnboardError(msg
) from e
230 return response
.json()