blob: ab829083fb6520b93777a6de3965e6dff4b8f2dc [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Scott Baker89c9e6e2017-03-14 17:47:32 -070015from xosapi.orm import ORMWrapper, register_convenience_wrapper
16
Zack Williams045b63d2019-01-22 16:30:57 -070017
Scott Baker89c9e6e2017-03-14 17:47:32 -070018class ORMWrapperService(ORMWrapper):
19 @property
20 def serviceattribute_dict(self):
21 attrs = {}
22 for attr in self.serviceattributes.all():
23 attrs[attr.name] = attr.value
24 return attrs
25
Scott Baker79808902017-03-15 15:51:21 -070026 def get_composable_networks(self):
Zack Williams045b63d2019-01-22 16:30:57 -070027 SUPPORTED_VTN_SERVCOMP_KINDS = ["VSG", "PRIVATE"]
Scott Baker79808902017-03-15 15:51:21 -070028
29 nets = []
30 for slice in self.slices.all():
31 for net in slice.networks.all():
Zack Williams045b63d2019-01-22 16:30:57 -070032 if (net.template.vtn_kind not in SUPPORTED_VTN_SERVCOMP_KINDS) or (
33 net.owner.id != slice.id
34 ):
Scott Baker79808902017-03-15 15:51:21 -070035 continue
36
37 if not net.controllernetworks.exists():
38 continue
39 nets.append(net)
40 return nets
41
Scott Baker6f24c452017-09-18 16:29:12 -070042 def get_service_instance_class_name(self):
43 # This assumes that a ServiceInstance is always named after its service. For example
44 # VSGService --> VSGServiceInstance. Services in which this is not the case should override this method.
45 # TODO: Specify via xproto ?
46 return self.leaf_model_name + "Instance"
47
48 def get_service_instance_class(self):
Scott Baker8f36c3f2017-09-26 16:44:36 -070049 return getattr(self.stub, self.get_service_instance_class_name())
Scott Baker6f24c452017-09-18 16:29:12 -070050
Matteo Scandolo5d607282018-04-11 09:19:25 -070051 @property
52 def provider_services(self):
53 svcs = []
54 service_deps = self.subscribed_dependencies.all()
55 for dep in service_deps:
56 svcs.append(dep.provider_service)
57 return svcs
58
59 @property
60 def subscriber_services(self):
61 svcs = []
62 service_deps = self.provided_dependencies.all()
63 for dep in service_deps:
64 svcs.append(dep.subscriber_service)
65 return svcs
66
Scott Bakere48bf8f2018-08-30 11:49:07 -070067 def acquire_service_instance(self, subscriber_service_instance):
68 """ Given a subscriber_service_instance:
69 1) If there is an eligible provider_service_instance that can be used, then link to it
70 2) Otherwise, create a new provider_service_instance and link to it.
71
72 This is the base class, knows nothing of service specifics, so it assumes that #1 always yields no
73 eligible provider_service_instances. To get custom behavior, override this method in your own
74 convenience wrapper.
75 """
76 si_classname = self.get_service_instance_class_name()
77
78 ServiceInstanceLink = self.stub.ServiceInstanceLink
79
80 eastbound_si_class = getattr(self.stub, si_classname)
Zack Williams045b63d2019-01-22 16:30:57 -070081 eastbound_si = eastbound_si_class(owner_id=self.id)
Scott Bakere48bf8f2018-08-30 11:49:07 -070082 eastbound_si.save()
83
Zack Williams045b63d2019-01-22 16:30:57 -070084 link = ServiceInstanceLink(
85 provider_service_instance=eastbound_si,
86 subscriber_service_instance=subscriber_service_instance,
87 )
Scott Bakere48bf8f2018-08-30 11:49:07 -070088 link.save()
89
90 def validate_links(self, subscriber_service_instance):
91 """ Validate existing links between the provider and subscriber service instances. If a valid link exists,
92 then return it. Return [] otherwise.
93
94 This is the base class, knows nothing of service specifics, so it assumes that all existing links are
95 valid. To get custom behavior, override this method in your own convenience wrapper.
96 """
97 matched = []
98 for link in subscriber_service_instance.subscribed_links.all():
99 if link.provider_service_instance.owner.id == self.id:
100 matched.append(link.provider_service_instance.leaf_model)
101 return matched
102
Scott Baker6f24c452017-09-18 16:29:12 -0700103
Scott Baker89c9e6e2017-03-14 17:47:32 -0700104register_convenience_wrapper("Service", ORMWrapperService)