[CORD-2641] Adding/removing IMSI from Progran

Change-Id: If32b45b4abb5b1e42e1e044b806f021dc3cd8137
diff --git a/samples/cem-profile.json b/samples/cem-profile.json
deleted file mode 100644
index 2a76901..0000000
--- a/samples/cem-profile.json
+++ /dev/null
@@ -1,19 +0,0 @@
-
-{
-  "name":"testcem",
-  "DlSchedType":"RR",
-  "UlSchedType":"RR",
-  "DlAllocRBRate":16,
-  "UlAllocRBRate":15,
-  "start":0,
-  "end":0,
-  "AdmControl":1,
-  "CellIndividualOffset":1,
-  "mmeip":"192.168.28.35",
-  "mmeport":"123",
-  "SubsProfile":"",
-  "DlWifiRate":13,
-  "DlUeAllocRbRate":12,
-  "enodeb_id": 1,
-  "handover_id": 1
-}
\ No newline at end of file
diff --git a/samples/profile.json b/samples/profile.json
index 0d97598..d51a386 100644
--- a/samples/profile.json
+++ b/samples/profile.json
@@ -1,17 +1,16 @@
+
 {
-  "AdmControl":"0",
+  "name":"testcem",
   "DlSchedType":"RR",
-  "start": 1516780800,
   "UlSchedType":"RR",
-  "end": 1517385600,
+  "DlAllocRBRate":16,
+  "UlAllocRBRate":15,
+  "AdmControl":1,
   "CellIndividualOffset":1,
-  "DlAllocRBRate":1,
-  "name":"test-profile",
-  "UlAllocRBRate":12,
-  "mmeip": "10.20.30.40",
-  "mmeport": "8080",
-  "DlWifiRate": "80",
-  "DlUeAllocRbRate": "70",
-  "enodeb_id":5,
-  "handover_id":1
+  "mmeip":"192.168.28.35",
+  "mmeport":"123",
+  "SubsProfile":"",
+  "DlWifiRate":13,
+  "DlUeAllocRbRate":12,
+  "handover_id": 1
 }
\ No newline at end of file
diff --git a/xos/models/models.py b/xos/models/models.py
index 4493452..295c172 100644
--- a/xos/models/models.py
+++ b/xos/models/models.py
@@ -1,4 +1,3 @@
-from core.models import Service
 from xos.exceptions import XOSValidationError
 
 from models_decl import ProgranService_decl
diff --git a/xos/models/progran.xproto b/xos/models/progran.xproto
index 8591291..ad0a378 100644
--- a/xos/models/progran.xproto
+++ b/xos/models/progran.xproto
@@ -41,14 +41,14 @@
     required int32 UlAllocRBRate = 4 [db_index = False, null = False, blank = False];
     required string start = 5 [content_type = "date", null = True, blank = True];
     required string end = 6 [content_type = "date", null = True, blank = True];
-    required int32 AdmControl = 7 [default = "0", choices = "(('0', 'ALL'), ('1', 'Voice Only'), ('2', 'Data Only'))", max_length = 1, blank = False, null = False, db_index = False];
+    required int32 AdmControl = 7 [default = "0", choices = "(('0', 'ALL'), ('1', 'Voice Only'), ('2', 'Data Only'))", blank = False, null = False, db_index = False];
     required int32 CellIndividualOffset = 8 [db_index = False, null = False, blank = False];
     required string mmeip = 9 [db_index = False, max_length = 256, null = False, blank = False];
     required string mmeport = 10 [db_index = False, max_length = 256, null = False, blank = False];
     required int32 DlWifiRate = 11 [default = 100, db_index = False, null = False, blank = False];
     required int32 DlUeAllocRbRate = 12 [default = 100, db_index = False, null = False, blank = False];
     required string SubsProfile = 13 [ db_index = False, null = True, blank = True];
-    required manytoone enodeb->ENodeB:profiles = 14 [null = True, blank = True];
+    optional manytoone enodeb->ENodeB:profiles = 14 [null = True, blank = True];
     required manytoone handover->Handover:profiles = 15 [null = False, blank = False];
 }
 
diff --git a/xos/synchronizer/steps/progran_curl.yaml b/xos/synchronizer/steps/progran_curl.yaml
index f567a3b..cf76f6f 100644
--- a/xos/synchronizer/steps/progran_curl.yaml
+++ b/xos/synchronizer/steps/progran_curl.yaml
@@ -16,12 +16,12 @@
 - hosts: 127.0.0.1
   connection: local
   vars:
-    - profile: '{{ profile }}'
+    - body: '{{ body }}'
     - endpoint: '{{ endpoint }}'
 
   tasks:
     - debug:
-        msg: "{{ '{{' }} profile {{ '}}' }}"
+        msg: "{{ '{{' }} body {{ '}}' }}"
     # NOTE that the task has a generic name as it's planned to be used for all the requests
     - name: Call onos Progran
       uri:
@@ -32,6 +32,6 @@
         force_basic_auth: yes
         status_code: 200
         {% if method == "POST" or method == "PUT" -%}
-        body: "{{ '{{' }} profile {{ '}}' }}"
+        body: "{{ '{{' }} body {{ '}}' }}"
         body_format: json
         {%- endif -%}
diff --git a/xos/synchronizer/steps/sync_enodeb.py b/xos/synchronizer/steps/sync_enodeb.py
index 8d65974..db5bca9 100644
--- a/xos/synchronizer/steps/sync_enodeb.py
+++ b/xos/synchronizer/steps/sync_enodeb.py
@@ -24,12 +24,15 @@
 from multistructlog import create_logger
 import json
 
-from helpers import ProgranHelpers
 
 log = create_logger(Config().get('logging'))
 
 parentdir = os.path.join(os.path.dirname(__file__), "..")
+
 sys.path.insert(0, parentdir)
+sys.path.insert(0, os.path.dirname(__file__))
+
+from helpers import ProgranHelpers
 
 class SyncProgranEnodeB(SyncInstanceUsingAnsible):
     provides = [ENodeB]
@@ -59,7 +62,7 @@
             'onos_password': onos['password'],
             'onos_port': onos['port'],
             'endpoint': 'enodeb',
-            'profile': self.get_progran_enodeb_field(o),
+            'body': self.get_progran_enodeb_field(o),
             'method': 'POST'
         }
 
diff --git a/xos/synchronizer/steps/sync_imsi.py b/xos/synchronizer/steps/sync_imsi.py
new file mode 100644
index 0000000..e4db047
--- /dev/null
+++ b/xos/synchronizer/steps/sync_imsi.py
@@ -0,0 +1,83 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# 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 os
+import sys
+from synchronizers.new_base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from synchronizers.new_base.ansible_helper import run_template
+from synchronizers.new_base.modelaccessor import MCordSubscriberInstance
+
+from xosconfig import Config
+from multistructlog import create_logger
+import json
+
+
+log = create_logger(Config().get('logging'))
+
+parentdir = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, parentdir)
+sys.path.insert(0, os.path.dirname(__file__))
+from helpers import ProgranHelpers
+
+class SyncProgranIMSI(SyncInstanceUsingAnsible):
+    provides = [MCordSubscriberInstance]
+
+    observes = MCordSubscriberInstance
+
+    def skip_ansible_fields(self, o):
+        # FIXME This model does not have an instance, this is a workaroung to make it work,
+        # but it need to be cleaned up creating a general SyncUsingAnsible base class
+        return True
+
+    def get_progran_imsi_field(self, o):
+
+        imsi = {
+            "IMSI": o.imsi_number,
+        }
+        imsi = json.dumps(imsi)
+        return imsi
+
+    def get_extra_attributes(self, o):
+        onos = ProgranHelpers.get_progran_onos_info()
+        fields = {
+            'onos_url': onos['url'],
+            'onos_username': onos['username'],
+            'onos_password': onos['password'],
+            'onos_port': onos['port'],
+            'endpoint': 'imsi',
+            'body': self.get_progran_imsi_field(o),
+            'method': 'POST'
+        }
+
+        return fields
+
+    # FIXME we need to override this as the default expect to ssh into a VM
+    def run_playbook(self, o, fields):
+        run_template("progran_curl.yaml", fields, object=o)
+
+    def delete_record(self, o):
+        log.info("deleting object", object=str(o), **o.tologdict())
+        onos = ProgranHelpers.get_progran_onos_info()
+        fields = {
+            'onos_url': onos['url'],
+            'onos_username': onos['username'],
+            'onos_password': onos['password'],
+            'onos_port': onos['port'],
+            'endpoint': 'imsi/%s' % o.imsi_number,
+            'body': '',
+            'method': 'DELETE'
+        }
+        res = self.run_playbook(o, fields)
\ No newline at end of file
diff --git a/xos/synchronizer/steps/sync_imsi_link.py b/xos/synchronizer/steps/sync_imsi_link.py
new file mode 100644
index 0000000..059b789
--- /dev/null
+++ b/xos/synchronizer/steps/sync_imsi_link.py
@@ -0,0 +1,97 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# 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 os
+import sys
+from synchronizers.new_base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from synchronizers.new_base.ansible_helper import run_template
+from synchronizers.new_base.modelaccessor import MCordSubscriberInstance, ServiceInstanceLink
+
+from xosconfig import Config
+from multistructlog import create_logger
+import json
+
+
+log = create_logger(Config().get('logging'))
+
+parentdir = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, parentdir)
+sys.path.insert(0, os.path.dirname(__file__))
+from helpers import ProgranHelpers
+
+class SyncProgranIMSILink(SyncInstanceUsingAnsible):
+    provides = [ServiceInstanceLink]
+
+    observes = ServiceInstanceLink
+
+    def skip_ansible_fields(self, o):
+        # FIXME This model does not have an instance, this is a workaroung to make it work,
+        # but it need to be cleaned up creating a general SyncUsingAnsible base class
+        return True
+
+    def get_progran_imsi_field(self, o):
+
+        imsi = {
+            "IMSIRuleArray": [
+                '123' # TODO retrieve it service_instance_link.subscriber_service_instance.imsi_number
+            ]
+        }
+        imsi = json.dumps(imsi)
+        return imsi
+
+    def get_extra_attributes(self, o):
+
+
+        return fields
+
+    def sync_record(self, o):
+        log.info("sync'ing profile", object=str(o), **o.tologdict())
+        # onos = ProgranHelpers.get_progran_onos_info()
+        # profile_name = 'foo' # TODO retrieve it service_instance_link.subscriber_service_instance.imsi_number
+        #
+        # fields = {
+        #     'onos_url': onos['url'],
+        #     'onos_username': onos['username'],
+        #     'onos_password': onos['password'],
+        #     'onos_port': onos['port'],
+        #     'endpoint': 'profile/%s/imsi' % profile_name,
+        #     'body': self.get_progran_imsi_field(o),
+        #     'method': 'POST'
+        # }
+        # fields = {}
+        # self.run_playbook(o, fields)
+        # o.save()
+        print o
+
+    # FIXME we need to override this as the default expect to ssh into a VM
+    def run_playbook(self, o, fields):
+        run_template("progran_curl.yaml", fields, object=o)
+
+    def delete_record(self, o):
+        log.info("deleting object", object=str(o), **o.tologdict())
+        # onos = ProgranHelpers.get_progran_onos_info()
+        # profile_name = 'foo'
+        # imsi_number = 'bar'
+        # fields = {
+        #     'onos_url': onos['url'],
+        #     'onos_username': onos['username'],
+        #     'onos_password': onos['password'],
+        #     'onos_port': onos['port'],
+        #     'endpoint': 'profile/{profile_name}/{imsi}' % (profile_name, imsi_number),
+        #     'body': '',
+        #     'method': 'DELETE'
+        # }
+        # self.run_playbook(o, fields)
\ No newline at end of file
diff --git a/xos/synchronizer/steps/sync_progranserviceinstance.py b/xos/synchronizer/steps/sync_progranserviceinstance.py
index 3b8e0d3..4daf104 100644
--- a/xos/synchronizer/steps/sync_progranserviceinstance.py
+++ b/xos/synchronizer/steps/sync_progranserviceinstance.py
@@ -24,12 +24,13 @@
 from multistructlog import create_logger
 import json
 
-from helpers import ProgranHelpers
 
 log = create_logger(Config().get('logging'))
 
 parentdir = os.path.join(os.path.dirname(__file__), "..")
 sys.path.insert(0, parentdir)
+sys.path.insert(0, os.path.dirname(__file__))
+from helpers import ProgranHelpers
 
 class SyncProgranServiceInstance(SyncInstanceUsingAnsible):
     provides = [ProgranServiceInstance]
@@ -93,7 +94,7 @@
         # progran profile specific fields
         profile_fields = {
             'endpoint': 'profile',
-            'profile': self.get_progran_profile_field(o),
+            'body': self.get_progran_profile_field(o),
             'method': 'POST'
         }
         profile_fields["ansible_tag"] = getattr(o, "ansible_tag", o.__class__.__name__ + "_" + str(o.id))
@@ -104,7 +105,7 @@
         if o.enodeb:
             log.info("adding profile to enodeb", object=str(o), **o.tologdict())
             enodeb_fields = {
-                'profile': json.dumps({
+                'body': json.dumps({
                     "ProfileArray": [
                         o.name
                     ]
@@ -135,7 +136,7 @@
             'onos_password': onos['password'],
             'onos_port': onos['port'],
             'endpoint': 'profile/%s' % o.name,
-            'profile': '',
+            'body': '',
             'method': 'DELETE'
         }
         res = self.run_playbook(o, fields)
\ No newline at end of file