RFE alarm monitor: Fix hardcoded metadata,add func. test
This patch will focus on: 1. Fixing hardcoded metadata 2. Adding functional test for alarm monitor 3. Refactoring tosca template for alarm monitor 4. Refactoring scaling in/out support in alarm monitor 5. Supporting multi-trigger Partial-bug: #1630614 Change-Id: Ic5d0046d0dc0b4381713bda01c485cecae17abea
This commit is contained in:
parent
a1dd7fd73d
commit
0eafa5b1bf
@ -44,20 +44,81 @@ described firstly like other TOSCA templates in Tacker.
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
actions: [respawn]
|
||||||
resize_compute:
|
|
||||||
action_name: respawn
|
|
||||||
|
|
||||||
Alarm framework already supported the some default backend actions like
|
Alarm framework already supported the some default backend actions like
|
||||||
**respawn, log, and log_and_kill**.
|
**scaling, respawn, log, and log_and_kill**.
|
||||||
|
|
||||||
Tacker users could change the desired action as described in the above example.
|
Tacker users could change the desired action as described in the above example.
|
||||||
Until now, the backend actions could be pointed to the specific policy which
|
Until now, the backend actions could be pointed to the specific policy which
|
||||||
is also described in TOSCA template like scaling policy. The integration between
|
is also described in TOSCA template like scaling policy. The integration between
|
||||||
alarming monitoring and auto-scaling was also supported by Alarm monitor in Tacker:
|
alarming monitoring and scaling was also supported by Alarm monitor in Tacker:
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
description: Demo example
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
template_name: sample-tosca-vnfd
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU1
|
||||||
|
VDU2:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
|
CP2:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU2
|
||||||
|
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VL
|
||||||
|
properties:
|
||||||
|
network_name: net_mgmt
|
||||||
|
vendor: Tacker
|
||||||
|
|
||||||
policies:
|
policies:
|
||||||
- SP1:
|
- SP1:
|
||||||
type: tosca.policies.tacker.Scaling
|
type: tosca.policies.tacker.Scaling
|
||||||
@ -67,12 +128,12 @@ alarming monitoring and auto-scaling was also supported by Alarm monitor in Tack
|
|||||||
min_instances: 1
|
min_instances: 1
|
||||||
max_instances: 3
|
max_instances: 3
|
||||||
default_instances: 2
|
default_instances: 2
|
||||||
targets: [VDU1]
|
targets: [VDU1,VDU2]
|
||||||
|
|
||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_scaling_out:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: ceilometer
|
implementation: ceilometer
|
||||||
@ -84,9 +145,28 @@ alarming monitoring and auto-scaling was also supported by Alarm monitor in Tack
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: SG1
|
||||||
resize_compute:
|
actions: [SP1]
|
||||||
action_name: SP1
|
|
||||||
|
vdu_lcpu_usage_scaling_in:
|
||||||
|
targets: [VDU1, VDU2]
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 10
|
||||||
|
constraint: utilization less_than 10%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: lt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
||||||
|
|
||||||
|
|
||||||
|
**NOTE:**
|
||||||
|
metadata defined in VDU properties must be matched with metadata in monitoring policy
|
||||||
|
|
||||||
How to setup environment
|
How to setup environment
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -112,45 +192,47 @@ is successfully passed to Ceilometer, Tacker users could use CLI:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ceilometer alarm-list
|
$aodh alarm list
|
||||||
|
|
||||||
+--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+------------+-------------------------------------+------------------+
|
+--------------------------------------+-----------+--------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+
|
||||||
| Alarm ID | Name | State | Severity | Enabled | Continuous | Alarm condition | Time constraints |
|
| alarm_id | type | name | state | severity | enabled |
|
||||||
+--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+------------+-------------------------------------+------------------+
|
+--------------------------------------+-----------+--------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+
|
||||||
| f6a89242-d849-4a1a-9eb5-de4c0730252f | tacker.vnfm.infra_drivers.openstack.openstack_OpenStack-d4900104-6257-4084-8506-9fa6895d1294-vdu1_cpu_usage_monitoring_policy-7rt36gqbmuqo | insufficient data | low | True | True | avg(cpu_util) > 15.0 during 1 x 65s | None |
|
| 6f2336b9-e0a2-4e33-88be-bc036192b42b | threshold | tacker.vnfm.infra_drivers.openstack.openstack_OpenStack-a0f60b00-ad3d-4769-92ef-e8d9518da2c8-vdu_lcpu_scaling_in-smgctfnc3ql5 | insufficient data | low | True |
|
||||||
+--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+------------+-------------------------------------+------------------
|
| e049f0d3-09a8-46c0-9b88-e61f1f524aab | threshold | tacker.vnfm.infra_drivers.openstack.openstack_OpenStack-a0f60b00-ad3d-4769-92ef-e8d9518da2c8-vdu_hcpu_usage_scaling_out-lubylov5g6xb | insufficient data | low | True |
|
||||||
|
+--------------------------------------+-----------+--------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------+---------+
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ ceilometer alarm-show 35a80852-e24f-46ed-bd34-e2f831d00172
|
$aodh alarm show 6f2336b9-e0a2-4e33-88be-bc036192b42b
|
||||||
|
|
||||||
+---------------------------+--------------------------------------------------------------------------+
|
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| Property | Value |
|
| Field | Value |
|
||||||
+---------------------------+--------------------------------------------------------------------------+
|
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| alarm_actions | ["http://pinedcn:9890/v1.0/vnfs/d4900104-6257-4084-8506-9fa6895d1294/vdu |
|
| alarm_actions | [u'http://pinedcn:9890/v1.0/vnfs/a0f60b00-ad3d-4769-92ef-e8d9518da2c8/vdu_lcpu_scaling_in/SP1-in/yl7kh5qd'] |
|
||||||
| | 1_cpu_usage_monitoring_policy/SP1/i42kd018"] |
|
| alarm_id | 6f2336b9-e0a2-4e33-88be-bc036192b42b |
|
||||||
| alarm_id | f6a89242-d849-4a1a-9eb5-de4c0730252f |
|
| comparison_operator | lt |
|
||||||
| comparison_operator | gt |
|
| description | utilization less_than 10% |
|
||||||
| description | utilization greater_than 50% |
|
|
||||||
| enabled | True |
|
| enabled | True |
|
||||||
| evaluation_periods | 1 |
|
| evaluation_periods | 1 |
|
||||||
| exclude_outliers | False |
|
| exclude_outliers | False |
|
||||||
| insufficient_data_actions | None |
|
| insufficient_data_actions | None |
|
||||||
| meter_name | cpu_util |
|
| meter_name | cpu_util |
|
||||||
| name | tacker.vnfm.infra_drivers.openstack.openstack_OpenStack-d4900104-6257-40 |
|
| name | tacker.vnfm.infra_drivers.openstack.openstack_OpenStack-a0f60b00-ad3d-4769-92ef-e8d9518da2c8-vdu_lcpu_scaling_in-smgctfnc3ql5 |
|
||||||
| | 84-8506-9fa6895d1294-vdu1_cpu_usage_monitoring_policy-7rt36gqbmuqo |
|
|
||||||
| ok_actions | None |
|
| ok_actions | None |
|
||||||
| period | 65 |
|
| period | 600 |
|
||||||
| project_id | abdc74442be44b9486ca5e32a980bca1 |
|
| project_id | 3db801789c9e4b61b14ce448c9e7fb6d |
|
||||||
| query | metadata.user_metadata.vnf_id == d4900104-6257-4084-8506-9fa6895d1294 |
|
| query | metadata.user_metadata.vnf_id = a0f60b00-ad3d-4769-92ef-e8d9518da2c8 |
|
||||||
| repeat_actions | True |
|
| repeat_actions | True |
|
||||||
| severity | low |
|
| severity | low |
|
||||||
| state | insufficient data |
|
| state | insufficient data |
|
||||||
|
| state_timestamp | 2016-11-16T18:39:30.134954 |
|
||||||
| statistic | avg |
|
| statistic | avg |
|
||||||
| threshold | 15.0 |
|
| threshold | 10.0 |
|
||||||
|
| time_constraints | [] |
|
||||||
|
| timestamp | 2016-11-16T18:39:30.134954 |
|
||||||
| type | threshold |
|
| type | threshold |
|
||||||
| user_id | 25a691398e534893b8627f3762712515 |
|
| user_id | a783e8a94768484fb9a43af03c6426cb |
|
||||||
+---------------------------+--------------------------------------------------------------------------+
|
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
How to trigger alarms:
|
How to trigger alarms:
|
||||||
@ -167,7 +249,7 @@ Another way could be used to check if backend action is handled well in Tacker:
|
|||||||
|
|
||||||
.. code-block::ini
|
.. code-block::ini
|
||||||
|
|
||||||
curl -H "Content-Type: application/json" -X POST -d '{"alarm_id": "35a80852-e24f-46ed-bd34-e2f831d00172", "current": "alarm"}' http://ubuntu:9890/v1.0/vnfs/6f3e523d-9e12-4973-a2e8-ea04b9601253/vdu1_cpu_usage_monitoring_policy/respawn/g0jtsxu9
|
curl -H "Content-Type: application/json" -X POST -d '{"alarm_id": "35a80852-e24f-46ed-bd34-e2f831d00172", "current": "alarm"}' http://pinedcn:9890/v1.0/vnfs/a0f60b00-ad3d-4769-92ef-e8d9518da2c8/vdu_lcpu_scaling_in/SP1-in/yl7kh5qd
|
||||||
|
|
||||||
Then, users can check Horizon to know if vnf is respawned. Please note that the url used
|
Then, users can check Horizon to know if vnf is respawned. Please note that the url used
|
||||||
in the above command could be captured from "**ceilometer alarm-show** command as shown before.
|
in the above command could be captured from "**ceilometer alarm-show** command as shown before.
|
||||||
|
@ -18,6 +18,7 @@ topology_template:
|
|||||||
image: cirros-0.3.4-x86_64-uec
|
image: cirros-0.3.4-x86_64-uec
|
||||||
mgmt_driver: noop
|
mgmt_driver: noop
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: VDU1}
|
||||||
|
|
||||||
CP1:
|
CP1:
|
||||||
type: tosca.nodes.nfv.CP.Tacker
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
@ -40,7 +41,7 @@ topology_template:
|
|||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_respawning:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: ceilometer
|
implementation: ceilometer
|
||||||
@ -52,6 +53,5 @@ topology_template:
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: VDU1
|
||||||
resize_compute:
|
actions: [respawn]
|
||||||
action_name: respawn
|
|
||||||
|
@ -18,6 +18,7 @@ topology_template:
|
|||||||
image: cirros-0.3.4-x86_64-uec
|
image: cirros-0.3.4-x86_64-uec
|
||||||
mgmt_driver: noop
|
mgmt_driver: noop
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
CP1:
|
CP1:
|
||||||
type: tosca.nodes.nfv.CP.Tacker
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
@ -29,6 +30,30 @@ topology_template:
|
|||||||
node: VL1
|
node: VL1
|
||||||
- virtualBinding:
|
- virtualBinding:
|
||||||
node: VDU1
|
node: VDU1
|
||||||
|
VDU2:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
|
CP2:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU2
|
||||||
|
|
||||||
VL1:
|
VL1:
|
||||||
type: tosca.nodes.nfv.VL
|
type: tosca.nodes.nfv.VL
|
||||||
@ -45,12 +70,12 @@ topology_template:
|
|||||||
min_instances: 1
|
min_instances: 1
|
||||||
max_instances: 3
|
max_instances: 3
|
||||||
default_instances: 2
|
default_instances: 2
|
||||||
targets: [VDU1]
|
targets: [VDU1,VDU2]
|
||||||
|
|
||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_scaling_out:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: ceilometer
|
implementation: ceilometer
|
||||||
@ -62,6 +87,21 @@ topology_template:
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: SG1
|
||||||
resize_compute:
|
actions: [SP1]
|
||||||
action_name: SP1
|
|
||||||
|
vdu_lcpu_usage_scaling_in:
|
||||||
|
targets: [VDU1, VDU2]
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 10
|
||||||
|
constraint: utilization less_than 10%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: lt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
||||||
|
@ -249,6 +249,10 @@ class AlarmUrlInvalid(BadRequest):
|
|||||||
message = _("Invalid alarm url for VNF %(vnf_id)s")
|
message = _("Invalid alarm url for VNF %(vnf_id)s")
|
||||||
|
|
||||||
|
|
||||||
|
class TriggerNotFound(NotFound):
|
||||||
|
message = _("Trigger %(trigger_name)s does not exist for VNF %(vnf_id)s")
|
||||||
|
|
||||||
|
|
||||||
class VnfPolicyNotFound(NotFound):
|
class VnfPolicyNotFound(NotFound):
|
||||||
message = _("Policy %(policy)s does not exist for VNF %(vnf_id)s")
|
message = _("Policy %(policy)s does not exist for VNF %(vnf_id)s")
|
||||||
|
|
||||||
|
@ -153,6 +153,10 @@ class VNFInactive(exceptions.InvalidInput):
|
|||||||
message = _("VNF %(vnf_id)s is not in Active state %(message)s")
|
message = _("VNF %(vnf_id)s is not in Active state %(message)s")
|
||||||
|
|
||||||
|
|
||||||
|
class MetadataNotMatched(exceptions.InvalidInput):
|
||||||
|
message = _("Metadata for alarm policy is not matched")
|
||||||
|
|
||||||
|
|
||||||
def _validate_service_type_list(data, valid_values=None):
|
def _validate_service_type_list(data, valid_values=None):
|
||||||
if not isinstance(data, list):
|
if not isinstance(data, list):
|
||||||
msg = _("invalid data format for service list: '%s'") % data
|
msg = _("invalid data format for service list: '%s'") % data
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
POLICY_ALARMING = 'tosca.policies.tacker.Alarming'
|
||||||
|
DEFAULT_ALARM_ACTIONS = ['respawn', 'log', 'log_and_kill', 'notify']
|
||||||
VNF_CIRROS_CREATE_TIMEOUT = 300
|
VNF_CIRROS_CREATE_TIMEOUT = 300
|
||||||
VNF_CIRROS_DELETE_TIMEOUT = 300
|
VNF_CIRROS_DELETE_TIMEOUT = 300
|
||||||
VNF_CIRROS_DEAD_TIMEOUT = 250
|
VNF_CIRROS_DEAD_TIMEOUT = 250
|
||||||
|
57
tacker/tests/etc/samples/sample-tosca-alarm-respawn.yaml
Normal file
57
tacker/tests/etc/samples/sample-tosca-alarm-respawn.yaml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
description: Demo example
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
template_name: sample-tosca-vnfd
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: VDU1}
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU1
|
||||||
|
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VL
|
||||||
|
properties:
|
||||||
|
network_name: net_mgmt
|
||||||
|
vendor: Tacker
|
||||||
|
|
||||||
|
policies:
|
||||||
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
|
type: tosca.policies.tacker.Alarming
|
||||||
|
triggers:
|
||||||
|
vdu_hcpu_usage_respawning:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 50
|
||||||
|
constraint: utilization greater_than 50%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: gt
|
||||||
|
metadata: VDU1
|
||||||
|
actions: [respawn]
|
82
tacker/tests/etc/samples/sample-tosca-alarm-scale.yaml
Normal file
82
tacker/tests/etc/samples/sample-tosca-alarm-scale.yaml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
description: Demo example
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
template_name: sample-tosca-vnfd
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU1
|
||||||
|
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VL
|
||||||
|
properties:
|
||||||
|
network_name: net_mgmt
|
||||||
|
vendor: Tacker
|
||||||
|
|
||||||
|
policies:
|
||||||
|
- SP1:
|
||||||
|
type: tosca.policies.tacker.Scaling
|
||||||
|
properties:
|
||||||
|
increment: 1
|
||||||
|
cooldown: 60
|
||||||
|
min_instances: 1
|
||||||
|
max_instances: 3
|
||||||
|
default_instances: 2
|
||||||
|
targets: [VDU1]
|
||||||
|
|
||||||
|
- vdu_cpu_usage_monitoring_policy:
|
||||||
|
type: tosca.policies.tacker.Alarming
|
||||||
|
triggers:
|
||||||
|
vdu_hcpu_usage_scaling_out:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 50
|
||||||
|
constraint: utilization greater_than 50%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: gt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
||||||
|
|
||||||
|
vdu_hcpu_usage_scaling_in:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 10
|
||||||
|
constraint: utilization less_than 10%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: lt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
150
tacker/tests/functional/vnfm/test_tosca_vnf_alarm.py
Normal file
150
tacker/tests/functional/vnfm/test_tosca_vnf_alarm.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
from tacker.plugins.common import constants as evt_constants
|
||||||
|
from tacker.tests import constants
|
||||||
|
from tacker.tests.functional import base
|
||||||
|
from tacker.tests.utils import read_file
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
class VnfTestAlarmMonitor(base.BaseTackerTest):
|
||||||
|
|
||||||
|
def _test_vnf_tosca_alarm(self, vnfd_file, vnf_name):
|
||||||
|
vnf_trigger_path = '/vnfs/%s/triggers'
|
||||||
|
data = dict()
|
||||||
|
data['tosca'] = read_file(vnfd_file)
|
||||||
|
tosca_dict = yaml.safe_load(data['tosca'])
|
||||||
|
toscal = data['tosca']
|
||||||
|
tosca_arg = {'vnfd': {'name': vnf_name,
|
||||||
|
'attributes': {'vnfd': toscal}}}
|
||||||
|
|
||||||
|
# Create vnfd with tosca template
|
||||||
|
vnfd_instance = self.client.create_vnfd(body=tosca_arg)
|
||||||
|
self.assertIsNotNone(vnfd_instance)
|
||||||
|
|
||||||
|
# Create vnf with vnfd_id
|
||||||
|
vnfd_id = vnfd_instance['vnfd']['id']
|
||||||
|
vnf_arg = {'vnf': {'vnfd_id': vnfd_id, 'name': vnf_name}}
|
||||||
|
vnf_instance = self.client.create_vnf(body=vnf_arg)
|
||||||
|
|
||||||
|
self.validate_vnf_instance(vnfd_instance, vnf_instance)
|
||||||
|
|
||||||
|
vnf_id = vnf_instance['vnf']['id']
|
||||||
|
|
||||||
|
def _waiting_time(count):
|
||||||
|
self.wait_until_vnf_active(
|
||||||
|
vnf_id,
|
||||||
|
constants.VNF_CIRROS_CREATE_TIMEOUT,
|
||||||
|
constants.ACTIVE_SLEEP_TIME)
|
||||||
|
vnf = self.client.show_vnf(vnf_id)['vnf']
|
||||||
|
# {"VDU1": ["10.0.0.14", "10.0.0.5"]}
|
||||||
|
self.assertEqual(count, len(json.loads(vnf['mgmt_url'])['VDU1']))
|
||||||
|
|
||||||
|
def trigger_vnf(vnf, policy_name, policy_action):
|
||||||
|
credential = 'g0jtsxu9'
|
||||||
|
body = {"trigger": {'policy_name': policy_name,
|
||||||
|
'action_name': policy_action,
|
||||||
|
'params': {
|
||||||
|
'data': {'alarm_id': '35a80852-e24f-46ed-bd34-e2f831d00172', 'current': 'alarm'}, # noqa
|
||||||
|
'credential': credential}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.client.post(vnf_trigger_path % vnf, body)
|
||||||
|
|
||||||
|
def _inject_monitoring_policy(vnfd_dict):
|
||||||
|
if vnfd_dict.get('tosca_definitions_version'):
|
||||||
|
polices = vnfd_dict['topology_template'].get('policies', [])
|
||||||
|
mon_policy = dict()
|
||||||
|
for policy_dict in polices:
|
||||||
|
for name, policy in policy_dict.items():
|
||||||
|
if policy['type'] == constants.POLICY_ALARMING:
|
||||||
|
triggers = policy['triggers']
|
||||||
|
for trigger_name, trigger_dict in triggers.items():
|
||||||
|
policy_action_list = trigger_dict['actions']
|
||||||
|
for policy_action in policy_action_list:
|
||||||
|
mon_policy[trigger_name] = policy_action
|
||||||
|
return mon_policy
|
||||||
|
|
||||||
|
def verify_policy(policy_dict, kw_policy):
|
||||||
|
for name, action in policy_dict.items():
|
||||||
|
if kw_policy in name:
|
||||||
|
return name
|
||||||
|
|
||||||
|
# trigger alarm
|
||||||
|
monitoring_policy = _inject_monitoring_policy(tosca_dict)
|
||||||
|
for mon_policy_name, mon_policy_action in monitoring_policy.items():
|
||||||
|
if mon_policy_action in constants.DEFAULT_ALARM_ACTIONS:
|
||||||
|
self.wait_until_vnf_active(
|
||||||
|
vnf_id,
|
||||||
|
constants.VNF_CIRROS_CREATE_TIMEOUT,
|
||||||
|
constants.ACTIVE_SLEEP_TIME)
|
||||||
|
trigger_vnf(vnf_id, mon_policy_name, mon_policy_action)
|
||||||
|
else:
|
||||||
|
if 'scaling_out' in mon_policy_name:
|
||||||
|
_waiting_time(2)
|
||||||
|
time.sleep(constants.SCALE_WINDOW_SLEEP_TIME)
|
||||||
|
# scaling-out backend action
|
||||||
|
scaling_out_action = mon_policy_action + '-out'
|
||||||
|
trigger_vnf(vnf_id, mon_policy_name, scaling_out_action)
|
||||||
|
|
||||||
|
_waiting_time(3)
|
||||||
|
|
||||||
|
scaling_in_name = verify_policy(monitoring_policy,
|
||||||
|
kw_policy='scaling_in')
|
||||||
|
if scaling_in_name:
|
||||||
|
time.sleep(constants.SCALE_WINDOW_SLEEP_TIME)
|
||||||
|
# scaling-in backend action
|
||||||
|
scaling_in_action = mon_policy_action + '-in'
|
||||||
|
trigger_vnf(vnf_id, scaling_in_name, scaling_in_action)
|
||||||
|
|
||||||
|
_waiting_time(2)
|
||||||
|
|
||||||
|
self.verify_vnf_crud_events(
|
||||||
|
vnf_id, evt_constants.RES_EVT_SCALE,
|
||||||
|
evt_constants.ACTIVE, cnt=2)
|
||||||
|
self.verify_vnf_crud_events(
|
||||||
|
vnf_id, evt_constants.RES_EVT_SCALE,
|
||||||
|
evt_constants.PENDING_SCALE_OUT, cnt=1)
|
||||||
|
self.verify_vnf_crud_events(
|
||||||
|
vnf_id, evt_constants.RES_EVT_SCALE,
|
||||||
|
evt_constants.PENDING_SCALE_IN, cnt=1)
|
||||||
|
# Delete vnf_instance with vnf_id
|
||||||
|
try:
|
||||||
|
self.client.delete_vnf(vnf_id)
|
||||||
|
except Exception:
|
||||||
|
assert False, ("Failed to delete vnf %s after the monitor test" %
|
||||||
|
vnf_id)
|
||||||
|
|
||||||
|
# Verify VNF monitor events captured for states, ACTIVE and DEAD
|
||||||
|
vnf_state_list = [evt_constants.ACTIVE, evt_constants.DEAD]
|
||||||
|
self.verify_vnf_monitor_events(vnf_id, vnf_state_list)
|
||||||
|
|
||||||
|
# Delete vnfd_instance
|
||||||
|
self.addCleanup(self.client.delete_vnfd, vnfd_id)
|
||||||
|
self.addCleanup(self.wait_until_vnf_delete, vnf_id,
|
||||||
|
constants.VNF_CIRROS_DELETE_TIMEOUT)
|
||||||
|
|
||||||
|
def test_vnf_alarm_respawn(self):
|
||||||
|
self._test_vnf_tosca_alarm(
|
||||||
|
'sample-tosca-alarm-respawn.yaml',
|
||||||
|
'alarm and respawn vnf')
|
||||||
|
|
||||||
|
def test_vnf_alarm_scale(self):
|
||||||
|
self._test_vnf_tosca_alarm(
|
||||||
|
'sample-tosca-alarm-scale.yaml',
|
||||||
|
'alarm and scale vnf')
|
@ -250,8 +250,7 @@ class TestDeviceHeat(base.TestCase):
|
|||||||
tosca_tpl_name,
|
tosca_tpl_name,
|
||||||
hot_tpl_name,
|
hot_tpl_name,
|
||||||
param_values='',
|
param_values='',
|
||||||
is_monitor=True,
|
is_monitor=True):
|
||||||
is_alarm=False):
|
|
||||||
tosca_tpl = _get_template(tosca_tpl_name)
|
tosca_tpl = _get_template(tosca_tpl_name)
|
||||||
exp_tmpl = self._get_expected_vnfd(tosca_tpl)
|
exp_tmpl = self._get_expected_vnfd(tosca_tpl)
|
||||||
tosca_hw_dict = yaml.safe_load(_get_template(hot_tpl_name))
|
tosca_hw_dict = yaml.safe_load(_get_template(hot_tpl_name))
|
||||||
@ -279,11 +278,9 @@ class TestDeviceHeat(base.TestCase):
|
|||||||
'"respawn"}, "parameters": {"count": 3, '
|
'"respawn"}, "parameters": {"count": 3, '
|
||||||
'"interval": 10}, "monitoring_params": '
|
'"interval": 10}, "monitoring_params": '
|
||||||
'{"count": 3, "interval": 10}}}}}'})
|
'{"count": 3, "interval": 10}}}}}'})
|
||||||
if is_alarm:
|
|
||||||
dvc['attributes'].update({'alarm_url': ''})
|
|
||||||
return dvc
|
return dvc
|
||||||
|
|
||||||
def _get_dummy_tosca_vnf(self, template, input_params='', is_alarm=False):
|
def _get_dummy_tosca_vnf(self, template, input_params=''):
|
||||||
|
|
||||||
tosca_template = _get_template(template)
|
tosca_template = _get_template(template)
|
||||||
vnf = utils.get_dummy_device_obj()
|
vnf = utils.get_dummy_device_obj()
|
||||||
@ -292,24 +289,20 @@ class TestDeviceHeat(base.TestCase):
|
|||||||
vnf['vnfd'] = dtemplate
|
vnf['vnfd'] = dtemplate
|
||||||
vnf['attributes'] = {}
|
vnf['attributes'] = {}
|
||||||
vnf['attributes']['param_values'] = input_params
|
vnf['attributes']['param_values'] = input_params
|
||||||
if is_alarm:
|
|
||||||
vnf['attributes']['alarm_url'] = ''
|
|
||||||
return vnf
|
return vnf
|
||||||
|
|
||||||
def _test_assert_equal_for_tosca_templates(self, tosca_tpl_name,
|
def _test_assert_equal_for_tosca_templates(self, tosca_tpl_name,
|
||||||
hot_tpl_name,
|
hot_tpl_name,
|
||||||
input_params='',
|
input_params='',
|
||||||
files=None,
|
files=None,
|
||||||
is_monitor=True,
|
is_monitor=True):
|
||||||
is_alarm=False):
|
vnf = self._get_dummy_tosca_vnf(tosca_tpl_name, input_params)
|
||||||
vnf = self._get_dummy_tosca_vnf(tosca_tpl_name, input_params, is_alarm)
|
|
||||||
expected_result = '4a4c2d44-8a52-4895-9a75-9d1c76c3e738'
|
expected_result = '4a4c2d44-8a52-4895-9a75-9d1c76c3e738'
|
||||||
expected_fields = self._get_expected_fields_tosca(hot_tpl_name)
|
expected_fields = self._get_expected_fields_tosca(hot_tpl_name)
|
||||||
expected_vnf = self._get_expected_tosca_vnf(tosca_tpl_name,
|
expected_vnf = self._get_expected_tosca_vnf(tosca_tpl_name,
|
||||||
hot_tpl_name,
|
hot_tpl_name,
|
||||||
input_params,
|
input_params,
|
||||||
is_monitor,
|
is_monitor)
|
||||||
is_alarm)
|
|
||||||
result = self.heat_driver.create(plugin=None, context=self.context,
|
result = self.heat_driver.create(plugin=None, context=self.context,
|
||||||
vnf=vnf,
|
vnf=vnf,
|
||||||
auth_attr=utils.get_vim_auth_obj())
|
auth_attr=utils.get_vim_auth_obj())
|
||||||
@ -459,8 +452,7 @@ class TestDeviceHeat(base.TestCase):
|
|||||||
|
|
||||||
def test_create_tosca_with_alarm_monitoring(self):
|
def test_create_tosca_with_alarm_monitoring(self):
|
||||||
self._test_assert_equal_for_tosca_templates(
|
self._test_assert_equal_for_tosca_templates(
|
||||||
'tosca_alarm.yaml',
|
'tosca_alarm_respawn.yaml',
|
||||||
'hot_tosca_alarm.yaml',
|
'hot_tosca_alarm_respawn.yaml',
|
||||||
is_monitor=False,
|
is_monitor=False
|
||||||
is_alarm=True
|
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: 'sample-tosca-vnfd-scaling
|
||||||
|
|
||||||
|
'
|
||||||
|
outputs:
|
||||||
|
mgmt_ip-VDU1:
|
||||||
|
value:
|
||||||
|
get_attr: [CP1, fixed_ips, 0, ip_address]
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
CP1:
|
||||||
|
properties: {network: net_mgmt, port_security_enabled: false}
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
VDU1:
|
||||||
|
properties:
|
||||||
|
availability_zone: nova
|
||||||
|
config_drive: false
|
||||||
|
flavor: m1.tiny
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
networks:
|
||||||
|
- port: {get_resource: CP1}
|
||||||
|
user_data_format: SOFTWARE_CONFIG
|
||||||
|
type: OS::Nova::Server
|
@ -0,0 +1,41 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: 'An exception will be raised when having the mismatched metadata
|
||||||
|
(metadata is described in monitoring policy but unavailable in VDU properties).
|
||||||
|
'
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
mgmt_ip-VDU1:
|
||||||
|
value:
|
||||||
|
get_attr: [CP1, fixed_ips, 0, ip_address]
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
VDU1:
|
||||||
|
properties:
|
||||||
|
availability_zone: nova
|
||||||
|
config_drive: false
|
||||||
|
flavor: {get_resource: VDU1_flavor}
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
networks:
|
||||||
|
- port: {get_resource: CP1}
|
||||||
|
user_data_format: SOFTWARE_CONFIG
|
||||||
|
type: OS::Nova::Server
|
||||||
|
CP1:
|
||||||
|
properties: {network: net_mgmt, port_security_enabled: false}
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
VDU1_flavor:
|
||||||
|
type: OS::Nova::Flavor
|
||||||
|
properties:
|
||||||
|
disk: 1
|
||||||
|
ram: 512
|
||||||
|
vcpus: 2
|
||||||
|
vdu_hcpu_usage_respawning:
|
||||||
|
type: OS::Aodh::Alarm
|
||||||
|
properties:
|
||||||
|
description: utilization greater_than 50%
|
||||||
|
meter_name: cpu_util
|
||||||
|
threshold: 50
|
||||||
|
period: 60
|
||||||
|
statistic: average
|
||||||
|
evaluation_periods: 1
|
||||||
|
comparison_operator: gt
|
||||||
|
'matching_metadata': {'metadata.user_metadata.vnf': 'VDU1'}
|
@ -18,6 +18,7 @@ resources:
|
|||||||
networks:
|
networks:
|
||||||
- port: {get_resource: CP1}
|
- port: {get_resource: CP1}
|
||||||
user_data_format: SOFTWARE_CONFIG
|
user_data_format: SOFTWARE_CONFIG
|
||||||
|
metadata: {'metering.vnf': 'VDU1'}
|
||||||
type: OS::Nova::Server
|
type: OS::Nova::Server
|
||||||
CP1:
|
CP1:
|
||||||
properties: {network: net_mgmt, port_security_enabled: false}
|
properties: {network: net_mgmt, port_security_enabled: false}
|
||||||
@ -28,7 +29,7 @@ resources:
|
|||||||
disk: 1
|
disk: 1
|
||||||
ram: 512
|
ram: 512
|
||||||
vcpus: 2
|
vcpus: 2
|
||||||
vdu1_cpu_usage_monitoring_policy:
|
vdu_hcpu_usage_respawning:
|
||||||
type: OS::Aodh::Alarm
|
type: OS::Aodh::Alarm
|
||||||
properties:
|
properties:
|
||||||
description: utilization greater_than 50%
|
description: utilization greater_than 50%
|
||||||
@ -38,4 +39,4 @@ resources:
|
|||||||
statistic: average
|
statistic: average
|
||||||
evaluation_periods: 1
|
evaluation_periods: 1
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
|
'matching_metadata': {'metadata.user_metadata.vnf': 'VDU1'}
|
@ -0,0 +1,49 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: Tacker scaling template
|
||||||
|
parameters: {}
|
||||||
|
resources:
|
||||||
|
G1:
|
||||||
|
properties:
|
||||||
|
cooldown: 60
|
||||||
|
desired_capacity: 2
|
||||||
|
max_size: 3
|
||||||
|
min_size: 1
|
||||||
|
resource: {type: scaling.yaml}
|
||||||
|
type: OS::Heat::AutoScalingGroup
|
||||||
|
SP1_scale_in:
|
||||||
|
properties:
|
||||||
|
adjustment_type: change_in_capacity
|
||||||
|
auto_scaling_group_id: {get_resource: G1}
|
||||||
|
cooldown: 60
|
||||||
|
scaling_adjustment: '-1'
|
||||||
|
type: OS::Heat::ScalingPolicy
|
||||||
|
SP1_scale_out:
|
||||||
|
properties:
|
||||||
|
adjustment_type: change_in_capacity
|
||||||
|
auto_scaling_group_id: {get_resource: G1}
|
||||||
|
cooldown: 60
|
||||||
|
scaling_adjustment: 1
|
||||||
|
type: OS::Heat::ScalingPolicy
|
||||||
|
|
||||||
|
vdu_hcpu_usage_scaling_out:
|
||||||
|
type: OS::Aodh::Alarm
|
||||||
|
properties:
|
||||||
|
description: utilization greater_than 50%
|
||||||
|
meter_name: cpu_util
|
||||||
|
statistic: avg
|
||||||
|
period: 600
|
||||||
|
evaluation_periods: 1
|
||||||
|
threshold: 50
|
||||||
|
matching_metadata: {'metadata.user_metadata.vnf': SG1}
|
||||||
|
comparison_operator: gt
|
||||||
|
vdu_lcpu_usage_scaling_in:
|
||||||
|
type: OS::Aodh::Alarm
|
||||||
|
properties:
|
||||||
|
description: utilization less_than 10%
|
||||||
|
meter_name: cpu_util
|
||||||
|
statistic: avg
|
||||||
|
period: 600
|
||||||
|
evaluation_periods: 1
|
||||||
|
threshold: 10
|
||||||
|
matching_metadata: {'metadata.user_metadata.vnf': SG1}
|
||||||
|
comparison_operator: lt
|
@ -18,6 +18,7 @@ topology_template:
|
|||||||
image: cirros-0.3.4-x86_64-uec
|
image: cirros-0.3.4-x86_64-uec
|
||||||
mgmt_driver: noop
|
mgmt_driver: noop
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: VDU1}
|
||||||
|
|
||||||
CP1:
|
CP1:
|
||||||
type: tosca.nodes.nfv.CP.Tacker
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
@ -40,7 +41,7 @@ topology_template:
|
|||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_respawning:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: ceilometer
|
implementation: ceilometer
|
||||||
@ -52,6 +53,5 @@ topology_template:
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: VDU1
|
||||||
resize_compute:
|
actions: [respawn]
|
||||||
action_name: respawn
|
|
||||||
|
@ -18,6 +18,7 @@ topology_template:
|
|||||||
image: cirros-0.3.4-x86_64-uec
|
image: cirros-0.3.4-x86_64-uec
|
||||||
mgmt_driver: noop
|
mgmt_driver: noop
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
CP1:
|
CP1:
|
||||||
type: tosca.nodes.nfv.CP.Tacker
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
@ -50,7 +51,7 @@ topology_template:
|
|||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_scaling_out:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: ceilometer
|
implementation: ceilometer
|
||||||
@ -62,6 +63,5 @@ topology_template:
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: avg
|
method: avg
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: SG1
|
||||||
resize_compute:
|
actions: [SP1]
|
||||||
action_name: SP1
|
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
description: >
|
||||||
|
An exception will be raised when having the mismatched metadata
|
||||||
|
(metadata is described in monitoring policy but unavailable in
|
||||||
|
VDU properties).
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
template_name: sample-tosca-vnfd
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
capabilities:
|
||||||
|
nfv_compute:
|
||||||
|
properties:
|
||||||
|
disk_size: 1 GB
|
||||||
|
mem_size: 512 MB
|
||||||
|
num_cpus: 2
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU1
|
||||||
|
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VL
|
||||||
|
properties:
|
||||||
|
network_name: net_mgmt
|
||||||
|
vendor: Tacker
|
||||||
|
|
||||||
|
policies:
|
||||||
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
|
type: tosca.policies.tacker.Alarming
|
||||||
|
triggers:
|
||||||
|
vdu_hcpu_usage_respawning:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: Ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 50
|
||||||
|
constraint: utilization greater_than 50%
|
||||||
|
period: 60
|
||||||
|
evaluations: 1
|
||||||
|
method: average
|
||||||
|
comparison_operator: gt
|
||||||
|
metadata: VDU1
|
||||||
|
actions: ''
|
@ -18,6 +18,8 @@ topology_template:
|
|||||||
image: cirros-0.3.4-x86_64-uec
|
image: cirros-0.3.4-x86_64-uec
|
||||||
mgmt_driver: noop
|
mgmt_driver: noop
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
|
metadata: {metering.vnf: VDU1}
|
||||||
|
|
||||||
|
|
||||||
CP1:
|
CP1:
|
||||||
type: tosca.nodes.nfv.CP.Tacker
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
@ -40,7 +42,7 @@ topology_template:
|
|||||||
- vdu1_cpu_usage_monitoring_policy:
|
- vdu1_cpu_usage_monitoring_policy:
|
||||||
type: tosca.policies.tacker.Alarming
|
type: tosca.policies.tacker.Alarming
|
||||||
triggers:
|
triggers:
|
||||||
resize_compute:
|
vdu_hcpu_usage_respawning:
|
||||||
event_type:
|
event_type:
|
||||||
type: tosca.events.resource.utilization
|
type: tosca.events.resource.utilization
|
||||||
implementation: Ceilometer
|
implementation: Ceilometer
|
||||||
@ -52,5 +54,5 @@ topology_template:
|
|||||||
evaluations: 1
|
evaluations: 1
|
||||||
method: average
|
method: average
|
||||||
comparison_operator: gt
|
comparison_operator: gt
|
||||||
action:
|
metadata: VDU1
|
||||||
resize_compute: ''
|
actions: ''
|
@ -0,0 +1,78 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||||
|
|
||||||
|
description: sample-tosca-vnfd-scaling
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
template_name: sample-tosca-vnfd-scaling
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
node_templates:
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.VDU.Tacker
|
||||||
|
properties:
|
||||||
|
image: cirros-0.3.4-x86_64-uec
|
||||||
|
mgmt_driver: noop
|
||||||
|
availability_zone: nova
|
||||||
|
flavor: m1.tiny
|
||||||
|
metadata: {metering.vnf: SG1}
|
||||||
|
|
||||||
|
CP1:
|
||||||
|
type: tosca.nodes.nfv.CP.Tacker
|
||||||
|
properties:
|
||||||
|
management: true
|
||||||
|
anti_spoofing_protection: false
|
||||||
|
requirements:
|
||||||
|
- virtualLink:
|
||||||
|
node: VL1
|
||||||
|
- virtualBinding:
|
||||||
|
node: VDU1
|
||||||
|
|
||||||
|
VL1:
|
||||||
|
type: tosca.nodes.nfv.VL
|
||||||
|
properties:
|
||||||
|
network_name: net_mgmt
|
||||||
|
vendor: Tacker
|
||||||
|
|
||||||
|
policies:
|
||||||
|
- SP1:
|
||||||
|
type: tosca.policies.tacker.Scaling
|
||||||
|
properties:
|
||||||
|
increment: 1
|
||||||
|
cooldown: 60
|
||||||
|
min_instances: 1
|
||||||
|
max_instances: 3
|
||||||
|
default_instances: 2
|
||||||
|
targets: [VDU1]
|
||||||
|
|
||||||
|
- vdu_cpu_usage_monitoring_policy:
|
||||||
|
type: tosca.policies.tacker.Alarming
|
||||||
|
triggers:
|
||||||
|
vdu_hcpu_usage_scaling_out:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 50
|
||||||
|
constraint: utilization greater_than 50%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: gt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
||||||
|
|
||||||
|
vdu_lcpu_usage_scaling_in:
|
||||||
|
event_type:
|
||||||
|
type: tosca.events.resource.utilization
|
||||||
|
implementation: ceilometer
|
||||||
|
metrics: cpu_util
|
||||||
|
condition:
|
||||||
|
threshold: 10
|
||||||
|
constraint: utilization less_than 10%
|
||||||
|
period: 600
|
||||||
|
evaluations: 1
|
||||||
|
method: avg
|
||||||
|
comparison_operator: lt
|
||||||
|
metadata: SG1
|
||||||
|
actions: [SP1]
|
@ -457,3 +457,26 @@ class TestOpenStack(base.TestCase):
|
|||||||
'test_tosca_mac_ip.yaml',
|
'test_tosca_mac_ip.yaml',
|
||||||
'hot_tosca_mac_ip.yaml'
|
'hot_tosca_mac_ip.yaml'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_tosca_alarm_respawn(self):
|
||||||
|
self._test_assert_equal_for_tosca_templates(
|
||||||
|
'tosca_alarm_respawn.yaml',
|
||||||
|
'hot_tosca_alarm_respawn.yaml',
|
||||||
|
is_monitor=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_create_tosca_alarm_scale(self):
|
||||||
|
self._test_assert_equal_for_tosca_templates(
|
||||||
|
'tosca_alarm_scale.yaml',
|
||||||
|
'hot_tosca_alarm_scale.yaml',
|
||||||
|
files={'scaling.yaml': 'hot_alarm_scale_custom.yaml'},
|
||||||
|
is_monitor=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_create_tosca_with_alarm_monitoring_not_matched(self):
|
||||||
|
self.assertRaises(vnfm.MetadataNotMatched,
|
||||||
|
self._test_assert_equal_for_tosca_templates,
|
||||||
|
'tosca_alarm_metadata.yaml',
|
||||||
|
'hot_tosca_alarm_metadata.yaml',
|
||||||
|
is_monitor=False
|
||||||
|
)
|
||||||
|
@ -394,17 +394,17 @@ class TestVNFMPlugin(db_base.SqlTestCase):
|
|||||||
dummy_vnf['vim_id'] = '437ac8ef-a8fb-4b6e-8d8a-a5e86a376e8b'
|
dummy_vnf['vim_id'] = '437ac8ef-a8fb-4b6e-8d8a-a5e86a376e8b'
|
||||||
return dummy_vnf
|
return dummy_vnf
|
||||||
|
|
||||||
def _test_create_vnf_trigger(self, action_value):
|
def _test_create_vnf_trigger(self, policy_name, action_value):
|
||||||
vnf_id = "6261579e-d6f3-49ad-8bc3-a9cb974778fe"
|
vnf_id = "6261579e-d6f3-49ad-8bc3-a9cb974778fe"
|
||||||
trigger_request = {"trigger": {"action_name": action_value, "params": {
|
trigger_request = {"trigger": {"action_name": action_value, "params": {
|
||||||
"credential": "026kll6n", "data": {"current": "alarm",
|
"credential": "026kll6n", "data": {"current": "alarm",
|
||||||
'alarm_id':
|
'alarm_id':
|
||||||
"b7fa9ffd-0a4f-4165-954b-5a8d0672a35f"}},
|
"b7fa9ffd-0a4f-4165-954b-5a8d0672a35f"}},
|
||||||
"policy_name": "vdu1_cpu_usage_monitoring_policy"}}
|
"policy_name": policy_name}}
|
||||||
expected_result = {"action_name": action_value, "params": {
|
expected_result = {"action_name": action_value, "params": {
|
||||||
"credential": "026kll6n", "data": {"current": "alarm",
|
"credential": "026kll6n", "data": {"current": "alarm",
|
||||||
"alarm_id": "b7fa9ffd-0a4f-4165-954b-5a8d0672a35f"}},
|
"alarm_id": "b7fa9ffd-0a4f-4165-954b-5a8d0672a35f"}},
|
||||||
"policy_name": "vdu1_cpu_usage_monitoring_policy"}
|
"policy_name": policy_name}
|
||||||
self._vnf_alarm_monitor.process_alarm_for_vnf.return_value = True
|
self._vnf_alarm_monitor.process_alarm_for_vnf.return_value = True
|
||||||
trigger_result = self.vnfm_plugin.create_vnf_trigger(
|
trigger_result = self.vnfm_plugin.create_vnf_trigger(
|
||||||
self.context, vnf_id, trigger_request)
|
self.context, vnf_id, trigger_request)
|
||||||
@ -418,7 +418,8 @@ class TestVNFMPlugin(db_base.SqlTestCase):
|
|||||||
mock_get_vnf.return_value = dummy_vnf
|
mock_get_vnf.return_value = dummy_vnf
|
||||||
mock_action_class = mock.Mock()
|
mock_action_class = mock.Mock()
|
||||||
mock_get_policy.return_value = mock_action_class
|
mock_get_policy.return_value = mock_action_class
|
||||||
self._test_create_vnf_trigger(action_value="respawn")
|
self._test_create_vnf_trigger(policy_name="vdu_hcpu_usage_respawning",
|
||||||
|
action_value="respawn")
|
||||||
mock_get_policy.assert_called_once_with('respawn', 'test_vim')
|
mock_get_policy.assert_called_once_with('respawn', 'test_vim')
|
||||||
mock_action_class.execute_action.assert_called_once_with(
|
mock_action_class.execute_action.assert_called_once_with(
|
||||||
self.vnfm_plugin, dummy_vnf)
|
self.vnfm_plugin, dummy_vnf)
|
||||||
@ -432,7 +433,8 @@ class TestVNFMPlugin(db_base.SqlTestCase):
|
|||||||
mock_action_class = mock.Mock()
|
mock_action_class = mock.Mock()
|
||||||
mock_get_policy.return_value = mock_action_class
|
mock_get_policy.return_value = mock_action_class
|
||||||
scale_body = {'scale': {'policy': 'SP1', 'type': 'out'}}
|
scale_body = {'scale': {'policy': 'SP1', 'type': 'out'}}
|
||||||
self._test_create_vnf_trigger(action_value="SP1")
|
self._test_create_vnf_trigger(policy_name="vdu_hcpu_usage_scaling_out",
|
||||||
|
action_value="SP1-out")
|
||||||
mock_get_policy.assert_called_once_with('scaling', 'test_vim')
|
mock_get_policy.assert_called_once_with('scaling', 'test_vim')
|
||||||
mock_action_class.execute_action.assert_called_once_with(
|
mock_action_class.execute_action.assert_called_once_with(
|
||||||
self.vnfm_plugin, dummy_vnf, scale_body)
|
self.vnfm_plugin, dummy_vnf, scale_body)
|
||||||
|
@ -67,7 +67,7 @@ class TestSamples(testtools.TestCase):
|
|||||||
self.assertIsNotNone(
|
self.assertIsNotNone(
|
||||||
tosca,
|
tosca,
|
||||||
"Tosca parser failed to parse %s" % f)
|
"Tosca parser failed to parse %s" % f)
|
||||||
|
utils.post_process_template(tosca)
|
||||||
hot = None
|
hot = None
|
||||||
try:
|
try:
|
||||||
hot = tosca_translator.TOSCATranslator(tosca,
|
hot = tosca_translator.TOSCATranslator(tosca,
|
||||||
|
@ -84,7 +84,7 @@ class TOSCAToHOT(object):
|
|||||||
|
|
||||||
self.fields['template'] = self.heat_template_yaml
|
self.fields['template'] = self.heat_template_yaml
|
||||||
if is_tosca_format:
|
if is_tosca_format:
|
||||||
self._handle_scaling(vnfd_dict)
|
self._handle_policies(vnfd_dict)
|
||||||
if self.monitoring_dict:
|
if self.monitoring_dict:
|
||||||
self.vnf['attributes']['monitoring_policy'] = jsonutils.dumps(
|
self.vnf['attributes']['monitoring_policy'] = jsonutils.dumps(
|
||||||
self.monitoring_dict)
|
self.monitoring_dict)
|
||||||
@ -124,30 +124,23 @@ class TOSCAToHOT(object):
|
|||||||
return dev_attrs
|
return dev_attrs
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def _handle_scaling(self, vnfd_dict):
|
def _handle_policies(self, vnfd_dict):
|
||||||
|
|
||||||
vnf = self.vnf
|
vnf = self.vnf
|
||||||
(is_scaling_needed, scaling_group_names,
|
(is_scaling_needed, scaling_group_names,
|
||||||
main_dict) = self._generate_hot_scaling(
|
main_dict) = self._generate_hot_scaling(
|
||||||
vnfd_dict['topology_template'], 'scaling.yaml')
|
vnfd_dict['topology_template'], 'scaling.yaml')
|
||||||
(is_enabled_alarm, alarm_resource, sub_heat_tpl_yaml) =\
|
(is_enabled_alarm, alarm_resource, heat_tpl_yaml) =\
|
||||||
self._generate_hot_alarm_resource(vnfd_dict['topology_template'])
|
self._generate_hot_alarm_resource(vnfd_dict['topology_template'])
|
||||||
if is_enabled_alarm and not is_scaling_needed:
|
if is_enabled_alarm and not is_scaling_needed:
|
||||||
self.fields['template'] = self.heat_template_yaml
|
self.fields['template'] = heat_tpl_yaml
|
||||||
|
|
||||||
if is_scaling_needed:
|
if is_scaling_needed:
|
||||||
if is_enabled_alarm:
|
if is_enabled_alarm:
|
||||||
main_dict['resources'].update(alarm_resource)
|
main_dict['resources'].update(alarm_resource)
|
||||||
main_yaml = yaml.dump(main_dict)
|
main_yaml = yaml.dump(main_dict)
|
||||||
self.fields['template'] = main_yaml
|
self.fields['template'] = main_yaml
|
||||||
if is_enabled_alarm:
|
self.fields['files'] = {'scaling.yaml': self.heat_template_yaml}
|
||||||
self.fields['files'] = {
|
|
||||||
'scaling.yaml': sub_heat_tpl_yaml
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
self.fields['files'] = {
|
|
||||||
'scaling.yaml': self.heat_template_yaml
|
|
||||||
}
|
|
||||||
vnf['attributes']['heat_template'] = main_yaml
|
vnf['attributes']['heat_template'] = main_yaml
|
||||||
# TODO(kanagaraj-manickam) when multiple groups are
|
# TODO(kanagaraj-manickam) when multiple groups are
|
||||||
# supported, make this scaling atribute as
|
# supported, make this scaling atribute as
|
||||||
@ -309,6 +302,7 @@ class TOSCAToHOT(object):
|
|||||||
LOG.debug("tosca-parser error: %s", str(e))
|
LOG.debug("tosca-parser error: %s", str(e))
|
||||||
raise vnfm.ToscaParserFailed(error_msg_details=str(e))
|
raise vnfm.ToscaParserFailed(error_msg_details=str(e))
|
||||||
|
|
||||||
|
metadata = toscautils.get_vdu_metadata(tosca)
|
||||||
monitoring_dict = toscautils.get_vdu_monitoring(tosca)
|
monitoring_dict = toscautils.get_vdu_monitoring(tosca)
|
||||||
mgmt_ports = toscautils.get_mgmt_ports(tosca)
|
mgmt_ports = toscautils.get_mgmt_ports(tosca)
|
||||||
res_tpl = toscautils.get_resources_dict(tosca,
|
res_tpl = toscautils.get_resources_dict(tosca,
|
||||||
@ -322,10 +316,12 @@ class TOSCAToHOT(object):
|
|||||||
LOG.debug("heat-translator error: %s", str(e))
|
LOG.debug("heat-translator error: %s", str(e))
|
||||||
raise vnfm.HeatTranslatorFailed(error_msg_details=str(e))
|
raise vnfm.HeatTranslatorFailed(error_msg_details=str(e))
|
||||||
heat_template_yaml = toscautils.post_process_heat_template(
|
heat_template_yaml = toscautils.post_process_heat_template(
|
||||||
heat_template_yaml, mgmt_ports, res_tpl, self.unsupported_props)
|
heat_template_yaml, mgmt_ports, metadata,
|
||||||
|
res_tpl, self.unsupported_props)
|
||||||
|
|
||||||
self.heat_template_yaml = heat_template_yaml
|
self.heat_template_yaml = heat_template_yaml
|
||||||
self.monitoring_dict = monitoring_dict
|
self.monitoring_dict = monitoring_dict
|
||||||
|
self.metadata = metadata
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def _generate_hot_from_legacy(self, vnfd_dict, dev_attrs):
|
def _generate_hot_from_legacy(self, vnfd_dict, dev_attrs):
|
||||||
@ -514,57 +510,55 @@ class TOSCAToHOT(object):
|
|||||||
alarm_resource = dict()
|
alarm_resource = dict()
|
||||||
heat_tpl = self.heat_template_yaml
|
heat_tpl = self.heat_template_yaml
|
||||||
heat_dict = yamlparser.simple_ordered_parse(heat_tpl)
|
heat_dict = yamlparser.simple_ordered_parse(heat_tpl)
|
||||||
sub_heat_dict = copy.deepcopy(heat_dict)
|
|
||||||
is_enabled_alarm = False
|
is_enabled_alarm = False
|
||||||
|
|
||||||
if 'policies' in topology_tpl_dict:
|
if 'policies' in topology_tpl_dict:
|
||||||
for policy_dict in topology_tpl_dict['policies']:
|
for policy_dict in topology_tpl_dict['policies']:
|
||||||
name, policy_tpl_dict = list(policy_dict.items())[0]
|
name, policy_tpl_dict = list(policy_dict.items())[0]
|
||||||
if policy_tpl_dict['type'] == ALARMING_POLICY:
|
# need to parse triggers here: scaling in/out, respawn,...
|
||||||
|
if policy_tpl_dict['type'] == \
|
||||||
|
'tosca.policies.tacker.Alarming':
|
||||||
is_enabled_alarm = True
|
is_enabled_alarm = True
|
||||||
alarm_resource[name], sub_heat_dict =\
|
triggers = policy_tpl_dict['triggers']
|
||||||
self._convert_to_heat_monitoring_resource(policy_dict,
|
for trigger_name, trigger_dict in triggers.items():
|
||||||
self.vnf, sub_heat_dict, topology_tpl_dict)
|
alarm_resource[trigger_name] =\
|
||||||
|
self._convert_to_heat_monitoring_resource({
|
||||||
|
trigger_name: trigger_dict}, self.vnf)
|
||||||
heat_dict['resources'].update(alarm_resource)
|
heat_dict['resources'].update(alarm_resource)
|
||||||
break
|
|
||||||
|
|
||||||
self.heat_template_yaml = yaml.dump(heat_dict)
|
heat_tpl_yaml = yaml.dump(heat_dict)
|
||||||
sub_heat_tpl_yaml = yaml.dump(sub_heat_dict)
|
return (is_enabled_alarm,
|
||||||
return (is_enabled_alarm, alarm_resource, sub_heat_tpl_yaml)
|
alarm_resource,
|
||||||
|
heat_tpl_yaml
|
||||||
|
)
|
||||||
|
|
||||||
@log.log
|
def _convert_to_heat_monitoring_resource(self, mon_policy, vnf):
|
||||||
def _convert_to_heat_monitoring_resource(self, mon_policy, vnf,
|
|
||||||
sub_heat_dict, topology_tpl_dict):
|
|
||||||
mon_policy_hot = {'type': 'OS::Aodh::Alarm'}
|
mon_policy_hot = {'type': 'OS::Aodh::Alarm'}
|
||||||
mon_policy_hot['properties'] = self._convert_to_heat_monitoring_prop(
|
mon_policy_hot['properties'] = \
|
||||||
mon_policy, vnf)
|
self._convert_to_heat_monitoring_prop(mon_policy, vnf)
|
||||||
|
return mon_policy_hot
|
||||||
|
|
||||||
if 'policies' in topology_tpl_dict:
|
|
||||||
for policies in topology_tpl_dict['policies']:
|
|
||||||
policy_name, policy_dt = list(policies.items())[0]
|
|
||||||
if policy_dt['type'] == SCALING_POLICY:
|
|
||||||
# Fixed metadata. it will be fixed
|
|
||||||
# once targets are supported
|
|
||||||
metadata_dict = dict()
|
|
||||||
metadata_dict['metering.vnf_id'] = vnf['id']
|
|
||||||
sub_heat_dict['resources']['VDU1']['properties']['metadata'] =\
|
|
||||||
metadata_dict
|
|
||||||
matching_metadata_dict = dict()
|
|
||||||
matching_metadata_dict['metadata.user_metadata.vnf_id'] =\
|
|
||||||
vnf['id']
|
|
||||||
mon_policy_hot['properties']['matching_metadata'] =\
|
|
||||||
matching_metadata_dict
|
|
||||||
break
|
|
||||||
return mon_policy_hot, sub_heat_dict
|
|
||||||
|
|
||||||
@log.log
|
|
||||||
def _convert_to_heat_monitoring_prop(self, mon_policy, vnf):
|
def _convert_to_heat_monitoring_prop(self, mon_policy, vnf):
|
||||||
name, mon_policy_dict = list(mon_policy.items())[0]
|
metadata = self.metadata
|
||||||
tpl_trigger_name = mon_policy_dict['triggers']['resize_compute']
|
trigger_name, trigger_dict = list(mon_policy.items())[0]
|
||||||
tpl_condition = tpl_trigger_name['condition']
|
tpl_condition = trigger_dict['condition']
|
||||||
properties = {}
|
properties = dict()
|
||||||
properties['meter_name'] = tpl_trigger_name['metrics']
|
if not (trigger_dict.get('metadata') and metadata):
|
||||||
properties['comparison_operator'] =\
|
raise vnfm.MetadataNotMatched()
|
||||||
|
matching_metadata_dict = dict()
|
||||||
|
properties['meter_name'] = trigger_dict['metrics']
|
||||||
|
is_matched = False
|
||||||
|
for vdu_name, metadata_dict in metadata['vdus'].items():
|
||||||
|
if trigger_dict['metadata'] ==\
|
||||||
|
metadata_dict['metering.vnf']:
|
||||||
|
is_matched = True
|
||||||
|
if not is_matched:
|
||||||
|
raise vnfm.MetadataNotMatched()
|
||||||
|
matching_metadata_dict['metadata.user_metadata.vnf'] =\
|
||||||
|
trigger_dict['metadata']
|
||||||
|
properties['matching_metadata'] = \
|
||||||
|
matching_metadata_dict
|
||||||
|
properties['comparison_operator'] = \
|
||||||
tpl_condition['comparison_operator']
|
tpl_condition['comparison_operator']
|
||||||
properties['period'] = tpl_condition['period']
|
properties['period'] = tpl_condition['period']
|
||||||
properties['evaluation_periods'] = tpl_condition['evaluations']
|
properties['evaluation_periods'] = tpl_condition['evaluations']
|
||||||
@ -572,8 +566,9 @@ class TOSCAToHOT(object):
|
|||||||
properties['description'] = tpl_condition['constraint']
|
properties['description'] = tpl_condition['constraint']
|
||||||
properties['threshold'] = tpl_condition['threshold']
|
properties['threshold'] = tpl_condition['threshold']
|
||||||
# alarm url process here
|
# alarm url process here
|
||||||
alarm_url = str(vnf['attributes'].get('alarm_url'))
|
alarm_url = vnf['attributes'].get(trigger_name)
|
||||||
if alarm_url:
|
if alarm_url:
|
||||||
|
alarm_url = str(alarm_url)
|
||||||
LOG.debug('Alarm url in heat %s', alarm_url)
|
LOG.debug('Alarm url in heat %s', alarm_url)
|
||||||
properties['alarm_actions'] = [alarm_url]
|
properties['alarm_actions'] = [alarm_url]
|
||||||
return properties
|
return properties
|
||||||
|
@ -215,43 +215,59 @@ class VNFAlarmMonitor(object):
|
|||||||
'tacker.tacker.alarm_monitor.drivers',
|
'tacker.tacker.alarm_monitor.drivers',
|
||||||
cfg.CONF.tacker.alarm_monitor_driver)
|
cfg.CONF.tacker.alarm_monitor_driver)
|
||||||
|
|
||||||
def update_vnf_with_alarm(self, vnf, policy_name, policy_dict):
|
def update_vnf_with_alarm(self, plugin, context, vnf, policy_dict):
|
||||||
|
triggers = policy_dict['triggers']
|
||||||
|
alarm_url = dict()
|
||||||
|
for trigger_name, trigger_dict in triggers.items():
|
||||||
params = dict()
|
params = dict()
|
||||||
params['vnf_id'] = vnf['id']
|
params['vnf_id'] = vnf['id']
|
||||||
params['mon_policy_name'] = policy_name
|
params['mon_policy_name'] = trigger_name
|
||||||
driver = policy_dict['triggers']['resize_compute'][
|
driver = trigger_dict['event_type']['implementation']
|
||||||
'event_type']['implementation']
|
policy_action_list = trigger_dict.get('actions')
|
||||||
policy_action = policy_dict['triggers']['resize_compute'].get('action')
|
if len(policy_action_list) == 0:
|
||||||
if not policy_action:
|
|
||||||
_log_monitor_events(t_context.get_admin_context(),
|
_log_monitor_events(t_context.get_admin_context(),
|
||||||
vnf,
|
vnf,
|
||||||
"Alarm not set: policy action missing")
|
"Alarm not set: policy action missing")
|
||||||
return
|
return
|
||||||
alarm_action_name = policy_action['resize_compute'].get('action_name')
|
# Other backend policies with the construct (policy, action)
|
||||||
if not alarm_action_name:
|
# ex: (SP1, in), (SP1, out)
|
||||||
_log_monitor_events(t_context.get_admin_context(),
|
|
||||||
vnf,
|
def _refactor_backend_policy(bk_policy_name, bk_action_name):
|
||||||
"Alarm not set: alarm action name missing")
|
policy = '%(policy_name)s-%(action_name)s' % {
|
||||||
return
|
'policy_name': bk_policy_name,
|
||||||
params['mon_policy_action'] = alarm_action_name
|
'action_name': bk_action_name}
|
||||||
alarm_url = self.call_alarm_url(driver, vnf, params)
|
return policy
|
||||||
|
for policy_action in policy_action_list:
|
||||||
|
filters = {'name': policy_action}
|
||||||
|
bkend_policies =\
|
||||||
|
plugin.get_vnf_policies(context, vnf['id'], filters)
|
||||||
|
if bkend_policies:
|
||||||
|
bkend_policy = bkend_policies[0]
|
||||||
|
if bkend_policy['type'] == constants.POLICY_SCALING:
|
||||||
|
cp = trigger_dict['condition'].\
|
||||||
|
get('comparison_operator')
|
||||||
|
scaling_type = 'out' if cp == 'gt' else 'in'
|
||||||
|
policy_action = _refactor_backend_policy(policy_action,
|
||||||
|
scaling_type)
|
||||||
|
|
||||||
|
params['mon_policy_action'] = policy_action
|
||||||
|
alarm_url[trigger_name] =\
|
||||||
|
self.call_alarm_url(driver, vnf, params)
|
||||||
details = "Alarm URL set successfully: %s" % alarm_url
|
details = "Alarm URL set successfully: %s" % alarm_url
|
||||||
_log_monitor_events(t_context.get_admin_context(),
|
_log_monitor_events(t_context.get_admin_context(),
|
||||||
vnf,
|
vnf,
|
||||||
details)
|
details)
|
||||||
return alarm_url
|
return alarm_url
|
||||||
# vnf['attribute']['alarm_url'] = alarm_url ---> create
|
|
||||||
# by plugin or vm_db
|
|
||||||
|
|
||||||
def process_alarm_for_vnf(self, policy):
|
def process_alarm_for_vnf(self, vnf, trigger):
|
||||||
'''call in plugin'''
|
'''call in plugin'''
|
||||||
vnf = policy['vnf']
|
params = trigger['params']
|
||||||
params = policy['params']
|
mon_prop = trigger['trigger']
|
||||||
mon_prop = policy['properties']
|
|
||||||
alarm_dict = dict()
|
alarm_dict = dict()
|
||||||
alarm_dict['alarm_id'] = params['data'].get('alarm_id')
|
alarm_dict['alarm_id'] = params['data'].get('alarm_id')
|
||||||
alarm_dict['status'] = params['data'].get('current')
|
alarm_dict['status'] = params['data'].get('current')
|
||||||
driver = mon_prop['resize_compute']['event_type']['implementation']
|
trigger_name, trigger_dict = list(mon_prop.items())[0]
|
||||||
|
driver = trigger_dict['event_type']['implementation']
|
||||||
return self.process_alarm(driver, vnf, alarm_dict)
|
return self.process_alarm(driver, vnf, alarm_dict)
|
||||||
|
|
||||||
def _invoke(self, driver, **kwargs):
|
def _invoke(self, driver, **kwargs):
|
||||||
@ -382,9 +398,9 @@ class ActionRespawnHeat(ActionPolicy):
|
|||||||
plugin.add_vnf_to_monitor(updated_vnf, vim_res['vim_type'])
|
plugin.add_vnf_to_monitor(updated_vnf, vim_res['vim_type'])
|
||||||
LOG.debug(_("VNF %s added to monitor thread"), updated_vnf[
|
LOG.debug(_("VNF %s added to monitor thread"), updated_vnf[
|
||||||
'id'])
|
'id'])
|
||||||
if vnf_dict['attributes'].get('alarm_url'):
|
if vnf_dict['attributes'].get('alarming_policy'):
|
||||||
_delete_heat_stack(vim_res['vim_auth'])
|
_delete_heat_stack(vim_res['vim_auth'])
|
||||||
vnf_dict['attributes'].pop('alarm_url')
|
vnf_dict['attributes'].pop('alarming_policy')
|
||||||
_respin_vnf()
|
_respin_vnf()
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,17 +249,19 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
LOG.debug('hosting_vnf: %s', hosting_vnf)
|
LOG.debug('hosting_vnf: %s', hosting_vnf)
|
||||||
self._vnf_monitor.add_hosting_vnf(hosting_vnf)
|
self._vnf_monitor.add_hosting_vnf(hosting_vnf)
|
||||||
|
|
||||||
def add_alarm_url_to_vnf(self, vnf_dict):
|
def add_alarm_url_to_vnf(self, context, vnf_dict):
|
||||||
vnfd_yaml = vnf_dict['vnfd']['attributes'].get('vnfd', '')
|
vnfd_yaml = vnf_dict['vnfd']['attributes'].get('vnfd', '')
|
||||||
vnfd_dict = yaml.load(vnfd_yaml)
|
vnfd_dict = yaml.load(vnfd_yaml)
|
||||||
if vnfd_dict and vnfd_dict.get('tosca_definitions_version'):
|
if vnfd_dict and vnfd_dict.get('tosca_definitions_version'):
|
||||||
polices = vnfd_dict['topology_template'].get('policies', [])
|
polices = vnfd_dict['topology_template'].get('policies', [])
|
||||||
for policy_dict in polices:
|
for policy_dict in polices:
|
||||||
name, policy = policy_dict.items()[0]
|
name, policy = list(policy_dict.items())[0]
|
||||||
if policy['type'] in constants.POLICY_ALARMING:
|
if policy['type'] in constants.POLICY_ALARMING:
|
||||||
alarm_url = self._vnf_alarm_monitor.update_vnf_with_alarm(
|
alarm_url =\
|
||||||
vnf_dict, name, policy)
|
self._vnf_alarm_monitor.update_vnf_with_alarm(
|
||||||
vnf_dict['attributes']['alarm_url'] = alarm_url
|
self, context, vnf_dict, policy)
|
||||||
|
vnf_dict['attributes']['alarming_policy'] = vnf_dict['id']
|
||||||
|
vnf_dict['attributes'].update(alarm_url)
|
||||||
break
|
break
|
||||||
|
|
||||||
def config_vnf(self, context, vnf_dict):
|
def config_vnf(self, context, vnf_dict):
|
||||||
@ -343,7 +345,7 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
vnf_id = vnf_dict['id']
|
vnf_id = vnf_dict['id']
|
||||||
LOG.debug(_('vnf_dict %s'), vnf_dict)
|
LOG.debug(_('vnf_dict %s'), vnf_dict)
|
||||||
self.mgmt_create_pre(context, vnf_dict)
|
self.mgmt_create_pre(context, vnf_dict)
|
||||||
self.add_alarm_url_to_vnf(vnf_dict)
|
self.add_alarm_url_to_vnf(context, vnf_dict)
|
||||||
try:
|
try:
|
||||||
instance_id = self._vnf_manager.invoke(
|
instance_id = self._vnf_manager.invoke(
|
||||||
driver_name, 'create', plugin=self,
|
driver_name, 'create', plugin=self,
|
||||||
@ -683,9 +685,11 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
policy_list.append(p)
|
policy_list.append(p)
|
||||||
|
|
||||||
# Check for filters
|
# Check for filters
|
||||||
if filters.get('name'):
|
if filters.get('name') or filters.get('type'):
|
||||||
if name == filters.get('name'):
|
if name == filters.get('name'):
|
||||||
_add(policy)
|
_add(policy)
|
||||||
|
if policy['type'] == filters.get('type'):
|
||||||
|
_add(policy)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
@ -714,38 +718,70 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
|
|
||||||
return scale['scale']
|
return scale['scale']
|
||||||
|
|
||||||
def _validate_alarming_policy(self, context, policy):
|
def get_vnf_policy_by_type(self, context, vnf_id, policy_type=None, fields=None): # noqa
|
||||||
vnf_id = policy['vnf']['id']
|
policies = self.get_vnf_policies(context,
|
||||||
# validate policy type
|
vnf_id,
|
||||||
type = policy['type']
|
filters={'type': policy_type})
|
||||||
if type not in constants.POLICY_ALARMING:
|
if policies:
|
||||||
raise exceptions.VnfPolicyTypeInvalid(
|
return policies[0]
|
||||||
type=type,
|
|
||||||
valid_types=constants.POLICY_ALARMING,
|
raise exceptions.VnfPolicyTypeInvalid(type=constants.POLICY_ALARMING,
|
||||||
policy=policy['id']
|
vnf_id=vnf_id)
|
||||||
)
|
|
||||||
|
def _validate_alarming_policy(self, context, vnf_id, trigger):
|
||||||
# validate alarm status
|
# validate alarm status
|
||||||
if not self._vnf_alarm_monitor.process_alarm_for_vnf(policy):
|
if not self._vnf_alarm_monitor.process_alarm_for_vnf(vnf_id, trigger):
|
||||||
raise exceptions.AlarmUrlInvalid(vnf_id=vnf_id)
|
raise exceptions.AlarmUrlInvalid(vnf_id=vnf_id)
|
||||||
|
|
||||||
# validate policy action
|
|
||||||
action = policy['action_name']
|
|
||||||
policy_ = None
|
policy_ = None
|
||||||
|
action_ = None
|
||||||
|
# validate policy action. if action is composite, split it.
|
||||||
|
# ex: SP1-in, SP1-out
|
||||||
|
action = trigger['action_name']
|
||||||
|
sp_action = action.split('-')
|
||||||
|
if len(sp_action) == 2:
|
||||||
|
bk_policy_name = sp_action[0]
|
||||||
|
bk_policy_action = sp_action[1]
|
||||||
|
policies_ = self.get_vnf_policies(context, vnf_id,
|
||||||
|
filters={'name': bk_policy_name})
|
||||||
|
if policies_:
|
||||||
|
policy_ = policies_[0]
|
||||||
|
action_ = bk_policy_action
|
||||||
|
|
||||||
|
if not policy_:
|
||||||
if action not in constants.DEFAULT_ALARM_ACTIONS:
|
if action not in constants.DEFAULT_ALARM_ACTIONS:
|
||||||
policy_ = self.get_vnf_policy(context, action, vnf_id)
|
policy_ = self.get_vnf_policy(context, action, vnf_id)
|
||||||
if not policy_:
|
LOG.debug(_("Trigger %s is validated successfully") % trigger)
|
||||||
raise exceptions.VnfPolicyNotFound(
|
return policy_, action_
|
||||||
vnf_id=action,
|
|
||||||
policy=policy['id']
|
|
||||||
)
|
|
||||||
LOG.debug(_("Policy %s is validated successfully") % policy)
|
|
||||||
return policy_
|
|
||||||
# validate url
|
# validate url
|
||||||
|
|
||||||
def _handle_vnf_monitoring(self, context, policy):
|
def _get_vnf_triggers(self, context, vnf_id, filters=None, fields=None):
|
||||||
vnf_dict = policy['vnf']
|
policy = self.get_vnf_policy_by_type(
|
||||||
if policy['action_name'] in constants.DEFAULT_ALARM_ACTIONS:
|
context, vnf_id, policy_type=constants.POLICY_ALARMING)
|
||||||
action = policy['action_name']
|
triggers = policy['properties']
|
||||||
|
vnf_trigger = dict()
|
||||||
|
for trigger_name, trigger_dict in triggers.items():
|
||||||
|
if trigger_name == filters.get('name'):
|
||||||
|
vnf_trigger['trigger'] = {trigger_name: trigger_dict}
|
||||||
|
vnf_trigger['vnf'] = policy['vnf']
|
||||||
|
break
|
||||||
|
|
||||||
|
return vnf_trigger
|
||||||
|
|
||||||
|
def get_vnf_trigger(self, context, vnf_id, trigger_name):
|
||||||
|
trigger = self._get_vnf_triggers(
|
||||||
|
context, vnf_id, filters={'name': trigger_name})
|
||||||
|
if not trigger:
|
||||||
|
raise exceptions.TriggerNotFound(
|
||||||
|
trigger_name=trigger_name,
|
||||||
|
vnf_id=vnf_id
|
||||||
|
)
|
||||||
|
return trigger
|
||||||
|
|
||||||
|
def _handle_vnf_monitoring(self, context, trigger):
|
||||||
|
vnf_dict = trigger['vnf']
|
||||||
|
if trigger['action_name'] in constants.DEFAULT_ALARM_ACTIONS:
|
||||||
|
action = trigger['action_name']
|
||||||
LOG.debug(_('vnf for monitoring: %s'), vnf_dict)
|
LOG.debug(_('vnf for monitoring: %s'), vnf_dict)
|
||||||
infra_driver, vim_auth = self._get_infra_driver(context, vnf_dict)
|
infra_driver, vim_auth = self._get_infra_driver(context, vnf_dict)
|
||||||
action_cls = monitor.ActionPolicy.get_policy(action,
|
action_cls = monitor.ActionPolicy.get_policy(action,
|
||||||
@ -753,11 +789,9 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
if action_cls:
|
if action_cls:
|
||||||
action_cls.execute_action(self, vnf_dict)
|
action_cls.execute_action(self, vnf_dict)
|
||||||
|
|
||||||
if policy.get('bckend_policy'):
|
if trigger.get('bckend_policy'):
|
||||||
bckend_policy = policy['bckend_policy']
|
bckend_policy = trigger['bckend_policy']
|
||||||
bckend_policy_type = bckend_policy['type']
|
bckend_policy_type = bckend_policy['type']
|
||||||
cp = policy['properties']['resize_compute']['condition'].\
|
|
||||||
get('comparison_operator')
|
|
||||||
if bckend_policy_type == constants.POLICY_SCALING:
|
if bckend_policy_type == constants.POLICY_SCALING:
|
||||||
if vnf_dict['status'] != constants.ACTIVE:
|
if vnf_dict['status'] != constants.ACTIVE:
|
||||||
LOG.info(context, vnf_dict,
|
LOG.info(context, vnf_dict,
|
||||||
@ -766,7 +800,7 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
action = 'scaling'
|
action = 'scaling'
|
||||||
scale = {}
|
scale = {}
|
||||||
scale.setdefault('scale', {})
|
scale.setdefault('scale', {})
|
||||||
scale['scale']['type'] = 'out' if cp == 'gt' else 'in'
|
scale['scale']['type'] = trigger['bckend_action']
|
||||||
scale['scale']['policy'] = bckend_policy['name']
|
scale['scale']['policy'] = bckend_policy['name']
|
||||||
infra_driver, vim_auth = self._get_infra_driver(context,
|
infra_driver, vim_auth = self._get_infra_driver(context,
|
||||||
vnf_dict)
|
vnf_dict)
|
||||||
@ -777,22 +811,16 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
|
|
||||||
def create_vnf_trigger(
|
def create_vnf_trigger(
|
||||||
self, context, vnf_id, trigger):
|
self, context, vnf_id, trigger):
|
||||||
# Verified API: pending
|
trigger_ = self.get_vnf_trigger(
|
||||||
# Need to use: _make_policy_dict, get_vnf_policies, get_vnf_policy
|
context, vnf_id, trigger['trigger']['policy_name'])
|
||||||
# action: scaling, refer to template to find specific scaling policy
|
trigger_.update({'action_name': trigger['trigger']['action_name']})
|
||||||
# we can extend in future to support other policies
|
trigger_.update({'params': trigger['trigger']['params']})
|
||||||
# Monitoring policy should be describe in heat_template_yaml.
|
bk_policy, bk_action = self._validate_alarming_policy(
|
||||||
# Create first
|
context, vnf_id, trigger_)
|
||||||
policy_ = self.get_vnf_policy(context,
|
|
||||||
trigger['trigger']['policy_name'],
|
|
||||||
vnf_id)
|
|
||||||
policy_.update({'action_name': trigger['trigger']['action_name']})
|
|
||||||
policy_.update({'params': trigger['trigger']['params']})
|
|
||||||
bk_policy = self._validate_alarming_policy(context, policy_)
|
|
||||||
if bk_policy:
|
if bk_policy:
|
||||||
policy_.update({'bckend_policy': bk_policy})
|
trigger_.update({'bckend_policy': bk_policy,
|
||||||
self._handle_vnf_monitoring(context, policy_)
|
'bckend_action': bk_action})
|
||||||
|
self._handle_vnf_monitoring(context, trigger_)
|
||||||
return trigger['trigger']
|
return trigger['trigger']
|
||||||
|
|
||||||
def get_vnf_resources(self, context, vnf_id, fields=None, filters=None):
|
def get_vnf_resources(self, context, vnf_id, fields=None, filters=None):
|
||||||
|
@ -62,7 +62,7 @@ FLAVOR_EXTRA_SPECS_LIST = ('cpu_allocation',
|
|||||||
|
|
||||||
delpropmap = {TACKERVDU: ('mgmt_driver', 'config', 'service_type',
|
delpropmap = {TACKERVDU: ('mgmt_driver', 'config', 'service_type',
|
||||||
'placement_policy', 'monitoring_policy',
|
'placement_policy', 'monitoring_policy',
|
||||||
'failure_policy'),
|
'metadata', 'failure_policy'),
|
||||||
TACKERCP: ('management',)}
|
TACKERCP: ('management',)}
|
||||||
|
|
||||||
convert_prop = {TACKERCP: {'anti_spoofing_protection':
|
convert_prop = {TACKERCP: {'anti_spoofing_protection':
|
||||||
@ -117,6 +117,19 @@ def get_vdu_monitoring(template):
|
|||||||
return monitoring_dict
|
return monitoring_dict
|
||||||
|
|
||||||
|
|
||||||
|
@log.log
|
||||||
|
def get_vdu_metadata(template):
|
||||||
|
metadata = dict()
|
||||||
|
metadata.setdefault('vdus', {})
|
||||||
|
for nt in template.nodetemplates:
|
||||||
|
if nt.type_definition.is_derived_from(TACKERVDU):
|
||||||
|
metadata_dict = nt.get_property_value('metadata') or None
|
||||||
|
if metadata_dict:
|
||||||
|
metadata['vdus'][nt.name] = {}
|
||||||
|
metadata['vdus'][nt.name].update(metadata_dict)
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def get_mgmt_ports(tosca):
|
def get_mgmt_ports(tosca):
|
||||||
mgmt_ports = {}
|
mgmt_ports = {}
|
||||||
@ -177,8 +190,8 @@ def convert_unsupported_res_prop(heat_dict, unsupported_res_prop):
|
|||||||
|
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl,
|
def post_process_heat_template(heat_tpl, mgmt_ports, metadata,
|
||||||
unsupported_res_prop=None):
|
res_tpl, unsupported_res_prop=None):
|
||||||
#
|
#
|
||||||
# TODO(bobh) - remove when heat-translator can support literal strings.
|
# TODO(bobh) - remove when heat-translator can support literal strings.
|
||||||
#
|
#
|
||||||
@ -200,6 +213,11 @@ def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl,
|
|||||||
else:
|
else:
|
||||||
heat_dict['outputs'] = output
|
heat_dict['outputs'] = output
|
||||||
LOG.debug(_('Added output for %s'), outputname)
|
LOG.debug(_('Added output for %s'), outputname)
|
||||||
|
if metadata:
|
||||||
|
for vdu_name, metadata_dict in metadata['vdus'].items():
|
||||||
|
heat_dict['resources'][vdu_name]['properties']['metadata'] =\
|
||||||
|
metadata_dict
|
||||||
|
|
||||||
add_resources_tpl(heat_dict, res_tpl)
|
add_resources_tpl(heat_dict, res_tpl)
|
||||||
if unsupported_res_prop:
|
if unsupported_res_prop:
|
||||||
convert_unsupported_res_prop(heat_dict, unsupported_res_prop)
|
convert_unsupported_res_prop(heat_dict, unsupported_res_prop)
|
||||||
|
Loading…
Reference in New Issue
Block a user