From c374c03e9a94fcb0880f9087364757c7266d4c2d Mon Sep 17 00:00:00 2001 From: Benjamin Diaz Date: Wed, 9 Oct 2019 14:29:59 -0300 Subject: [PATCH] Adds arch docs to POL Change-Id: If8ad88148e50b76c7df29d7a16ddaa58fce9f84b Signed-off-by: Benjamin Diaz --- docs/architecture.md | 60 +++++++++++++++++++++++++++ docs/assets/POL_Overview_Diagram.jpg | Bin 0 -> 11894 bytes 2 files changed, 60 insertions(+) create mode 100644 docs/architecture.md create mode 100644 docs/assets/POL_Overview_Diagram.jpg diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..49cf6be --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,60 @@ + +# Policy Management module (POL) + +## Summary + +POL accomplishes the following tasks: + +* Configure auto scaling groups for VNFs. +* Configure VNF alarms for VNFs. +* Listen for MON alarms status and evaluating corresponding policies (scaling and vnf alarms). +* Sending scaling messages to LCM when scaling policy conditions are met. +* Calling webhooks when VNF alarm policies are met. + +## Overview + +![](assets/POL_Overview_Diagram.jpg) + +POL has the following components: + +* POL Agent: + * Listens to message bus for NS LCM actions (instantiation, scaling, deletion) and configures resources accordingly. + * Listens to message bus for alarm notifications, evaluates policies and executes corresponding actions. + +## POL Agent + +POL subscribes to the message bus and waits for the following messages: + +* topic: ns - key: instantiated +* topic: ns - key: scaled +* topic: ns - key: terminated +* topic: alarm_response - key: notify_alarm + +When a NS is created, it checks the corresponding VNFDs for scaling group descriptors or vnf alarms. It creates the corresponding +resources in MON. +When a NS is scaled, it does the same as above for new VDUs if scaled out. It removes orphaned resources if scaled in. +When a NS is terminated, it deletes associated resources. + +When an alarm is raised, if it corresponds to a scaling policy, it stores its last status and then validates the policy, +as policies can have N alarms related to them and can specify a boolean operator (AND/OR) to evaluate the conditions. +If it corresponds to a VNF alarm, the associated webhook is called. + +Data is stored in POL database in the OSM MySQL engine. diff --git a/docs/assets/POL_Overview_Diagram.jpg b/docs/assets/POL_Overview_Diagram.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5dd43c45427ed28e38522c2a4094bb3f49298fb GIT binary patch literal 11894 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 literal 0 HcmV?d00001 -- 2.25.1