3 # Copyright 2016-2017 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 (
23 ProjectNsdYang
as NsdYang
,
28 class ScalingGroupIndexExists(Exception):
32 class ScaleGroupTrigger(Enum
):
33 """ Trigger for scaling config """
40 class ScaleGroupState(Enum
):
41 """ Scaling group state """
47 class ScalingGroup(object):
48 """ This represents a configured NSR scaling group """
49 def __init__(self
, log
, group_msg
):
50 """ Create a ScalingGroup instance
52 This class is responsible for representing a configured scaling group
53 which is present within an NSR.
55 :param log: A logger instance
56 :param group_msg: A NSD scaling group pb message
59 self
._group
_msg
= group_msg
64 return "ScalingGroup(%s)" % self
.name
68 """ Name of the scaling group """
69 return self
._group
_msg
.name
73 """ State of the scaling group """
74 state
= ScaleGroupState
.RUNNING
75 for instance
in self
._instances
.values():
76 if instance
.operational_status
in ["init", "vnf_init_phase"]:
77 self
._log
.debug("Scaling instance %s in scaling-out state: %s",
78 instance
, instance
.operational_status
)
79 state
= ScaleGroupState
.SCALING_OUT
81 elif instance
.operational_status
in ["terminate", "vnf_terminate_phase"]:
82 self
._log
.debug("Scaling instance %s in scaling-in state: %s",
83 instance
, instance
.operational_status
)
84 state
= ScaleGroupState
.SCALING_IN
89 def vnf_index_count_map(self
):
90 """ The mapping of member_vnf_index_ref to count"""
91 return {mbr
.member_vnf_index_ref
: mbr
.count
for mbr
in self
._group
_msg
.vnfd_member
}
95 """ Return the scale group PB message """
96 return self
._group
_msg
99 def min_instance_count(self
):
100 """ Minimum (and default) number of instance of the scaling group """
101 return self
._group
_msg
.min_instance_count
104 def max_instance_count(self
):
105 """ Maximum number of instance of the scaling group """
106 return self
._group
_msg
.max_instance_count
108 def create_record_msg(self
):
109 """ Returns a NSR Scaling group record """
110 msg
= NsrYang
.YangData_RwProject_Project_NsInstanceOpdata_Nsr_ScalingGroupRecord(
111 scaling_group_name_ref
=self
.name
,
114 for instance
in self
.instances
:
115 msg
.instance
.append(instance
.create_record_msg())
121 return self
._instances
.values()
123 def get_instance(self
, instance_id
):
124 """ Get a scaling group instance
126 :param instance_id: The instance's instance_id
128 return self
._instances
[instance_id
]
130 def create_instance(self
, instance_id
, is_default
=False):
131 """ Create a scaling group instance
133 :param instance_id: The new instance's instance_id
135 self
._log
.debug("Creating %s instance instance_id %s ", self
, instance_id
)
137 if instance_id
in self
._instances
:
138 raise ScalingGroupIndexExists("%s instance_id %s already exists" % (self
, instance_id
))
140 instance
= ScalingGroupInstance(
142 group_name
=self
.name
,
143 instance_id
=instance_id
,
144 is_default
=is_default
,
147 self
._instances
[instance_id
] = instance
151 def delete_instance(self
, instance_id
):
152 self
._log
.debug("Deleting %s instance instance_id %s ", self
, instance_id
)
153 del self
._instances
[instance_id
]
155 def trigger_map(self
, trigger
):
157 NsdYang
.ScalingTrigger
.PRE_SCALE_IN
: 'pre_scale_in',
158 NsdYang
.ScalingTrigger
.POST_SCALE_IN
: 'post_scale_in',
159 NsdYang
.ScalingTrigger
.PRE_SCALE_OUT
: 'pre_scale_out',
160 NsdYang
.ScalingTrigger
.POST_SCALE_OUT
: 'post_scale_out',
164 return trig_map
[trigger
]
165 except Exception as e
:
166 self
._log
.error("Unknown scaling group trigger passed: {}".format(trigger
))
167 self
._log
.exception(e
)
169 def trigger_config(self
, trigger
):
170 """ Get the config action for the trigger """
171 self
._log
.debug("Trigger config {}: {}".format(trigger
, self
._group
_msg
))
172 trig
= self
.trigger_map(trigger
)
176 for config
in self
._group
_msg
.scaling_config_action
:
177 if trig
== config
.trigger
:
181 class ScalingGroupInstance(object):
182 """ This class represents a configured NSR Scaling Group instance"""
184 valid_status_list
= (
189 "vnf_terminate_phase",
194 valid_config_status_list
= (
200 def __init__(self
, log
, group_name
, instance_id
, is_default
=False):
202 self
._group
_name
= group_name
203 self
._instance
_id
= instance_id
204 self
._is
_default
= is_default
208 self
._create
_time
= int(time
.time())
209 self
._op
_status
= "init"
210 self
._config
_status
= "configuring"
211 self
._config
_err
_msg
= None
214 return "ScalingGroupInstance(%s #%s)" % (self
._group
_name
, self
.instance_id
)
217 def operational_status(self
):
218 return self
._op
_status
220 @operational_status.setter
221 def operational_status(self
, op_status
):
222 if op_status
not in ScalingGroupInstance
.valid_status_list
:
223 raise ValueError("Invalid scaling group instance status: %s", op_status
)
225 self
._op
_status
= op_status
228 def config_status(self
):
229 return self
._config
_status
231 @config_status.setter
232 def config_status(self
, status
):
233 if status
not in ScalingGroupInstance
.valid_config_status_list
:
234 raise ValueError("%s, invalid status: %s",
237 self
._config
_status
= status
240 def config_err_msg(self
):
241 return self
._config
_err
_msg
243 @config_err_msg.setter
244 def config_err_msg(self
, msg
):
245 if self
.config_err_msg
is not None:
246 self
._log
.info("%s, overwriting previous config error msg '%s' with '%s'",
247 self
, self
.config_err_msg
, msg
)
249 self
._config
_err
_msg
= msg
252 def instance_id(self
):
253 return self
._instance
_id
256 def is_default(self
):
257 return self
._is
_default
261 """ Return all VirtualNetworkFunctionRecord's that have been added"""
262 return self
._vnfrs
.values()
264 def create_record_msg(self
):
265 msg
= NsrYang
.YangData_RwProject_Project_NsInstanceOpdata_Nsr_ScalingGroupRecord_Instance(
266 instance_id
=self
._instance
_id
,
267 create_time
=self
._create
_time
,
268 op_status
=self
._op
_status
,
269 config_status
=self
._config
_status
,
270 error_msg
=self
._config
_err
_msg
,
271 is_default
=self
._is
_default
274 for vnfr
in self
.vnfrs
:
275 msg
.vnfrs
.append(vnfr
.id)
279 def add_vnfr(self
, vnfr
):
280 """ Add a VirtualNetworkFunctionRecord"""
281 self
._log
.debug("Added %s to %s", vnfr
, self
)
282 self
._vnfrs
[vnfr
.id] = vnfr