Пример #1
0
    def test_create_service(self):
        db = DatabaseManager()
        if len(db.get_all(Service)) > 0:
            self.fail('The Database must be empty: ' + str())

        connection = httplib.HTTPConnection('%s:8090' % HOST)
        headers = {'Content-type': 'application/json'}

        sent_service = {"service_type": "controller", 'image': "nubomedia-broker", 'flavor': "m1.medium",
                        'size': {'def': 1, 'max': 1, 'min': 1}, 'config': {'hostname': 'ControlServer'}}

        sent_service_json = json.dumps(sent_service)

        connection.request('POST', '/services', sent_service_json, headers)
        resp = connection.getresponse()

        self.assertEqual(resp.status, 200)

        service = db.get_by_service_type(Service, sent_service["service_type"])[0]

        self.assertIsNotNone(service)

        self.assertEqual(service.service_type, sent_service["service_type"])
        self.assertEqual(service.image, sent_service["image"])
        self.assertEqual(service.flavor, sent_service["flavor"])
        self.assertEqual(service.size, sent_service['size'])
        self.assertEqual(service.config, sent_service['config'])

        sent_service['flavor'] = "m1.small"

        sent_service_json = json.dumps(sent_service)

        connection.request('PUT', '/services/' + str(service.id), sent_service_json, headers)
        resp = connection.getresponse()

        self.assertEqual(resp.status, 200)

        service = db.get_by_service_type(Service, sent_service["service_type"])[0]
        self.assertIsNotNone(service)
        self.assertEqual(service.service_type, sent_service["service_type"])
        self.assertEqual(service.image, sent_service["image"])
        self.assertEqual(service.flavor, sent_service["flavor"])
        self.assertEqual(service.size, sent_service['size'])
        self.assertEqual(service.config, sent_service['config'])

        connection.request('DELETE', '/services/' + str(service.id), sent_service_json, headers)

        time.sleep(2)

        self.assertEqual(len(db.get_by_service_type(Service, sent_service["service_type"])), 0)
Пример #2
0
class TopologyManager(ABCTopologyManager):
    def __init__(self):
        self.db = DatabaseManager()

    def create(self, config):
        ###Topology arguments
        top_name = config.get('name')
        top_state = 'DEFINED'
        top_service_instances = []
        LOG.debug("Parse Topology \"%s\"" % top_name)
        ###Parse all service instances described in config file
        sis_config = config.get('service_instances')
        for si_config in sis_config:
            si_args = {}
            si_args['state'] = 'DEFINED'
            service = None
            if si_config.get('service_type'):
                service_type = si_config.get('service_type')
                LOG.debug('Fetching service of service_type \"%s\"' %
                          service_type)
                service_list = self.db.get_by_service_type(
                    Service, service_type)
                if len(service_list) == 1:
                    service = service_list[0]
                    LOG.debug('Service \"%s\" is available.' % service)
                    si_args['service_type'] = service.service_type
                    si_args['image'] = service.image
                    si_args['flavor'] = service.flavor
                    si_args['configuration'] = service.configuration
                    si_args['key'] = service.key
                    si_args['size'] = service.size
                    si_args['adapter'] = service.adapter
                    si_args['requirements'] = []
                    for requirement in service.requirements:
                        func = Requirement.__init__
                        needed_parameters = func.func_code.co_varnames[
                            1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = requirement.__dict__.get(param)
                        new_requirement = Requirement(**args)
                        si_args['requirements'].append(new_requirement)
                    si_args['networks'] = []
                    for network in service.networks:
                        func = Network_Instance.__init__
                        needed_parameters = func.func_code.co_varnames[
                            1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = network.__dict__.get(param)
                        new_network = Network_Instance(**args)
                        si_args['networks'].append(new_network)
                    si_args['user_data'] = []
                    for command in service.user_data:
                        func = Command.__init__
                        needed_parameters = func.func_code.co_varnames[
                            1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = command.__dict__.get(param)
                        new_command = Command(**args)
                        si_args['user_data'].append(new_command)
                else:
                    raise NotFoundException(
                        'service_type:\"%s\" is not available.' % service_type)
            else:
                raise NotDefinedException("service_type is not defined.")
            for si_item in si_config:
                if si_item == "name":
                    si_args['name'] = si_config.get(si_item)
                    LOG.debug("Parsing service instance \"%s\"" %
                              si_args['name'])
                elif si_item == "service_type":
                    si_args['service_type'] = si_config.get(si_item)
                elif si_item == "adapter":
                    si_args['adapter'] = si_config.get(si_item)
                elif si_item == "image":
                    image_name = si_config.get(si_item)
                    image_list = self.db.get_by_name(Image, image_name)
                    if len(image_list) == 1:
                        image = image_list[0]
                        si_args['image'] = image
                    else:
                        raise NotFoundException(
                            'image:\"%s\" is not available.' % image_name)
                elif si_item == "flavor":
                    flavor_name = si_config.get(si_item)
                    flavor_list = self.db.get_by_name(Flavor, flavor_name)
                    if len(flavor_list) == 1:
                        flavor = flavor_list[0]
                        si_args['flavor'] = flavor
                    else:
                        raise NotFoundException(
                            'flavor:\"%s\" is not available.' % flavor_name)
                elif si_item == "key":
                    key_name = si_config.get(si_item)
                    key_list = self.db.get_by_name(Key, key_name)
                    if len(key_list) == 1:
                        key = key_list[0]
                        si_args['key'] = key
                    else:
                        raise NotFoundException(
                            'key:\"%s\" is not available.' % key_name)
                elif si_item == "size":
                    si_args['size'].update(si_config.get(si_item))
                elif si_item == "networks":
                    networks = []
                    _networks = si_config.get(si_item)
                    LOG.debug("Fetch SecurityGroups for networks %s." %
                              _networks)
                    for _net_inst in _networks:
                        secgroups = []
                        for _secgroup_name in _net_inst.get('security_groups'):
                            lst = self.db.get_by_name(SecurityGroup,
                                                      _secgroup_name)
                            if len(lst) > 0:
                                _secgroup = lst[0]
                            else:
                                raise NotFoundException(
                                    'SecurityGroup:\"%s\" is not available.' %
                                    _secgroup_name)
                            secgroups.append(_secgroup)
                        _net_inst['security_groups'] = secgroups
                        networks.append(Network_Instance(**_net_inst))
                    si_args['networks'] = networks
                elif si_item == "configuration":
                    for key in si_config.get(si_item).keys():
                        if key in service.configuration.keys():
                            si_args['configuration'][key] = si_config.get(
                                si_item).get(key)
                elif si_item == "policies":
                    policies = []
                    _policies = si_config.get(si_item)
                    for _policy in _policies:
                        _new_policy_args = {}
                        for _po_item in _policy:
                            if _po_item == "name":
                                _new_policy_args.update(
                                    {'name': _policy.get(_po_item)})
                            elif _po_item == "period":
                                _new_policy_args.update(
                                    {'period': _policy.get(_po_item)})
                            elif _po_item == "alarm":
                                _new_alarm_args = _policy.get(_po_item)
                                _new_alarm = Alarm(**_new_alarm_args)
                                _new_policy_args.update({'alarm': _new_alarm})
                            elif _po_item == "action":
                                _new_action_args = _policy.get(_po_item)
                                _new_action = Action(**_new_action_args)
                                _new_policy_args.update(
                                    {'action': _new_action})
                        try:
                            _new_policy = Policy(**_new_policy_args)
                        except TypeError:
                            raise InvalidInputException()
                        policies.append(_new_policy)
                    si_args['policies'] = policies
                elif si_item == "requirements":
                    requirements = []
                    for _req in si_config.get(si_item):
                        _req_args = _req
                        requirement = Requirement(**_req_args)
                        requirements.append(requirement)
                    si_args['requirements'] = requirements
                elif si_item == "user_data":
                    user_data = []
                    for _user_data_item in si_config.get(si_item):
                        command = Command(_user_data_item)
                        user_data.append(command)
                    si_args['user_data'] = user_data
                elif si_item == "location":
                    location = []
                    for _loc in si_config.get(si_item):
                        LOG.debug("found item location %s" % _loc)
                        loc = Location(_loc)
                        location.append(loc)
                    si_args['location'] = location
                elif si_item == "relation":
                    relation = []
                    for _rel in si_config.get(si_item):
                        LOG.debug("found item relation %s" % _rel)
                        rel = Relation(_rel)
                        relation.append(rel)
                    si_args['relation'] = relation
                else:
                    raise InvalidInputException(
                        "parameter \"%s\" is not provided by Services." %
                        si_config.get(si_item))

            ###Initialise Units
            units = []
            unit_number = si_args.get('size').get('def') or 1
            for i in range(1, unit_number + 1):
                if i == 1:
                    _hostname = '%s' % si_args.get('name')
                else:
                    _hostname = '%s-%s' % (si_args.get('name'), i)
                _new_unit = Unit(hostname=_hostname, state='DEFINED')
                units.append(_new_unit)
            si_args['units'] = units
            ###Initialise Service Instance
            new_service_instance = ServiceInstance(**si_args)
            ###Add the new service instance to the topology
            top_service_instances.append(new_service_instance)

        ###Initialise Topology
        ext_name = '' + top_name + '_' + str(random.randint(1000, 9999))
        topology = Topology(name=top_name,
                            state=top_state,
                            service_instances=top_service_instances,
                            ext_name=ext_name)
        LOG.debug(topology)
        return topology

    def update(self, new_topology, old_topology):
        conf = sys_util().get_sys_conf()
        db = FactoryAgent().get_agent(conf['database_manager'])
        updated_topology = old_topology
        updated_topology.name = new_topology.name
        #check for additional service instances and add them to the list of new instances
        appended_service_instances = []
        for new_service_instance in new_topology.service_instances:
            is_found = False
            for updated_service_instance in updated_topology.service_instances:
                if new_service_instance.name == updated_service_instance.name:
                    is_found = True
                    break
            if not is_found:
                appended_service_instances.append(new_service_instance)
        #check for removed service instances and add it to the list of removed instances
        removed_service_instances = []
        for updated_service_instance in updated_topology.service_instances:
            is_found = False
            for new_service_instance in new_topology.service_instances:
                if new_service_instance.name == updated_service_instance.name:
                    is_found = True
                    break
            if not is_found:
                removed_service_instances.append(updated_service_instance)
        #remove removed service instances
        for removed_service_instance in removed_service_instances:
            updated_topology.service_instances.remove(removed_service_instance)
            LOG.debug('Removed ServiceInstance \"%s\" from Topology \"%s\".' %
                      (removed_service_instance.name, updated_topology.name))
        #append additional service instances
        for appended_service_instance in appended_service_instances:
            appended_service_instance.topology_id = updated_topology.id
            updated_topology.service_instances.append(
                appended_service_instance)
            if appended_service_instance.policies is not None:
                for policy in appended_service_instance.policies:
                    db.persist(policy)
            db.persist(appended_service_instance)
            LOG.debug('Appended ServiceInstance \"%s\" to Topology \"%s\".' %
                      (appended_service_instance.name, updated_topology.name))
        #Update all values for each service instance
        for updated_service_instance in updated_topology.service_instances:
            for new_service_instance in new_topology.service_instances:
                if updated_service_instance.name == new_service_instance.name:
                    updated_service_instance.size = new_service_instance.size
                    updated_service_instance.configuration = new_service_instance.configuration
                    updated_service_instance.policies = new_service_instance.policies
                    #updated_service_instance.service_type = new_service_instance.service_type
                    if new_service_instance.service_type and updated_service_instance.service_type != new_service_instance.service_type:
                        LOG.warning(
                            "Cannot update service_type for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    if new_service_instance.adapter and updated_service_instance.adapter != new_service_instance.adapter:
                        LOG.warning(
                            "Cannot update adapter for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    #updated_service_instance.flavor = new_service_instance.flavor
                    if new_service_instance.flavor and updated_service_instance.flavor.name != new_service_instance.flavor.name:
                        LOG.warning(
                            "Cannot update flavor for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    #updated_service_instance.image = new_service_instance.image
                    if new_service_instance.image and updated_service_instance.image.name != new_service_instance.image.name:
                        LOG.warning(
                            "Cannot update image for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    #updated_service_instance.networks = new_service_instance.networks
                    if new_service_instance.networks is not None:
                        LOG.warning(
                            "Cannot update networks for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    #updated_service_instance.requirements = new_service_instance.requirements
                    if new_service_instance.requirements is not None:
                        LOG.warning(
                            "Cannot update networks for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    #updated_service_instance.user_data = new_service_instance.user_data
                    if new_service_instance.user_data is not None:
                        LOG.warning(
                            "Cannot update user_data for %s->%s. Not Implemented."
                            % (updated_topology.name,
                               updated_service_instance.name))
                    if new_service_instance.key and updated_service_instance.key.name != new_service_instance.key.name:
                        LOG.warning(
                            "Cannot update key for %s->%s without replacement."
                            % (updated_topology.name,
                               updated_service_instance.name))
        #Add or remove units according to minimal or maximal size
        for updated_service_instance in updated_topology.service_instances:
            if updated_service_instance not in appended_service_instances:
                if len(updated_service_instance.units
                       ) < updated_service_instance.size.get('min'):
                    for i in range(
                            updated_service_instance.size.get('min') -
                            len(updated_service_instance.units)):
                        _hostname = '%s-%s' % (
                            updated_service_instance.name,
                            str(len(updated_service_instance.units) + 1))
                        _state = 'DEFINED'
                        new_unit = Unit(hostname=_hostname, state=_state)
                        new_unit.service_instance_id = updated_service_instance.id
                        updated_service_instance.units.append(new_unit)
                        db.persist(new_unit)
                if len(updated_service_instance.units
                       ) > updated_service_instance.size.get('max'):
                    for i in range(
                            len(updated_service_instance.units) -
                            updated_service_instance.size.get('max')):
                        removed_unit = updated_service_instance.units.pop(
                            len(updated_service_instance.units) - 1)
                        db.remove(removed_unit)
        return updated_topology

    def dynamic_create(self, dict):
        LOG.debug(dict)
        t = Topology(**dict)
        LOG.debug(t.__dict__)
        return t

    def get_attrs(self, _class):
        return [k for k in dir(_class) if not k.startswith('__')]
class TopologyManager(ABCTopologyManager):

    def __init__(self):
        self.db = DatabaseManager()

    def create(self, config):
        ###Topology arguments
        top_name = config.get('name')
        top_state = 'DEFINED'
        top_service_instances = []
        logger.debug("Parse Topology \"%s\"" % top_name)
        ###Parse all service instances described in config file
        sis_config = config.get('service_instances')
        for si_config in sis_config:
            si_args = {}
            si_args['state'] = 'DEFINED'
            service = None
            if si_config.get('service_type'):
                service_type = si_config.get('service_type')
                logger.debug('Fetching service of service_type \"%s\"' % service_type)
                service_list = self.db.get_by_service_type(Service, service_type)
                if len(service_list) == 1:
                    service = service_list[0]
                    logger.debug('Service \"%s\" is available.' % service)
                    si_args['service_type'] = service.service_type
                    si_args['image'] = service.image
                    si_args['flavor'] = service.flavor
                    si_args['configuration'] = service.configuration
                    si_args['key'] = service.key
                    si_args['size'] = service.size
                    si_args['adapter'] = service.adapter
                    si_args['requirements'] = []
                    for requirement in service.requirements:
                        func = Requirement.__init__
                        needed_parameters = func.func_code.co_varnames[1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = requirement.__dict__.get(param)
                        new_requirement = Requirement(**args)
                        si_args['requirements'].append(new_requirement)
                    si_args['networks'] = []
                    for network in service.networks:
                        func = Network_Instance.__init__
                        needed_parameters = func.func_code.co_varnames[1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = network.__dict__.get(param)
                        new_network = Network_Instance(**args)
                        si_args['networks'].append(new_network)
                    si_args['user_data'] = []
                    for command in service.user_data:
                        func = Command.__init__
                        needed_parameters = func.func_code.co_varnames[1:func.func_code.co_argcount]
                        args = {}
                        for param in needed_parameters:
                            args[param] = command.__dict__.get(param)
                        new_command = Command(**args)
                        si_args['user_data'].append(new_command)
                else:
                    raise NotFoundException('service_type:\"%s\" is not available.' % service_type)
            else:
                raise NotDefinedException("service_type is not defined.")
            for si_item in si_config:
                if si_item == "name":
                    si_args['name'] = si_config.get(si_item)
                    logger.debug("Parsing service instance \"%s\"" % si_args['name'])
                elif si_item == "service_type":
                    si_args['service_type'] = si_config.get(si_item)
                elif si_item == "adapter":
                    si_args['adapter'] = si_config.get(si_item)
                elif si_item == "image":
                    image_name = si_config.get(si_item)
                    image_list = self.db.get_by_name(Image, image_name)
                    if len(image_list) == 1:
                        image = image_list[0]
                        si_args['image'] = image
                    else:
                        raise NotFoundException('image:\"%s\" is not available.' % image_name)
                elif si_item == "flavor":
                    flavor_name = si_config.get(si_item)
                    flavor_list = self.db.get_by_name(Flavor, flavor_name)
                    if len(flavor_list) == 1:
                        flavor = flavor_list[0]
                        si_args['flavor'] = flavor
                    else:
                        raise NotFoundException('flavor:\"%s\" is not available.' % flavor_name)
                elif si_item == "key":
                    key_name = si_config.get(si_item)
                    key_list = self.db.get_by_name(Key, key_name)
                    if len(key_list) == 1:
                        key = key_list[0]
                        si_args['key'] = key
                    else:
                        raise NotFoundException('key:\"%s\" is not available.' % key_name)
                elif si_item == "size":
                    si_args['size'].update(si_config.get(si_item))
                elif si_item == "networks":
                    networks = []
                    _networks = si_config.get(si_item)
                    logger.debug("Fetch SecurityGroups for networks %s." % _networks)
                    for _net_inst in _networks:
                        secgroups = []
                        for _secgroup_name in _net_inst.get('security_groups'):
                            lst = self.db.get_by_name(SecurityGroup, _secgroup_name)
                            if len(lst) > 0:
                                _secgroup = lst[0]
                            else:
                                raise NotFoundException('SecurityGroup:\"%s\" is not available.'  % _secgroup_name)
                            secgroups.append(_secgroup)
                        _net_inst['security_groups'] = secgroups
                        networks.append(Network_Instance(**_net_inst))
                    si_args['networks'] = networks
                elif si_item == "configuration":
                    for key in si_config.get(si_item).keys():
                        if key in service.configuration.keys():
                            si_args['configuration'][key] = si_config.get(si_item).get(key)
                elif si_item == "policies":
                    policies = []
                    _policies = si_config.get(si_item)
                    for _policy in _policies:
                        _new_policy_args = {}
                        for _po_item in _policy:
                            if _po_item == "name":
                                _new_policy_args.update({'name':_policy.get(_po_item)})
                            elif _po_item == "period":
                                _new_policy_args.update({'period':_policy.get(_po_item)})
                            elif _po_item == "alarm":
                                _new_alarm_args = _policy.get(_po_item)
                                _new_alarm = Alarm(**_new_alarm_args)
                                _new_policy_args.update({'alarm':_new_alarm})
                            elif _po_item == "action":
                                _new_action_args = _policy.get(_po_item)
                                _new_action = Action(**_new_action_args)
                                _new_policy_args.update({'action':_new_action})
                        try:
                            _new_policy = Policy(**_new_policy_args)
                        except TypeError:
                            raise InvalidInputException()
                        policies.append(_new_policy)
                    si_args['policies'] = policies
                elif si_item == "requirements":
                   requirements = []
                   for _req in si_config.get(si_item):
                       _req_args = _req
                       requirement = Requirement(**_req_args)
                       requirements.append(requirement)
                   si_args['requirements'] = requirements
                elif si_item == "user_data":
                    user_data = []
                    for _user_data_item in  si_config.get(si_item):
                        command = Command(_user_data_item)
                        user_data.append(command)
                    si_args['user_data'] = user_data
                elif si_item == "location":
                    location = []
                    for _loc in si_config.get(si_item):
                        logger.debug("found item location %s"%_loc)
                        loc = Location(_loc)
                        location.append(loc)
                    si_args['location'] = location
                elif si_item == "relation":
                    relation = []
                    for _rel in si_config.get(si_item):
                        logger.debug("found item relation %s"%_rel)
                        rel = Relation(_rel)
                        relation.append(rel)
                    si_args['relation'] = relation
                else:
                    raise InvalidInputException("parameter \"%s\" is not provided by Services." % si_config.get(si_item))

            ###Initialise Units
            units = []
            unit_number = si_args.get('size').get('def') or 1
            for i in range(1,unit_number+1):
                _hostname = '%s-%s' % (si_args.get('name'),i)
                _new_unit = Unit(hostname=_hostname, state='DEFINED')
                units.append(_new_unit)
            si_args['units'] = units
            ###Initialise Service Instance
            new_service_instance = ServiceInstance(**si_args)
            ###Add the new service instance to the topology
            top_service_instances.append(new_service_instance)

        ###Initialise Topology
        ext_name = '' + top_name + '_' +str(random.randint(1000,9999))
        topology = Topology(name=top_name, state=top_state, service_instances=top_service_instances, ext_name=ext_name)
        logger.debug(topology)
        return topology

    def update(self, new_topology, old_topology):
        conf = sys_util().get_sys_conf()
        db = FactoryAgent().get_agent(conf['database_manager'])
        updated_topology = old_topology
        updated_topology.name = new_topology.name
        #check for additional service instances and add them to the list of new instances
        appended_service_instances = []
        for new_service_instance in new_topology.service_instances:
            is_found = False
            for updated_service_instance in updated_topology.service_instances:
                if new_service_instance.name == updated_service_instance.name:
                    is_found = True
                    break
            if not is_found:
                appended_service_instances.append(new_service_instance)
        #check for removed service instances and add it to the list of removed instances
        removed_service_instances = []
        for updated_service_instance in updated_topology.service_instances:
            is_found = False
            for new_service_instance in new_topology.service_instances:
                if new_service_instance.name == updated_service_instance.name:
                    is_found = True
                    break
            if not is_found:
                removed_service_instances.append(updated_service_instance)
        #remove removed service instances
        for removed_service_instance in removed_service_instances:
            updated_topology.service_instances.remove(removed_service_instance)
            logger.debug('Removed ServiceInstance \"%s\" from Topology \"%s\".' % (removed_service_instance.name, updated_topology.name))
        #append additional service instances
        for appended_service_instance in appended_service_instances:
            appended_service_instance.topology_id = updated_topology.id
            updated_topology.service_instances.append(appended_service_instance)
            if appended_service_instance.policies is not None:
                for policy in appended_service_instance.policies:
                    db.persist(policy)
            db.persist(appended_service_instance)
            logger.debug('Appended ServiceInstance \"%s\" to Topology \"%s\".' % (appended_service_instance.name, updated_topology.name))
        #Update all values for each service instance
        for updated_service_instance in updated_topology.service_instances:
            for new_service_instance in new_topology.service_instances:
                if updated_service_instance.name == new_service_instance.name:
                    updated_service_instance.size = new_service_instance.size
                    updated_service_instance.configuration = new_service_instance.configuration
                    updated_service_instance.policies = new_service_instance.policies
                    #updated_service_instance.service_type = new_service_instance.service_type
                    if new_service_instance.service_type and updated_service_instance.service_type != new_service_instance.service_type:
                        logger.warning("Cannot update service_type for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    if new_service_instance.adapter and updated_service_instance.adapter != new_service_instance.adapter:
                        logger.warning("Cannot update adapter for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    #updated_service_instance.flavor = new_service_instance.flavor
                    if new_service_instance.flavor and updated_service_instance.flavor.name != new_service_instance.flavor.name:
                        logger.warning("Cannot update flavor for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    #updated_service_instance.image = new_service_instance.image
                    if new_service_instance.image and updated_service_instance.image.name != new_service_instance.image.name:
                        logger.warning("Cannot update image for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    #updated_service_instance.networks = new_service_instance.networks
                    if new_service_instance.networks is not None:
                        logger.warning("Cannot update networks for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    #updated_service_instance.requirements = new_service_instance.requirements
                    if new_service_instance.requirements is not None:
                        logger.warning("Cannot update networks for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    #updated_service_instance.user_data = new_service_instance.user_data
                    if new_service_instance.user_data is not None:
                        logger.warning("Cannot update user_data for %s->%s. Not Implemented." % (updated_topology.name, updated_service_instance.name))
                    if new_service_instance.key and updated_service_instance.key.name != new_service_instance.key.name:
                        logger.warning("Cannot update key for %s->%s without replacement." % (updated_topology.name, updated_service_instance.name))
        #Add or remove units according to minimal or maximal size
        for updated_service_instance in updated_topology.service_instances:
            if updated_service_instance not in appended_service_instances:
                if len(updated_service_instance.units) < updated_service_instance.size.get('min'):
                    for i in range(updated_service_instance.size.get('min') - len(updated_service_instance.units)):
                        _hostname = '%s-%s' % (
                            updated_service_instance.name, str(len(updated_service_instance.units) + 1))
                        _state = 'DEFINED'
                        new_unit = Unit(hostname=_hostname, state=_state)
                        new_unit.service_instance_id = updated_service_instance.id
                        updated_service_instance.units.append(new_unit)
                        db.persist(new_unit)
                if len(updated_service_instance.units) > updated_service_instance.size.get('max'):
                    for i in range(len(updated_service_instance.units) - updated_service_instance.size.get('max')):
                        removed_unit = updated_service_instance.units.pop(len(updated_service_instance.units) - 1)
                        db.remove(removed_unit)
        return updated_topology

    def dynamic_create(self, dict):
        logger.debug(dict)
        t = Topology(**dict)
        logger.debug(t.__dict__)
        return t

    def get_attrs(self,_class):
        return [k for k in dir(_class) if not k.startswith('__') ]