blob: 8c9985a5d5788d434beea0671f18725768ef0bc9 [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
Zack Williams5c2ea232019-01-30 15:23:01 -070015from __future__ import absolute_import
16
Scott Baker89c9e6e2017-03-14 17:47:32 -070017from xosapi.orm import ORMWrapper, register_convenience_wrapper
18
Zack Williams045b63d2019-01-22 16:30:57 -070019
Scott Baker89c9e6e2017-03-14 17:47:32 -070020class ORMWrapperService(ORMWrapper):
21 @property
22 def serviceattribute_dict(self):
23 attrs = {}
24 for attr in self.serviceattributes.all():
25 attrs[attr.name] = attr.value
26 return attrs
27
Scott Baker79808902017-03-15 15:51:21 -070028 def get_composable_networks(self):
Zack Williams045b63d2019-01-22 16:30:57 -070029 SUPPORTED_VTN_SERVCOMP_KINDS = ["VSG", "PRIVATE"]
Scott Baker79808902017-03-15 15:51:21 -070030
31 nets = []
32 for slice in self.slices.all():
33 for net in slice.networks.all():
Zack Williams045b63d2019-01-22 16:30:57 -070034 if (net.template.vtn_kind not in SUPPORTED_VTN_SERVCOMP_KINDS) or (
35 net.owner.id != slice.id
36 ):
Scott Baker79808902017-03-15 15:51:21 -070037 continue
38
39 if not net.controllernetworks.exists():
40 continue
41 nets.append(net)
42 return nets
43
Scott Baker6f24c452017-09-18 16:29:12 -070044 def get_service_instance_class_name(self):
45 # This assumes that a ServiceInstance is always named after its service. For example
46 # VSGService --> VSGServiceInstance. Services in which this is not the case should override this method.
47 # TODO: Specify via xproto ?
48 return self.leaf_model_name + "Instance"
49
50 def get_service_instance_class(self):
Scott Baker8f36c3f2017-09-26 16:44:36 -070051 return getattr(self.stub, self.get_service_instance_class_name())
Scott Baker6f24c452017-09-18 16:29:12 -070052
Matteo Scandolo5d607282018-04-11 09:19:25 -070053 @property
54 def provider_services(self):
55 svcs = []
56 service_deps = self.subscribed_dependencies.all()
57 for dep in service_deps:
58 svcs.append(dep.provider_service)
59 return svcs
60
61 @property
62 def subscriber_services(self):
63 svcs = []
64 service_deps = self.provided_dependencies.all()
65 for dep in service_deps:
66 svcs.append(dep.subscriber_service)
67 return svcs
68
Scott Bakere48bf8f2018-08-30 11:49:07 -070069 def acquire_service_instance(self, subscriber_service_instance):
70 """ Given a subscriber_service_instance:
71 1) If there is an eligible provider_service_instance that can be used, then link to it
72 2) Otherwise, create a new provider_service_instance and link to it.
73
74 This is the base class, knows nothing of service specifics, so it assumes that #1 always yields no
75 eligible provider_service_instances. To get custom behavior, override this method in your own
76 convenience wrapper.
77 """
78 si_classname = self.get_service_instance_class_name()
79
80 ServiceInstanceLink = self.stub.ServiceInstanceLink
81
82 eastbound_si_class = getattr(self.stub, si_classname)
Zack Williams045b63d2019-01-22 16:30:57 -070083 eastbound_si = eastbound_si_class(owner_id=self.id)
Scott Bakere48bf8f2018-08-30 11:49:07 -070084 eastbound_si.save()
85
Zack Williams045b63d2019-01-22 16:30:57 -070086 link = ServiceInstanceLink(
87 provider_service_instance=eastbound_si,
88 subscriber_service_instance=subscriber_service_instance,
89 )
Scott Bakere48bf8f2018-08-30 11:49:07 -070090 link.save()
91
92 def validate_links(self, subscriber_service_instance):
93 """ Validate existing links between the provider and subscriber service instances. If a valid link exists,
94 then return it. Return [] otherwise.
95
96 This is the base class, knows nothing of service specifics, so it assumes that all existing links are
97 valid. To get custom behavior, override this method in your own convenience wrapper.
98 """
99 matched = []
100 for link in subscriber_service_instance.subscribed_links.all():
101 if link.provider_service_instance.owner.id == self.id:
102 matched.append(link.provider_service_instance.leaf_model)
103 return matched
104
Scott Baker6f24c452017-09-18 16:29:12 -0700105
Scott Baker89c9e6e2017-03-14 17:47:32 -0700106register_convenience_wrapper("Service", ORMWrapperService)