Пример #1
0
    def post(self):
        """
        method to add TemplateCompose list
        """
        if not self.result.get("success"):
            return self.result

        name = self.args.get('name')
        description = self.args.get('description')
        environment = self.args.get("environment")
        if environment:
            environment = json.dumps(self.args.get("environment"))
        # check name is it exist
        exist_compose = TemplateCompose.query.filter(
            TemplateCompose.name == name).first()
        if exist_compose:
            em = "TemplateCompose is already existed. name: <{0}>".format(name)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        compose = TemplateCompose(name, description, environment=environment)
        try:
            db_session.add(compose)
            db_session.commit()
            logger.info('{0} created'.format(compose))
            compose_ret = TemplateCompose.query.filter(
                TemplateCompose.id == compose.id).first()
            return marshal(compose_ret, TEMPLATE_COMPOSE_FIELDS,
                           'templatecompose')
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {"error": [{"code": 401, "msg": "{0}".format(e)}]}
Пример #2
0
    def delete(self):
        """
        method to delete ComposeTemplate
        """
        if not self.result.get("success"):
            return self.result

        compose_id = self.args.get('compose_id')
        template_id = self.args.get('template_id')

        compose = TemplateCompose.query.filter(
            and_(TemplateCompose.id == compose_id,
                 TemplateCompose.removed == None)).first()
        if not compose:
            em = 'Invalid compose id {0}'.format(compose_id)
            logger.info(em)
            return {"error": [{"code": 401, "msg": "{0}".format(em)}]}
        ref = ComposeTemplateRef.query.filter(
            ComposeTemplateRef.compose_id == compose_id,
            ComposeTemplateRef.template_id == template_id).first()
        if not ref:
            em = "ComposeTemplate is not exist"
            return {"error": [{"code": 401, "msg": "{0}".format(em)}]}

        try:
            db_session.delete(ref)
            db_session.commit()
            logger.info('Template ref {0} deleted from compose {1}'.format(
                ref.id, compose_id))
            return {"success": [{"code": 200, "msg": ""}]}
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {"error": [{"code": 500, "msg": ""}]}
Пример #3
0
 def post(self):
     try:
         if not self.result.get("success"):
             return self.result
         network_id = self.args.get('network_id').strip()
         sw_ip = self.args.get('sw_ip').strip()
         sw_pwd = self.args.get('sw_pwd').strip()
         sw_user = self.args.get('sw_user').strip()
         network = Network.query.filter(Network.network_id == network_id).first()
         if not network:
             em = "can not fond network. id: <{0}>".format(network_id)
             logger.warn(em)
             return 400
         vlan = network.vlan
         vni = network.vni
         if not network.iscreated:
             task = Thread(target=lambda: ConfigureSdnSwitch.add_vtep(sw_ip, sw_user, sw_pwd, vlan, vni))
             task.setDaemon(True)
             task.start()
         return {"success": {"code": 200, "msg": ""}}
     except Exception as e:
         db_session.rollback()
         em = "config sdn switch error. msg: <{0}>".format(e)
         logger.warn(em)
         return 500
Пример #4
0
    def put(self):
        """
        update a network
        """
        if not self.result.get("success"):
            return self.result

        name = self.args.get('name')
        user_id = self.context.get('user_id')
        n_name = self.args.get('n_name')
        description = self.args.get('description')
        data = {}
        if n_name:
            data.update({'name': n_name})
        if description:
            data.update({'description': description})

        exist_network = Network.query.filter(and_(Network.name == name,
                                                  Network.removed == None,
                                                  Network.user_id == user_id)).first()
        if not exist_network:
            em = 'Network {0} is not exist'.format(name)
            logger.info(em)
            return {"error": [{"code": 401, "msg": "{0}".format(em)}]}
        try:
            Network.query.filter(and_(Network.user_id == user_id,
                                      Network.name == name)).update(data)
            db_session.commit()
            return {'ec': 0, 'em': 'success'}
        except Exception as e:
            db_session.rollback()
            logger.warn('Unable to update networke, user id=`%s` name=`%s`' % (user_id, name))
            return {"error": [{"code": 500, "msg": "{0}".format(e)}]}
Пример #5
0
    def delete(self, project_id, service_id):

        project = Project.query.filter(Project.id == project_id).first()
        if project is None:
            em = 'Invalid project id ' + str(project_id)
            logger.info(em)
            return {'ec': 1, 'em': em}
        service = Service.query.filter(
            and_(Service.project_id == project_id,
                 Service.id == service_id)).first()
        if service is None:
            em = 'Invalid service id ' + str(service_id)
            logger.info(em)
            return {'ec': 1, 'em': em}
        existing_services = Service.query.filter(
            Service.project_id == project_id).all()
        if len(existing_services) == 1:
            em = 'Unable to remove the only one service {0}. Please delete the project instead'.format(
                service_id)
            logger.info(em)
            return {'ec': 1, 'em': em}

        if project.state != 'created':
            try:
                compose_project = get_compose_project(project)
                containers = compose_project.containers(
                    service_names=[service.name], stopped=True)
                for container in containers:
                    container.remove(v=True, force=True)
            except Exception as e:
                em = 'Unable to remove containers of service {0}: {1}'.format(
                    service.name, e)
                logger.warn(em)
                return {'ec': 2, 'em': em}

        try:
            VlanIpAddress.query.filter(
                VlanIpAddress.service_id == service.id).update({
                    VlanIpAddress.service_id:
                    None,
                    VlanIpAddress.user_id:
                    None,
                    VlanIpAddress.state:
                    'free'
                })
            db_session.delete(service)
            db_session.flush()
            project_yml = setup_project_yml(project)
            Project.query.filter(Project.id == project.id).update(
                {'yml': project_yml})
            db_session.commit()
            logger.info('{0} deleted'.format(service))
            save_project_yml(project)
            return {'ec': 0, 'em': 'success'}
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {'ec': 3, 'em': 'Exception {0}'.format(e)}
Пример #6
0
 def start(self, project, service):
     try:
         project_name = start_service(project, service)
         logger.info("Service %s started, compose project %s", service.name,
                     project_name)
         return {'ec': 0, 'em': 'success'}
     except Exception as e:
         db_session.rollback()
         logger.warn(str(e))
         return {'ec': 1, 'em': str(e)}
Пример #7
0
 def stop(self, project, service):
     try:
         compose_project = get_compose_project(project)
         compose_project.stop(service_names=[service.name])
         logger.info("Service %s stopped, compose project %s", service.name,
                     compose_project.name)
         return {'ec': 0, 'em': 'success'}
     except Exception as e:
         db_session.rollback()
         logger.warn(str(e))
         return {'ec': 1, 'em': str(e)}
Пример #8
0
    def post(self):
        """
        method to add template to template groups
        """
        if not self.result.get("success"):
            return self.result

        template_id = self.args.get('template_id')
        compose_id = self.args.get('compose_id')

        compose = TemplateCompose.query.filter(
            and_(TemplateCompose.id == compose_id,
                 TemplateCompose.removed == None)).first()
        if not compose:
            em = 'Invalid compose id {0}'.format(compose_id)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        if type(template_id) is not int:
            em = 'Invalid template_id {0}, it should be a integer'.format(
                template_id)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        template = ServiceTemplate.query.filter(
            ServiceTemplate.id == template_id).first()
        if not template:
            em = 'Invalid template_id {0}'.format(template_id)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        exist_ref = ComposeTemplateRef.query.filter(
            and_(ComposeTemplateRef.compose_id == compose_id,
                 ComposeTemplateRef.template_id == template_id)).first()
        if exist_ref:
            em = 'Template {0} is already added to compose {1}'.format(
                template_id, compose_id)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        ref = ComposeTemplateRef(compose.id, template_id)
        try:
            db_session.add(ref)
            db_session.commit()
            logger.info('Template {0} added to compose {1}'.format(
                template_id, compose_id))
            compose_ret = TemplateCompose.query.filter(
                TemplateCompose.id == compose_id).first()
            return marshal(compose_ret, TEMPLATE_COMPOSE_FIELDS,
                           'templatecompose')
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {"error": [{"code": 500, "msg": "{0}".format(e)}]}
Пример #9
0
 def delete_vtep(sw_ip, sw_user, sw_pwd, vlan, network_id):
     try:
         sdn_switch_obj = PyjsonrpcClient(sw_ip, username=sw_user, password=sw_pwd)
         vteps = sdn_switch_obj.get_vteps()
         if vteps.get("error"):
             return vteps
         for vtep_index, vtep_ip in vteps.iteritems():
             sdn_switch_obj.delete_vni_mapping(vlan, vtep_index)
         Network.query.filter(Network.network_id == network_id).update({Network.iscreated: False})
         db_session.commit()
     except Exception as e:
         db_session.rollback()
         em = "delete vtep error. msg: <{0}>".format(e)
         logger.warn(em)
         return 500
Пример #10
0
 def delete(self, compose_id):
     compose = TemplateCompose.query.filter(
         and_(TemplateCompose.id == compose_id,
              TemplateCompose.removed == None)).first()
     if compose is None:
         return {"templatecompose": {"id": compose_id}}
     if (not compose.public and compose.user_id != g.user.id and g.user.type != 'Admin') \
             or (compose.public and g.user.type != 'Admin'):
         em = 'No auth for deleting the TemplateCompose'
         logger.info(em)
         return {'ec': 1, 'em': em}
     try:
         TemplateCompose.query.filter(
             TemplateCompose.id == compose_id).update(
                 {TemplateCompose.removed: datetime.datetime.now()})
         db_session.commit()
         logger.info('{0} removed'.format(compose))
     except Exception as e:
         logger.warn(e)
         db_session.rollback()
         return {'ec': 3, 'em': 'Exception {0}'.format(e)}
     return {"templatecompose": {"id": compose_id}}
Пример #11
0
    def delete(self, name):
        """
        method to delete TemplateCompose list
        :param name: 
        :return: 
        """
        if not self.result.get("success"):
            return self.result

        compose = TemplateCompose.query.filter(
            TemplateCompose.name == name).first()
        if not compose:
            em = 'name {0} not found'.format(name)
            logger.info(em)
            return {"error": [{"code": 401, "msg": "{0}".format(em)}]}
        try:
            db_session.delete(compose)
            db_session.commit()
            logger.info('{0} removed'.format(compose))
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {"error": [{"code": 401, "msg": "{0}".format(e)}]}
        return {"success": [{"code": 200, "msg": ""}]}
Пример #12
0
    def post(self, project_id):

        project = Project.query.filter(Project.id == project_id).first()
        if project is None:
            em = 'Invalid project id ' + str(project_id)
            logger.info(em)
            return {'ec': 1, 'em': em}
        services = request.get_json()
        if not services:
            em = 'No service provided'
            logger.info(em)
            return {'ec': 1, 'em': em}

        existing_services = Service.query.filter(
            Service.project_id == project_id).all()
        service_names = [s.name for s in existing_services]
        all_networks = Network.query.filter(Network.removed == None).all()
        if not all_networks:
            allowed_external_nets = []
        else:
            allowed_external_nets = [
                network.name for network in all_networks
                if g.user.type == 'Admin' or network.public or (
                    g.user.id in [user.id for user in network.users])
            ]

        service_depends = {}
        template_id_depends = []
        template_ids = [s.template_id for s in existing_services]
        for s_name in list(services.keys()):
            template_id = services[s_name].get("template_id")
            template_ids.append(template_id)
            template_depends = ServiceTemplateDepends.query.filter(
                ServiceTemplateDepends.template_id == template_id).all()
            for service_template_depend in template_depends:
                if service_template_depend.template_id_depend not in template_id_depends:
                    template_id_depends.append(
                        service_template_depend.template_id_depend)
                    template_depend = ServiceTemplate.query.filter(
                        ServiceTemplate.id ==
                        service_template_depend.template_id_depend).first()
                    service_template_data = json.loads(template_depend.yml)
                    service_depend = {}
                    service_depend["template_id"] = template_depend.id
                    if service_template_data.get("environment"):
                        service_depend[
                            "environment"] = service_template_data.get(
                                "environment")
                    if service_template_data.get("hostname"):
                        service_depend["hostname"] = service_template_data.get(
                            "hostname")
                    service_depend["restart"] = "always"
                    service_depend["networks"] = {"default": {}}
                    name = service_template_data.get("service")
                    service_depends[name] = service_depend
        for s_name in list(service_depends.keys()):
            template_id = service_depends[s_name].get("template_id")
            if template_id not in template_ids:
                services[s_name] = service_depends[s_name]

        for s_name in list(services.keys()):
            if (s_name is None) or (type(s_name) is not unicode) or (
                    not re.match('^[a-zA-Z0-9\._\-]+$', s_name)):
                em = 'Invalid service name {0}'.format(s_name)
                logger.info(em)
                return {'ec': 1, 'em': em}
            if s_name in service_names:
                em = 'Duplicated service name {0}'.format(s_name)
                logger.info(em)
                return {'ec': 1, 'em': em}
            service_names.append(s_name)
            template_id = services[s_name].get("template_id")
            template = ServiceTemplate.query.filter(
                ServiceTemplate.id == template_id).first()
            if not template:
                em = 'Invalid template id {0}'.format(template_id)
                logger.info(em)
                return {'ec': 1, 'em': em}
            networks = services[s_name].get("networks")
            if networks:
                for n_name in networks:
                    if n_name != "default":
                        network = networks.get(n_name)
                        ipaddress = network.get("ipv4_address")
                        network_db = Network.query.filter(
                            Network.name == n_name).first()
                        if ipaddress == '':
                            ipaddress_db = VlanIpAddress.query.filter(
                                and_(VlanIpAddress.network_id == network_db.id,
                                     VlanIpAddress.state == 'free')).order_by(
                                         func.rand()).first()
                            if ipaddress_db:
                                network[
                                    "ipv4_address"] = ipaddress_db.ip_address
                        else:
                            ipaddress_db = VlanIpAddress.query.filter(
                                and_(VlanIpAddress.network_id == network_db.id,
                                     VlanIpAddress.state == 'allocated',
                                     VlanIpAddress.ip_address ==
                                     ipaddress)).first()
                            if ipaddress_db:
                                em = 'IP address {0} has been used'.format(
                                    ipaddress_db.ip_address)
                                logger.info(em)
                                return {'ec': 1, 'em': em}
                            ipaddress_db = VlanIpAddress.query.filter(
                                and_(VlanIpAddress.network_id == network_db.id,
                                     VlanIpAddress.state == 'free',
                                     VlanIpAddress.ip_address ==
                                     ipaddress)).first()
                        if ipaddress_db:
                            VlanIpAddress.query.filter(
                                VlanIpAddress.id == ipaddress_db.id).update({
                                    VlanIpAddress.user_id:
                                    g.user.id,
                                    VlanIpAddress.state:
                                    'allocated'
                                })
                em = check_service_networks(s_name, networks,
                                            allowed_external_nets)
                if em != '':
                    logger.info(em)
                    return {'ec': 1, 'em': em}

                # Change service name
                if VLAN_CON_CANT_USE_FULL_NAME in networks:
                    s_new_name = s_name.split('.')[0]
                    if s_new_name != s_name:
                        if s_new_name in service_names:
                            em = "Unable to rename service {0} to {1}, duplicated service".format(
                                s_name, s_new_name)
                            logger.info(em)
                            return {'ec': 1, 'em': em}
                        services[s_new_name] = services.pop(s_name)
                        logger.info("Service name %s changed to %s", s_name,
                                    s_new_name)
            else:
                services[s_name]["networks"] = {"default": {}}

            # Set default network aliases
            if 'default' in networks:
                default_network = networks.get("default")
                if default_network is None:
                    default_network = {}
                    networks["default"] = default_network
                service_template_data = json.loads(template.yml)
                service_template_service = service_template_data.get("service")
                service_template_aliases = service_template_data.get("aliases")
                if service_template_aliases is None:
                    service_template_aliases = [service_template_service]
                else:
                    service_template_aliases.append(service_template_service)
                logger.info(service_template_aliases)
                default_network['aliases'] = service_template_aliases

        try:
            for s_name in services:
                service = services[s_name]
                template_id = service['template_id']
                data = {}
                if service.get("hostname"):
                    data["hostname"] = service.get("hostname")
                if service.get("environment"):
                    data["environment"] = service.get("environment")
                if service.get("command"):
                    data["command"] = service.get("command")
                data["restart"] = "always"
                if service.get("networks"):
                    data["networks"] = service.get("networks")
                new_service = Service(s_name, project.id, template_id,
                                      json.dumps(data))
                db_session.add(new_service)
                db_session.flush()
                networks = service.get("networks")
                for n_name in networks:
                    if n_name != "default":
                        network = networks.get(n_name)
                        ipaddress = network.get("ipv4_address")
                        if ipaddress != '':
                            VlanIpAddress.query.filter(
                                VlanIpAddress.ip_address == ipaddress).update(
                                    {VlanIpAddress.service_id: new_service.id})
            project_yml = setup_project_yml(project)
            Project.query.filter(Project.id == project.id).update(
                {Project.yml: project_yml})
            db_session.commit()
            save_project_yml(project)
            logger.info('%s created', project)
            return {'ec': 0, 'em': 'success'}
        except Exception as e:
            db_session.rollback()
            logger.warn("Unable to add services: %s", e)
            return {'ec': 3, 'em': str(e)}
Пример #13
0
    def put(self, project_id, service_id):

        project = Project.query.filter(Project.id == project_id).first()
        if project is None:
            em = 'Invalid project id ' + str(project_id)
            logger.info(em)
            return {'ec': 1, 'em': em}
        service = Service.query.filter(
            and_(Service.project_id == project_id,
                 Service.id == service_id)).first()
        if service is None:
            em = 'Invalid service id ' + str(service_id)
            logger.info(em)
            return {'ec': 1, 'em': em}

        args = request.get_json()
        template_id = args.get('template_id')
        template = ServiceTemplate.query.filter(
            ServiceTemplate.id == template_id).first()
        if not template:
            em = 'Invalid template id {0}'.format(template_id)
            logger.info(em)
            return {'ec': 1, 'em': em}
        data = {'name': service.name}
        if args.get("hostname"):
            data["hostname"] = args.get("hostname")
        if args.get("environment"):
            data["environment"] = args.get("environment")
        if args.get("command"):
            data["command"] = args.get("command")
        data["restart"] = "always"
        s_name = service.name
        s_new_name = service.name
        networks = args.get("networks")
        if networks:
            for n_name in networks:
                if n_name != "default":
                    network = networks.get(n_name)
                    ipaddress_new = network.get("ipv4_address")
                    network_db = Network.query.filter(
                        Network.name == n_name).first()
                    ipaddress_db = VlanIpAddress.query.filter(
                        and_(VlanIpAddress.network_id == network_db.id,
                             VlanIpAddress.state == 'allocated',
                             VlanIpAddress.service_id == service_id)).first()
                    if ipaddress_db:
                        ipaddress_old = ipaddress_db.ip_address
                    else:
                        ipaddress_old = ''
                    if ipaddress_new == '' and ipaddress_old == '':
                        ipaddress_db = VlanIpAddress.query.filter(
                            and_(VlanIpAddress.network_id == network_db.id,
                                 VlanIpAddress.state == 'free')).order_by(
                                     func.rand()).first()
                        network["ipv4_address"] = ipaddress_db.ip_address
                        VlanIpAddress.query.filter(
                            VlanIpAddress.ip_address ==
                            ipaddress_db.ip_address).update({
                                VlanIpAddress.service_id:
                                service_id,
                                VlanIpAddress.user_id:
                                g.user.id,
                                VlanIpAddress.state:
                                'allocated'
                            })
                    elif ipaddress_new == '' and ipaddress_old != '':
                        network["ipv4_address"] = ipaddress_old
                    elif ipaddress_new != ipaddress_old:
                        ipaddress_db = VlanIpAddress.query.filter(
                            and_(VlanIpAddress.network_id == network_db.id,
                                 VlanIpAddress.state == 'allocated',
                                 VlanIpAddress.ip_address ==
                                 ipaddress_new)).first()
                        if ipaddress_db:
                            em = 'IP address {0} has been used'.format(
                                ipaddress_db.ip_address)
                            logger.info(em)
                            return {'ec': 1, 'em': em}
                        else:
                            VlanIpAddress.query.filter(
                                VlanIpAddress.ip_address ==
                                ipaddress_new).update({
                                    VlanIpAddress.service_id:
                                    service_id,
                                    VlanIpAddress.user_id:
                                    g.user.id,
                                    VlanIpAddress.state:
                                    'allocated'
                                })
                            VlanIpAddress.query.filter(
                                VlanIpAddress.ip_address ==
                                ipaddress_old).update({
                                    VlanIpAddress.service_id:
                                    None,
                                    VlanIpAddress.user_id:
                                    None,
                                    VlanIpAddress.state:
                                    'free'
                                })
            all_networks = Network.query.filter(Network.removed == None).all()
            if not all_networks:
                allowed_external_nets = []
            else:
                allowed_external_nets = [
                    network.name for network in all_networks
                    if g.user.type == 'Admin' or network.public or (
                        g.user.id in [user.id for user in network.users])
                ]
            em = check_service_networks(service.name, networks,
                                        allowed_external_nets)
            if em != '':
                logger.info(em)
                return {'ec': 1, 'em': em}

            service_name_rows = db_session.query(Service.name).filter(
                Service.project_id == service.project_id).all()
            service_names = [r[0] for r in service_name_rows]

            # Change service name
            if VLAN_CON_CANT_USE_FULL_NAME in networks:
                s_new_name = s_name.split('.')[0]
                if s_new_name != s_name:
                    if s_new_name in service_names:
                        em = "Unable to rename service {0} to {1}, duplicated service".format(
                            s_name, s_new_name)
                        logger.info(em)
                        return {'ec': 1, 'em': em}
                    logger.info("Service name %s changed to %s", s_name,
                                s_new_name)
        else:
            networks = {"default": {}}

        # Set default network aliases
        if 'default' in networks:
            default_network = networks.get("default")
            if default_network is None:
                default_network = {}
                networks["default"] = default_network
            service_template_data = json.loads(template.yml)
            service_template_service = service_template_data.get("service")
            service_template_aliases = service_template_data.get("aliases")
            if service_template_aliases is None:
                service_template_aliases = [service_template_service]
            else:
                service_template_aliases.append(service_template_service)
            logger.info(service_template_aliases)
            default_network['aliases'] = service_template_aliases

        data["networks"] = networks

        # Remove containers before we change the service.
        restart = False
        if project.state != 'created':
            try:
                compose_project = get_compose_project(project)
                containers = compose_project.containers(
                    service_names=[service.name], stopped=True)
                for container in containers:
                    if container.is_running:
                        restart = True
                    container.remove(force=True)
            except NoSuchService:
                pass
            except Exception as e:
                logger.warn(type(e))
                em = 'Unable to remove containers of service {0}: {1}'.format(
                    service.name, e)
                logger.warn(em)
                return {'ec': 2, 'em': em}

        try:
            Service.query.filter(Service.id == service_id).update({
                Service.name:
                s_new_name,
                Service.template_id:
                template_id,
                Service.data:
                json.dumps(data)
            })
            db_session.commit()
            logger.info('Service %s updated, %s', service.name, project)
            if restart:
                start_service(project, service)
            return {'ec': 0, 'em': 'success'}
        except Exception as e:
            em = 'Unable to update service: {0}'.format(e)
            db_session.rollback()
            logger.warn(em)
            return {'ec': 2, 'em': em}
Пример #14
0
    def post(self):
        """        
        method to add a ServiceTemplate
        """
        if not self.result.get("success"):
            return self.result

        args = self.args
        name = args.get("name")
        if (name is None) or (type(name) is not unicode) or len(
                name.strip()) == 0:
            em = 'Invalid name {0}'.format(name)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        name = name.strip()
        description = args.get("description")
        if description and type(description) is not unicode:
            em = 'Invalid description {0}'.format(description)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        exist_template = ServiceTemplate.query.filter(
            ServiceTemplate.name == name).first()
        if exist_template:
            em = 'ServiceTemplate {0} is already exist'.format(name)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        service = args.get("service")
        if (service is None) or (type(service) is not unicode) or (
                not re.match('^[a-zA-Z0-9\._\-]+$', service)):
            em = 'Invalid service {0}'.format(service)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        image = args.get("image")
        if (image is None) or (type(image) is not unicode) or len(
                image.strip()) == 0:
            em = 'Invalid image {0}'.format(image)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        hostname = args.get('hostname')
        if (hostname is not None) and (type(hostname) is not unicode):
            em = 'Invalid hostname {0}'.format(hostname)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        aliases = args.get('aliases')
        if (aliases is not None) and (type(aliases) is not list):
            em = 'Invalid aliases {0}'.format(aliases)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        command = args.get('command')
        if (command is not None) and (type(command) is not unicode):
            em = 'Invalid command {0}'.format(command)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        environment = args.get('environment')
        if environment is not None:
            if type(environment) is not dict:
                em = 'Invalid environment {0}'.format(environment)
                logger.info(em)
                return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
            for key in environment:
                if (key is None) or (type(key) is not unicode) or len(
                        key.strip()) == 0:
                    em = 'Invalid environment key {0}'.format(key)
                    logger.info(em)
                    return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        independent = args.get('independent')
        if (independent is not None) and (type(independent) is not bool):
            em = 'Invalid independent {0}'.format(independent)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}
        depends = args.get('depends')
        if (depends is not None) and (type(depends) is not list):
            em = 'Invalid template depends {0}'.format(depends)
            logger.info(em)
            return {"error": [{"code": 400, "msg": "{0}".format(em)}]}

        service_dict = OrderedDict({'service': service})
        service_dict['image'] = image
        if hostname is not None:
            service_dict['hostname'] = hostname
        if aliases is not None:
            for tmp in aliases:
                if tmp == '':
                    aliases.remove(tmp)
            service_dict['aliases'] = aliases
        if command is not None:
            service_dict['command'] = command
        if environment is not None:
            service_dict['environment'] = args['environment']
        service_yml = json.dumps(service_dict)
        # user_id = self.context.get('user_id')
        user_id = None
        service_template = ServiceTemplate(name, description, image,
                                           service_yml, user_id, independent)
        try:
            db_session.add(service_template)
            db_session.flush()
            if depends is not None:
                for depend in depends:
                    service_template_depends = ServiceTemplateDepends(
                        service_template.id, depend)
                    db_session.add(service_template_depends)
            db_session.commit()
            logger.info('{0} created'.format(service_template))
            populate_template(service_template)
        except Exception as e:
            logger.warn(e)
            db_session.rollback()
            return {"error": [{"code": 500, "msg": "{0}".format(e)}]}

        return jsonify(
            servicetemplate=marshal(service_template, TEMPLATE_FIELDS))
Пример #15
0
    def post(self):
        """
        method to sync Network from OpenStack's user define network
        """
        if not self.result.get("success"):
            return self.result
        try:
            # description = self.args.get("description")
            user_id = self.context.get('user_id')

            # get user's all networks from OpenStack
            openstack_networks = get_user_networks(self.token)
            if not openstack_networks:
                return False, 500
            # get user's all network from docker(smurf)
            docker_networks = Network.query.filter(Network.user_id == user_id).all()
            if not docker_networks:
                invalid_nets = []
            else:
                invalid_nets = copy.copy(docker_networks)
            for openstack_network in openstack_networks:
                network_id = openstack_network
                subnet_ids = openstack_networks.get(network_id).get("sub_nets")
                status = openstack_networks.get(network_id).get("status")
                # get network's vni
                networksegment = NetworkSegments.query.filter(NetworkSegments.network_id == network_id).first()
                if networksegment is None:
                    em = "could not be find network's vni id from openstack. network id: {0}".format(network_id)
                    logger.info(em)
                    return False, 500
                vni = networksegment.segmentation_id
                # if network has no Vxlan id. the container can not use that network
                if not vni:
                    continue
                # generate uniqueness vlan id
                networks = Network.query.filter(Network.vlan != None).all()
                vlan_id = set(range(config.vlan_range[0], config.vlan_range[1])).difference(
                    set([network.vlan for network in networks])).pop()
                if not vlan_id:
                    em = 'no available vlan id allocation'
                    logger.warn(em)
                    return False, 500
                for subnet_id in subnet_ids:
                    ret = [s for s in docker_networks if s.network_id == network_id and s.subnet_id == subnet_id]
                    # if not found network in docker platform. add the network in docker platform
                    data = get_subnet(self.token, subnet_id)
                    if not data:
                        return False, 500
                    cidr = data.get('subnet').get('cidr')
                    gateway = data.get('subnet').get('gateway_ip')
                    name = data.get('subnet').get("name")
                    if not ret:
                        # get openstack network's info
                        # get subnet cidr and gateway
                        network = Network(name=name, description=None, user_id=user_id, vlan=vlan_id, vni=vni,
                                          network_id=network_id, subnet_id=subnet_id, cidr=cidr, gateway=gateway,
                                          status=status)
                        db_session.add(network)
                        db_session.flush()
                    else:
                        Network.query.filter(and_(Network.network_id == network_id,
                                                  Network.subnet_id == subnet_id)).update({Network.name: name,
                                                                                           Network.status: status,
                                                                                           Network.cidr: cidr,
                                                                                           Network.gateway: gateway})
                        # db_session.flush()
                        db_session.commit()
                    # if found network in docker platform. update network info
                    # exclude OpenStack's networks from docker db. it is invalid networks
                    invalid_nets = [s for s in invalid_nets if s.subnet_id != subnet_id and s.network_id != network_id]

            # delete invalid nets
            for invalid_net in invalid_nets:
                # remove network if is created on docker
                if invalid_net.iscreated:
                    # subnet id is the docker network name
                    net_name = invalid_net.subnet_id
                    VlanNetworkManager.delete_network(net_name)
                Network.query.filter(and_(Network.network_id == invalid_net.network_id,
                                          Network.subnet_id == invalid_net.subnet_id)).delete()
                db_session.flush()

            db_session.commit()
            return True, 200
        except Exception as e:
            db_session.rollback()
            em = "cannot sync network from OpenStack. msg: {0}".format(e)
            logger.warn(em)
            return False, 500