[COMAC-185] Upgrade ProgRAN base image

Change-Id: I5c48fcffafb9525436a55d01f8ad7bc7ab80b236
diff --git a/Dockerfile.synchronizer b/Dockerfile.synchronizer
index a07d3e6..f9411d2 100644
--- a/Dockerfile.synchronizer
+++ b/Dockerfile.synchronizer
@@ -16,7 +16,7 @@
 
 # xosproject/progran-synchronizer
 
-FROM xosproject/xos-synchronizer-base:2.1.38
+FROM xosproject/xos-synchronizer-base:2.2.5
 
 COPY xos/synchronizer /opt/xos/synchronizers/progran
 COPY VERSION /opt/xos/synchronizers/progran/
diff --git a/VERSION b/VERSION
index f1547e6..815e68d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.7
+2.0.8
diff --git a/xos/synchronizer/config.yaml b/xos/synchronizer/config.yaml
index a3f2048..22d5115 100644
--- a/xos/synchronizer/config.yaml
+++ b/xos/synchronizer/config.yaml
@@ -15,6 +15,7 @@
 
 
 name: progran
+core_version: ">=2.2.1"
 required_models:
   - ProgranService
   - ProgranServiceInstance
diff --git a/xos/synchronizer/models/progran.xproto b/xos/synchronizer/models/progran.xproto
index 37ab7ae..8a4025d 100644
--- a/xos/synchronizer/models/progran.xproto
+++ b/xos/synchronizer/models/progran.xproto
@@ -12,7 +12,7 @@
 
 message ENodeB (XOSBase){
     option verbose_name = "eNodeB";
-    required string description = 1 [db_index = False, max_length = 256, null = False, blank = False];
+    required string description = 1 [tosca_key = True];
     required string enbId = 2 [help_text = "ID of this enodeb", db_index = False, max_length = 256, null = False, blank = False];
     required string ipAddr = 3 [help_text = "IP address of this enodeb", db_index = False, max_length = 256, null = False, blank = False];
     optional string created_by = 4 [null = True, blank = True, gui_hidden = True];
@@ -32,6 +32,7 @@
     required int32 HysteresisA5 = 9 [default = 1, db_index = False, null = False, blank = False];
     required int32 A5TriggerQuantity = 10 [default = 0, db_index = False, null = False, blank = False];
     optional string created_by = 11 [null = True, blank = True, gui_hidden = True];
+    optional string name = 12 [tosca_key = True];
 }
 
 message ProgranServiceInstance (ServiceInstance){
diff --git a/xos/synchronizer/steps/sync_progranserviceinstance_back.py b/xos/synchronizer/steps/sync_progranserviceinstance_back.py
deleted file mode 100644
index 25a92e9..0000000
--- a/xos/synchronizer/steps/sync_progranserviceinstance_back.py
+++ /dev/null
@@ -1,191 +0,0 @@
-
-# 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
-
-import datetime
-import time
-
-from xossynchronizer.steps.syncstep import SyncStep
-from xossynchronizer.modelaccessor import ProgranServiceInstance, ENodeB, Handover, ServiceInstanceLink, MCordSubscriberInstance
-
-from xosconfig import Config
-from multistructlog import create_logger
-import requests
-from requests.auth import HTTPBasicAuth
-
-
-
-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 SyncProgranServiceInstanceBack(SyncStep):
-    provides = [ProgranServiceInstance]
-
-    observes = ProgranServiceInstance
-
-
-    def call(self, failed=[], deletion=False):
-        """
-        Read profile from progran and save them in xos
-        """
-
-        if deletion == False:
-            # NOTE we won't it to run only after the delete has completed
-            return
-
-        log.debug("Reading profiles from progran")
-        onos = ProgranHelpers.get_progran_onos_info(self.model_accessor)
-        profile_url = "http://%s:%s/onos/progran/profile/" % (onos['url'], onos['port'])
-        r = requests.get(profile_url, auth=HTTPBasicAuth(onos['username'], onos['password']))
-        res = r.json()['ProfileArray']
-
-
-        # remove default profiles
-        res = [p for p in res if "Default" not in p['Name']]
-        pnames = [p['Name'] for p in res]
-        log.debug("Received Profiles: ", profiles=pnames)
-
-        field_mapping = {
-            'Name': 'name',
-            'Start': 'start',
-            'End': 'end',
-        }
-
-        field_transformations = {
-            'Start': ProgranHelpers.date_to_time,
-            'End': ProgranHelpers.date_to_time
-        }
-
-        handover_mapping = {
-            'A5Hysteresis': 'HysteresisA5',
-            'A3Hysteresis': 'HysteresisA3'
-        }
-
-        updated_profiles = []
-
-        for p in res:
-
-
-            # checking for profiles
-            try:
-                si = ProgranServiceInstance.objects.get(name=p['Name'])
-                log.debug("Profile %s already exists, updating it" % p['Name'])
-
-            except IndexError:
-                si = ProgranServiceInstance()
-
-                si.created_by = "Progran"
-
-                log.debug("Profile %s is new, creating it" % p['Name'])
-
-            if not si.is_new:
-                # update IMSI association
-                xos_imsis_for_profile = [i.subscriber_service_instance.leaf_model for i in si.provided_links.all()]
-                progran_imsis_for_profile = p['IMSIRuleArray']
-
-                log.debug("List of imsis for profile %s in XOS" % p["Name"], imsis=xos_imsis_for_profile)
-                log.debug("List of imsis for profile %s in ONOS" % p["Name"], imsis=progran_imsis_for_profile)
-
-                for i in xos_imsis_for_profile:
-                    if not i.imsi_number in progran_imsis_for_profile:
-                        log.debug("Removing Imsi %s from profile %s" % (i.imsi_number, p['Name']))
-
-                        imsi_link = ServiceInstanceLink.objects.get(subscriber_service_instance_id=i.id)
-
-                        # NOTE: this model has already been removed from the backend, no need to synchronize
-                        imsi_link.backend_need_delete = False
-                        imsi_link.no_sync = True
-                        imsi_link.save() # we need to save it to avoid a synchronization loop
-
-                        imsi_link.delete()
-                    else:
-                        # remove from imsi list coming from progran everything we already know about
-                        progran_imsis_for_profile.remove(i.imsi_number)
-
-                for i in progran_imsis_for_profile:
-                    log.debug("Adding Imsi %s to profile %s" % (i, p['Name']))
-                    imsi = MCordSubscriberInstance.objects.get(imsi_number=i)
-                    imsi_to_profile = ServiceInstanceLink(provider_service_instance=si,
-                                                          subscriber_service_instance=imsi)
-                    imsi_to_profile.save()
-
-            # if the model has not been synchronized yet, skip it
-            if not si.is_new and si.no_sync is False:
-                log.debug("Skipping profile %s as not synchronized" % p['Name'])
-                # NOTE add it to the removed profiles to avoid deletion (this is ugly, I know)
-                updated_profiles.append(si.name)
-                continue
-
-            # ugly fix
-            if p['AdmControl']:
-                p['AdmControl'] = str(p['AdmControl'])
-
-            si = ProgranHelpers.update_fields(si, p, field_mapping, field_transformations)
-
-            # checking for handovers
-            handover_dict = p['Handover']
-            handover_dict = ProgranHelpers.convert_keys(handover_dict, handover_mapping)
-            del p['Handover']
-
-            if si.handover_id:
-                handover = si.handover
-                log.debug("handover already exists, updating it", handover=handover_dict)
-            else:
-                handover = Handover()
-                handover = ProgranHelpers.update_fields(handover, handover_dict)
-                log.debug("handover is new, creating it", handover=handover_dict)
-                handover.created_by = "Progran"
-
-            handover = ProgranHelpers.update_fields(handover, handover_dict)
-            handover.save()
-
-            # Assigning handover to profile
-            si.handover = handover
-
-            # si.backend_status = "OK"
-            # si.backend_code = 1
-
-            si.no_sync = True
-            si.previously_sync = True
-
-            if p["MMECfg"]:
-                si.mmeip = str(p["MMECfg"]["IPAddr"])
-                si.mmeport = str(p["MMECfg"]["Port"])
-
-            si.enacted = time.mktime(datetime.datetime.now().timetuple())
-
-            si.save()
-
-            updated_profiles.append(si.name)
-
-        existing_profiles = [p.name for p in ProgranServiceInstance.objects.all() if not p.is_new]
-        deleted_profiles = ProgranHelpers.list_diff(existing_profiles, updated_profiles)
-
-        if len(deleted_profiles) > 0:
-            for p in deleted_profiles:
-                si = ProgranServiceInstance.objects.get(name=p)
-                if si.created_by == 'XOS' and si.previously_sync == False:
-                    # don't delete if the profile has been created by XOS and it hasn't been sync'ed yet
-                    continue
-                # TODO delete also the associated Handover
-                log.debug("Profiles %s have been removed in progran, removing it from XOS" % str(p))
-                si.delete()