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.
22 from gi
.repository
import NsdYang
, NsrYang
25 class ScalingGroupIndexExists(Exception):
29 class ScaleGroupTrigger(Enum
):
30 """ Trigger for scaling config """
37 class ScaleGroupState(Enum
):
38 """ Scaling group state """
44 class ScalingGroup(object):
45 """ This represents a configured NSR scaling group """
46 def __init__(self
, log
, group_msg
):
47 """ Create a ScalingGroup instance
49 This class is responsible for representing a configured scaling group
50 which is present within an NSR.
52 :param log: A logger instance
53 :param group_msg: A NSD scaling group pb message
56 self
._group
_msg
= group_msg
61 return "ScalingGroup(%s)" % self
.name
65 """ Name of the scaling group """
66 return self
._group
_msg
.name
70 """ State of the scaling group """
71 state
= ScaleGroupState
.RUNNING
72 for instance
in self
._instances
.values():
73 if instance
.operational_status
in ["init", "vnf_init_phase"]:
74 self
._log
.debug("Scaling instance %s in scaling-out state: %s",
75 instance
, instance
.operational_status
)
76 state
= ScaleGroupState
.SCALING_OUT
78 elif instance
.operational_status
in ["terminate", "vnf_terminate_phase"]:
79 self
._log
.debug("Scaling instance %s in scaling-in state: %s",
80 instance
, instance
.operational_status
)
81 state
= ScaleGroupState
.SCALING_IN
86 def vnf_index_count_map(self
):
87 """ The mapping of member_vnf_index_ref to count"""
88 return {mbr
.member_vnf_index_ref
: mbr
.count
for mbr
in self
._group
_msg
.vnfd_member
}
92 """ Return the scale group PB message """
93 return self
._group
_msg
96 def min_instance_count(self
):
97 """ Minimum (and default) number of instance of the scaling group """
98 return self
._group
_msg
.min_instance_count
101 def max_instance_count(self
):
102 """ Maximum number of instance of the scaling group """
103 return self
._group
_msg
.max_instance_count
105 def create_record_msg(self
):
106 """ Returns a NSR Scaling group record """
107 msg
= NsrYang
.YangData_Nsr_NsInstanceOpdata_Nsr_ScalingGroupRecord(
108 scaling_group_name_ref
=self
.name
,
111 for instance
in self
.instances
:
112 msg
.instance
.append(instance
.create_record_msg())
118 return self
._instances
.values()
120 def get_instance(self
, instance_id
):
121 """ Get a scaling group instance
123 :param instance_id: The instance's instance_id
125 return self
._instances
[instance_id
]
127 def create_instance(self
, instance_id
, is_default
=False):
128 """ Create a scaling group instance
130 :param instance_id: The new instance's instance_id
132 self
._log
.debug("Creating %s instance instance_id %s ", self
, instance_id
)
134 if instance_id
in self
._instances
:
135 raise ScalingGroupIndexExists("%s instance_id %s already exists" % (self
, instance_id
))
137 instance
= ScalingGroupInstance(
139 group_name
=self
.name
,
140 instance_id
=instance_id
,
141 is_default
=is_default
,
144 self
._instances
[instance_id
] = instance
148 def delete_instance(self
, instance_id
):
149 self
._log
.debug("Deleting %s instance instance_id %s ", self
, instance_id
)
150 del self
._instances
[instance_id
]
152 def trigger_map(self
, trigger
):
154 NsdYang
.ScalingTrigger
.PRE_SCALE_IN
: 'pre_scale_in',
155 NsdYang
.ScalingTrigger
.POST_SCALE_IN
: 'post_scale_in',
156 NsdYang
.ScalingTrigger
.PRE_SCALE_OUT
: 'pre_scale_out',
157 NsdYang
.ScalingTrigger
.POST_SCALE_OUT
: 'post_scale_out',
161 return trig_map
[trigger
]
162 except Exception as e
:
163 self
._log
.error("Unknown scaling group trigger passed: {}".format(trigger
))
164 self
._log
.exception(e
)
166 def trigger_config(self
, trigger
):
167 """ Get the config action for the trigger """
168 self
._log
.debug("Trigger config {}: {}".format(trigger
, self
._group
_msg
))
169 trig
= self
.trigger_map(trigger
)
173 for config
in self
._group
_msg
.scaling_config_action
:
174 if trig
== config
.trigger
:
178 class ScalingGroupInstance(object):
179 """ This class represents a configured NSR Scaling Group instance"""
181 valid_status_list
= (
186 "vnf_terminate_phase",
191 valid_config_status_list
= (
197 def __init__(self
, log
, group_name
, instance_id
, is_default
=False):
199 self
._group
_name
= group_name
200 self
._instance
_id
= instance_id
201 self
._is
_default
= is_default
205 self
._create
_time
= int(time
.time())
206 self
._op
_status
= "init"
207 self
._config
_status
= "configuring"
208 self
._config
_err
_msg
= None
211 return "ScalingGroupInstance(%s #%s)" % (self
._group
_name
, self
.instance_id
)
214 def operational_status(self
):
215 return self
._op
_status
217 @operational_status.setter
218 def operational_status(self
, op_status
):
219 if op_status
not in ScalingGroupInstance
.valid_status_list
:
220 raise ValueError("Invalid scaling group instance status: %s", op_status
)
222 self
._op
_status
= op_status
225 def config_status(self
):
226 return self
._config
_status
228 @config_status.setter
229 def config_status(self
, status
):
230 if status
not in ScalingGroupInstance
.valid_config_status_list
:
231 raise ValueError("%s, invalid status: %s",
234 self
._config
_status
= status
237 def config_err_msg(self
):
238 return self
._config
_err
_msg
240 @config_err_msg.setter
241 def config_err_msg(self
, msg
):
242 if self
.config_err_msg
is not None:
243 self
._log
.info("%s, overwriting previous config error msg '%s' with '%s'",
244 self
, self
.config_err_msg
, msg
)
246 self
._config
_err
_msg
= msg
249 def instance_id(self
):
250 return self
._instance
_id
253 def is_default(self
):
254 return self
._is
_default
258 """ Return all VirtualNetworkFunctionRecord's that have been added"""
259 return self
._vnfrs
.values()
261 def create_record_msg(self
):
262 msg
= NsrYang
.YangData_Nsr_NsInstanceOpdata_Nsr_ScalingGroupRecord_Instance(
263 instance_id
=self
._instance
_id
,
264 create_time
=self
._create
_time
,
265 op_status
=self
._op
_status
,
266 config_status
=self
._config
_status
,
267 error_msg
=self
._config
_err
_msg
,
268 is_default
=self
._is
_default
271 for vnfr
in self
.vnfrs
:
272 msg
.vnfrs
.append(vnfr
.id)
276 def add_vnfr(self
, vnfr
):
277 """ Add a VirtualNetworkFunctionRecord"""
278 self
._log
.debug("Added %s to %s", vnfr
, self
)
279 self
._vnfrs
[vnfr
.id] = vnfr