Example #1
0
    def run(self):
        self.app.register_backend(self.srv_type, self.service_backend)

        if self.reg_srv:
            self.register_service()

        # setup shutdown handler for de-registration of service
        for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
            signal.signal(sig, self.shutdown_handler)

        up = urlparse(self.stg["service_endpoint"])
        dep_port = CONFIG.get("general", "port")
        if dep_port != "":
            LOG.warn(
                "DEPRECATED: parameter general: port in service manager config. "
                "Service port number (" + str(up.port) + ") is taken from the service manifest"
            )

        if self.DEBUG:
            from wsgiref.simple_server import make_server

            httpd = make_server("", int(up.port), self.app)
            httpd.serve_forever()
        else:
            container = wsgi.WSGIContainer(self.app)
            http_server = httpserver.HTTPServer(container)
            http_server.listen(int(up.port))
            ioloop.IOLoop.instance().start()

        LOG.info("Service Manager running on interfaces, running on port: " + int(up.port))
Example #2
0
    def service_parameters(self, state='', content_type='text/occi'):
        # takes the internal parameters defined for the lifecycle phase...
        #       and combines them with the client supplied parameters
        if content_type == 'text/occi':
            params = []
            # get the state specific internal parameters
            try:
                params = self.service_params[state]
            except KeyError as err:
                LOG.warn(
                    'The requested states parameters are not available: "' +
                    state + '"')

            # get the client supplied parameters if any
            try:
                for p in self.service_params['client_params']:
                    params.append(p)
            except KeyError as err:
                LOG.info('No client params')

            header = ''
            for param in params:
                if param['type'] == 'string':
                    value = '"' + param['value'] + '"'
                else:
                    value = str(param['value'])

                header = header + param['name'] + '=' + value + ', '

            return header[0:-2]
        else:
            LOG.error('Content type not supported: ' + content_type)
Example #3
0
    def run(self):
        self.app.register_backend(self.srv_type, self.service_backend)

        if self.reg_srv:
            self.register_service()

            # setup shutdown handler for de-registration of service
            for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
                signal.signal(sig, self.shutdown_handler)

        up = urlparse(self.stg['service_endpoint'])
        dep_port = CONFIG.get('general', 'port')
        if dep_port != '':
            LOG.warn('DEPRECATED: parameter general: port in service manager config. '
                     'Service port number (' + str(up.port) + ') is taken from the service manifest')

        if self.DEBUG:
            LOG.debug('Using WSGI reference implementation')
            httpd = make_server('', int(up.port), self.app)
            httpd.serve_forever()
        else:
            LOG.debug('Using tornado implementation')
            container = wsgi.WSGIContainer(self.app)
            http_server = httpserver.HTTPServer(container)
            http_server.listen(int(up.port))
            ioloop.IOLoop.instance().start()

        LOG.info('Service Manager running on interfaces, running on port: ' + str(up.port))
Example #4
0
    def service_parameters(self, state='', content_type='text/occi'):
        # takes the internal parameters defined for the lifecycle phase...
        #       and combines them with the client supplied parameters
        if content_type == 'text/occi':
            params = []
            # get the state specific internal parameters
            try:
                params = self.service_params[state]
            except KeyError:  # as err:
                LOG.warn('The requested states parameters are not available: "' + state + '"')

            # get the client supplied parameters if any
            try:
                for param in self.service_params['client_params']:
                    params.append(param)
            except KeyError:  # as err:
                LOG.info('No client params')

            header = ''
            for param in params:
                if param['type'] == 'string':
                    value = '"' + param['value'] + '"'
                else:
                    value = str(param['value'])

                header = header + param['name'] + '=' + value + ', '

            return header[0:-2]
        else:
            LOG.error('Content type not supported: ' + content_type)
Example #5
0
    def run(self):
        # example request to the SO
        # curl -v -X GET http://localhost:8051/orchestrator/default \
        #   -H 'X-Auth-Token: '$KID \
        #   -H 'X-Tenant-Name: '$TENANT

        if self.entity.attributes['mcn.service.state'] in ['activate', 'deploy', 'provision', 'update']:
            heads = {
                'Content-Type': 'text/occi',
                'Accept': 'text/occi',
                'X-Auth-Token': self.extras['token'],
                'X-Tenant-Name': self.extras['tenant_name']}
            LOG.info('Getting state of service orchestrator with: ' + self.host + '/orchestrator/default')
            LOG.info('Sending headers: ' + heads.__repr__())
            r = http_retriable_request('GET', HTTP + self.host + '/orchestrator/default', headers=heads)

            attrs = r.headers['x-occi-attribute'].split(', ')
            for attr in attrs:
                kv = attr.split('=')
                if kv[0] != 'occi.core.id':
                    if kv[1].startswith('"') and kv[1].endswith('"'):
                        kv[1] = kv[1][1:-1]  # scrub off quotes
                    self.entity.attributes[kv[0]] = kv[1]
                    LOG.debug('OCCI Attribute: ' + kv[0] + ' --> ' + kv[1])

            # Assemble the SIG
            svcinsts = ''
            try:
                svcinsts = self.entity.attributes['mcn.so.svcinsts']
                del self.entity.attributes['mcn.so.svcinsts']  # remove this, not be be used anywhere else
            except KeyError:
                LOG.warn('There was no service instance endpoints - ignore if not a composition.')
                pass

            if self.registry is None:
                LOG.error('No registry!')

            if len(svcinsts) > 0:
                svcinsts = svcinsts.split()  # all instance EPs
                for svc_loc in svcinsts:
                    # TODO get the service instance resource representation
                    # source resource is self.entity
                    compos = svc_loc.split('/')
                    key = '/' + compos[3] + '/' + compos[4]
                    target = Resource(key, Resource.kind, [])  # target resource
                    target.attributes['mcn.sm.endpoint'] = svc_loc
                    self.registry.add_resource(key, target, None)

                    key = '/link/'+str(uuid.uuid4())
                    link = Link(key, Link.kind, [], self.entity, target)
                    self.registry.add_resource(key, link, None)
                    self.entity.links.append(link)
        else:
            LOG.debug('Cannot GET entity as it is not in the activated, deployed or provisioned, updated state')

        return self.entity, self.extras
Example #6
0
    def get_category(self, svc_kind):

        keystone = client.Client(token=self.token,
                                 tenant_name=self.tenant_name,
                                 auth_url=self.design_uri)

        try:
            svc = keystone.services.find(type=svc_kind.keys()[0])
            svc_ep = keystone.endpoints.find(service_id=svc.id)
        except Exception as e:
            LOG.error('Cannot find the service endpoint of: ' +
                      svc_kind.__repr__())
            raise e

        u = urlparse(svc_ep.publicurl)

        # sort out the OCCI QI path
        if u.path == '/':
            svc_ep.publicurl += '-/'
        elif u.path == '':
            svc_ep.publicurl += '/-/'
        else:
            LOG.warn('Service endpoint URL does not look like it will work: ' +
                     svc_ep.publicurl.__repr__())
            svc_ep.publicurl = u.scheme + '://' + u.netloc + '/-/'
            LOG.warn('Trying with the scheme and net location: ' +
                     svc_ep.publicurl.__repr__())

        heads = {
            'X-Auth-Token': self.token,
            'X-Tenant-Name': self.tenant_name,
            'Accept': 'application/occi+json'
        }

        try:
            r = requests.get(svc_ep.publicurl, headers=heads)
            r.raise_for_status()
        except requests.HTTPError as err:
            LOG.error('HTTP Error: should do something more here!' +
                      err.message)
            raise err

        registry = json.loads(r.content)

        category = None
        for cat in registry:
            if 'related' in cat:
                category = cat

        return Kind(scheme=category['scheme'],
                    term=category['term'],
                    related=category['related'],
                    title=category['title'],
                    attributes=category['attributes'],
                    location=category['location'])
Example #7
0
 def __init__(self, entity, extras):
     Task.__init__(self, entity, extras, state='initialise')
     self.nburl = CONFIG.get('cloud_controller', 'nb_api', '')
     if self.nburl[-1] == '/':
         self.nburl = self.nburl[0:-1]
     LOG.info('CloudController Northbound API: ' + self.nburl)
     if len(entity.attributes) > 0:
         LOG.info('Client supplied parameters: ' + entity.attributes.__repr__())
         # XXX check that these parameters are valid according to the kind specification
         self.extras['srv_prms'].add_client_params(entity.attributes)
     else:
         LOG.warn('No client supplied parameters.')
Example #8
0
 def __init__(self, entity, extras):
     Task.__init__(self, entity, extras, state='initialise')
     self.nburl = CONFIG.get('cloud_controller', 'nb_api', '')
     if self.nburl[-1] == '/':
         self.nburl = self.nburl[0:-1]
     LOG.info('CloudController Northbound API: ' + self.nburl)
     if len(entity.attributes) > 0:
         LOG.info('Client supplied parameters: ' + entity.attributes.__repr__())
         # XXX check that these parameters are valid according to the kind specification
         self.extras['srv_prms'].add_client_params(entity.attributes)
     else:
         LOG.warn('No client supplied parameters.')
Example #9
0
    def __init__(self, app, srv_type=None):
        # openstack objects tracking the keystone service and endpoint
        self.srv_ep = None
        self.ep = None
        self.DEBUG = True

        self.app = app
        self.service_backend = ServiceBackend(app)
        LOG.info('Using configuration file: ' + CONFIG_PATH)

        self.token, self.tenant_name = self.get_service_credentials()
        self.design_uri = CONFIG.get('service_manager', 'design_uri', '')
        if self.design_uri == '':
            LOG.fatal('No design_uri parameter supplied in sm.cfg')
            raise Exception('No design_uri parameter supplied in sm.cfg')

        self.stg = None
        stg_path = CONFIG.get('service_manager', 'manifest', '')
        if stg_path == '':
            raise RuntimeError('No STG specified in the configuration file.')
        with open(stg_path) as stg_content:
            self.stg = json.load(stg_content)
            stg_content.close()

        if not srv_type:
            srv_type = self.create_service_type()
        self.srv_type = srv_type

        self.reg_srv = CONFIG.getboolean('service_manager_admin',
                                         'register_service')
        if self.reg_srv:
            self.region = CONFIG.get('service_manager_admin', 'region', '')
            if self.region == '':
                LOG.info(
                    'No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne'
                )
                self.region = 'RegionOne'
            self.service_endpoint = CONFIG.get('service_manager_admin',
                                               'service_endpoint')
            if self.service_endpoint != '':
                LOG.warn(
                    'DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in '
                    'service manifest as service_endpoint')
            LOG.info('Using ' + self.stg['service_endpoint'] +
                     ' as the service_endpoint value '
                     'from service manifest')
            up = urlparse(self.stg['service_endpoint'])

            self.service_endpoint = up.scheme + '://' + up.hostname + ':' + str(
                up.port) + '/' + str('mobaas')
            LOG.info(self.service_endpoint)
Example #10
0
 def __init__(self):
     self.service_params = {}
     service_params_file_path = CONFIG.get('service_manager', 'service_params', '')
     if len(service_params_file_path) > 0:
         try:
             with open(service_params_file_path) as svc_params_content:
                 self.service_params = json.load(svc_params_content)
                 svc_params_content.close()
         except ValueError:  # as e:
             LOG.error("Invalid JSON sent as service config file")
         except IOError:  # as e:
             LOG.error('Cannot find the specified parameters file: ' + service_params_file_path)
     else:
         LOG.warn("No service parameters file found in config file, setting internal params to empty.")
Example #11
0
 def __init__(self):
     self.service_params = {}
     service_params_file_path = CONFIG.get('service_manager', 'service_params', '')
     if len(service_params_file_path) > 0:
         try:
             with open(service_params_file_path) as svc_params_content:
                 self.service_params = json.load(svc_params_content)
                 svc_params_content.close()
         except ValueError:  # as e:
             LOG.error("Invalid JSON sent as service config file")
         except IOError:  # as e:
             LOG.error('Cannot find the specified parameters file: ' + service_params_file_path)
     else:
         LOG.warn("No service parameters file found in config file, setting internal params to empty.")
Example #12
0
    def get_category(self, svc_kind):

        keystone = client.Client(token=self.token, tenant_name=self.tenant_name, auth_url=self.design_uri)

        try:
            svc = keystone.services.find(type=svc_kind.keys()[0])
            svc_ep = keystone.endpoints.find(service_id=svc.id)
        except Exception as e:
            LOG.error("Cannot find the service endpoint of: " + svc_kind.__repr__())
            raise e

        u = urlparse(svc_ep.publicurl)

        # sort out the OCCI QI path
        if u.path == "/":
            svc_ep.publicurl += "-/"
        elif u.path == "":
            svc_ep.publicurl += "/-/"
        else:
            LOG.warn("Service endpoint URL does not look like it will work: " + svc_ep.publicurl.__repr__())
            svc_ep.publicurl = u.scheme + "://" + u.netloc + "/-/"
            LOG.warn("Trying with the scheme and net location: " + svc_ep.publicurl.__repr__())

        heads = {"X-Auth-Token": self.token, "X-Tenant-Name": self.tenant_name, "Accept": "application/occi+json"}

        try:
            r = requests.get(svc_ep.publicurl, headers=heads)
            r.raise_for_status()
        except requests.HTTPError as err:
            LOG.error("HTTP Error: should do something more here!" + err.message)
            raise err

        registry = json.loads(r.content)

        category = None
        for cat in registry:
            if "related" in cat:
                category = cat

        return Kind(
            scheme=category["scheme"],
            term=category["term"],
            related=category["related"],
            title=category["title"],
            attributes=category["attributes"],
            location=category["location"],
        )
Example #13
0
    def __init__(self, app, srv_type=None):
        # openstack objects tracking the keystone service and endpoint
        self.srv_ep = None
        self.ep = None
        self.DEBUG = True

        self.app = app
        self.service_backend = ServiceBackend(app)
        LOG.info("Using configuration file: " + CONFIG_PATH)

        self.token, self.tenant_name = self.get_service_credentials()
        self.design_uri = CONFIG.get("service_manager", "design_uri", "")
        if self.design_uri == "":
            LOG.fatal("No design_uri parameter supplied in sm.cfg")
            raise Exception("No design_uri parameter supplied in sm.cfg")

        self.stg = None
        stg_path = CONFIG.get("service_manager", "manifest", "")
        if stg_path == "":
            raise RuntimeError("No STG specified in the configuration file.")
        with open(stg_path) as stg_content:
            self.stg = json.load(stg_content)
            stg_content.close()

        if not srv_type:
            srv_type = self.create_service_type()
        self.srv_type = srv_type

        self.reg_srv = CONFIG.getboolean("service_manager_admin", "register_service")
        if self.reg_srv:
            self.region = CONFIG.get("service_manager_admin", "region", "")
            if self.region == "":
                LOG.info("No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne")
                self.region = "RegionOne"
            self.service_endpoint = CONFIG.get("service_manager_admin", "service_endpoint")
            if self.service_endpoint != "":
                LOG.warn(
                    "DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in "
                    "service manifest as service_endpoint"
                )
            LOG.info(
                "Using " + self.stg["service_endpoint"] + " as the service_endpoint value " "from service manifest"
            )
            up = urlparse(self.stg["service_endpoint"])
            self.service_endpoint = up.scheme + "://" + up.hostname + ":" + str(up.port)
Example #14
0
    def __init__(self, app, srv_type=None):
        # openstack objects tracking the keystone service and endpoint
        self.srv_ep = None
        self.ep = None
        self.DEBUG = True

        self.app = app
        self.service_backend = ServiceBackend(app)
        LOG.info('Using configuration file: ' + CONFIG_PATH)

        self.token, self.tenant_name = self.get_service_credentials()
        self.design_uri = CONFIG.get('service_manager', 'design_uri', '')
        if self.design_uri == '':
                LOG.fatal('No design_uri parameter supplied in sm.cfg')
                raise Exception('No design_uri parameter supplied in sm.cfg')

        self.stg = None
        stg_path = CONFIG.get('service_manager', 'manifest', '')
        if stg_path == '':
            raise RuntimeError('No STG specified in the configuration file.')
        with open(stg_path) as stg_content:
            self.stg = json.load(stg_content)
            stg_content.close()

        if not srv_type:
            srv_type = self.create_service_type()
        self.srv_type = srv_type

        self.reg_srv = CONFIG.getboolean('service_manager_admin', 'register_service')
        if self.reg_srv:
            self.region = CONFIG.get('service_manager_admin', 'region', '')
            if self.region == '':
                LOG.info('No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne')
                self.region = 'RegionOne'
            self.service_endpoint = CONFIG.get('service_manager_admin', 'service_endpoint')
            if self.service_endpoint != '':
                LOG.warn('DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in '
                         'service manifest as service_endpoint')
            LOG.info('Using ' + self.stg['service_endpoint'] + ' as the service_endpoint value '
                                                               'from service manifest')
            up = urlparse(self.stg['service_endpoint'])
            
            self.service_endpoint = up.scheme + '://' + up.hostname + ':' + str(up.port) + '/' + str('mobaas')
	    LOG.info(self.service_endpoint)
Example #15
0
    def get_category(self, svc_kind):

        keystone = client.Client(token=self.token, tenant_name=self.tenant_name, auth_url=self.design_uri)

        try:
            svc = keystone.services.find(type=svc_kind.keys()[0])
            svc_ep = keystone.endpoints.find(service_id=svc.id)
        except Exception as e:
            LOG.error('Cannot find the service endpoint of: ' + svc_kind.__repr__())
            raise e

        u = urlparse(svc_ep.publicurl)

        # sort out the OCCI QI path
        if u.path == '/':
            svc_ep.publicurl += '-/'
        elif u.path == '':
            svc_ep.publicurl += '/-/'
        else:
            LOG.warn('Service endpoint URL does not look like it will work: ' + svc_ep.publicurl.__repr__())
            svc_ep.publicurl = u.scheme + '://' + u.netloc + '/-/'
            LOG.warn('Trying with the scheme and net location: ' + svc_ep.publicurl.__repr__())

        heads = {'X-Auth-Token': self.token, 'X-Tenant-Name': self.tenant_name, 'Accept': 'application/occi+json'}

        try:
            r = requests.get(svc_ep.publicurl, headers=heads)
            r.raise_for_status()
        except requests.HTTPError as err:
            LOG.error('HTTP Error: should do something more here!' + err.message)
            raise err

        registry = json.loads(r.content)

        category = None
        for cat in registry:
            if 'related' in cat:
                category = cat

        return Kind(scheme=category['scheme'], term=category['term'], related=category['related'],
                    title=category['title'], attributes=category['attributes'], location=category['location'])
Example #16
0
    def __create_app(self):

        # will generate an appname 24 chars long - compatible with v2 and v3
        # e.g. soandycd009b39c28790f3
        app_name = 'so' + self.entity.kind.term[0:4] + \
                   ''.join(random.choice('0123456789abcdef') for _ in range(16))
        heads = {'Content-Type': 'text/occi'}

        url = self.nburl + '/app/'

        if self.entity.extras['ops_version'] == 'v2':
            heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \
                                'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \
                                'small; scheme="http://schemas.openshift.com/template/app#"'
            heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name)
            LOG.debug('Ensuring SM SSH Key...')
            self.__ensure_ssh_key()
        elif self.entity.extras['ops_version'] == 'v3':

            # for OpSv3 bundle location is the repo id of the container image
            bundle_loc = CONFIG.get('service_manager', 'bundle_location', '')
            if bundle_loc == '':
                LOG.error('No bundle_location parameter supplied in sm.cfg')
                raise Exception('No bundle_location parameter supplied in sm.cfg')
            if bundle_loc.startswith('/'):
                LOG.warn('Bundle location does not look like an image reference!')
            LOG.debug('Bundle to execute: ' + bundle_loc)

            design_uri = CONFIG.get('service_manager', 'design_uri', '')
            if design_uri == '':
                raise Exception('No design_uri parameter supplied in sm.cfg')
            LOG.debug('Design URI: ' + design_uri)

            heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"'
            # TODO provide a means to provide additional docker env params
            attrs = 'occi.app.name="' + app_name + '", ' + \
                    'occi.app.image="' + bundle_loc + '", ' + \
                    'occi.app.env="DESIGN_URI=' + design_uri + '"'
            heads['X-OCCI-Attribute'] = str(attrs)
        else:
            LOG.error('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version'])
            raise Exception('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version'])

        LOG.debug('Requesting container to execute SO Bundle: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        r = http_retriable_request('POST', url, headers=heads, authenticate=True)

        loc = r.headers.get('Location', '')
        if loc == '':
            LOG.error("No OCCI Location attribute found in request")
            raise AttributeError("No OCCI Location attribute found in request")

        self.entity.attributes['occi.so.url'] = loc

        app_uri_path = urlparse(loc).path
        LOG.debug('SO container created: ' + app_uri_path)

        LOG.debug('Updating OCCI entity.identifier from: ' + self.entity.identifier + ' to: ' +
                  app_uri_path.replace('/app/', self.entity.kind.location))
        self.entity.identifier = app_uri_path.replace('/app/', self.entity.kind.location)

        LOG.debug('Setting occi.core.id to: ' + app_uri_path.replace('/app/', ''))
        self.entity.attributes['occi.core.id'] = app_uri_path.replace('/app/', '')

        # its a bit wrong to put this here, but we do not have the required information before.
        # this keeps things consistent as the timing is done right
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'].split('/'),
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'init',
                    'phase_event': 'start',
                    'response_time': 0,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        # OpSv2 only: get git uri. this is where our bundle is pushed to
        # XXX this is fugly
        # TODO use the same name for the app URI
        if self.entity.extras['ops_version'] == 'v2':
            self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path)
        elif self.entity.extras['ops_version'] == 'v3':
            self.entity.extras['loc'] = self.__git_uri(app_uri_path)
Example #17
0
    def __create_app(self):

        # will generate an appname 24 chars long - compatible with v2 and v3
        # e.g. soandycd009b39c28790f3
        app_name = 'so' + self.entity.kind.term[0:4] + \
                   ''.join(random.choice('0123456789abcdef') for _ in range(16))
        heads = {'Content-Type': 'text/occi'}

        url = self.nburl + '/app/'

        if self.entity.extras['ops_version'] == 'v2':
            heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \
                                'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \
                                'small; scheme="http://schemas.openshift.com/template/app#"'
            heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name)
            LOG.debug('Ensuring SM SSH Key...')
            self.__ensure_ssh_key()
        elif self.entity.extras['ops_version'] == 'v3':

            # for OpSv3 bundle location is the repo id of the container image
            bundle_loc = os.environ.get('BUNDLE_LOC', False)
            if not bundle_loc:
                bundle_loc = CONFIG.get('service_manager', 'bundle_location',
                                        '')
            if bundle_loc == '':
                LOG.error('No bundle_location parameter supplied in sm.cfg')
                raise Exception(
                    'No bundle_location parameter supplied in sm.cfg')
            if bundle_loc.startswith('/'):
                LOG.warn(
                    'Bundle location does not look like an image reference!')
            LOG.debug('Bundle to execute: ' + bundle_loc)

            design_uri = CONFIG.get('service_manager', 'design_uri', '')
            if design_uri == '':
                raise Exception('No design_uri parameter supplied in sm.cfg')
            LOG.debug('Design URI: ' + design_uri)

            heads[
                'category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"'
            # TODO provide a means to provide additional docker env params
            attrs = 'occi.app.name="' + app_name + '", ' + \
                    'occi.app.image="' + bundle_loc + '", ' + \
                    'occi.app.env="DESIGN_URI=' + design_uri + '"'
            heads['X-OCCI-Attribute'] = str(attrs)
        else:
            LOG.error('Unknown OpenShift version. ops_version: ' +
                      self.entity.extras['ops_version'])
            raise Exception('Unknown OpenShift version. ops_version: ' +
                            self.entity.extras['ops_version'])

        LOG.debug('Requesting container to execute SO Bundle: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        r = http_retriable_request('POST',
                                   url,
                                   headers=heads,
                                   authenticate=True)

        loc = r.headers.get('Location', '')
        if loc == '':
            LOG.error("No OCCI Location attribute found in request")
            raise AttributeError("No OCCI Location attribute found in request")

        self.entity.attributes['occi.so.url'] = loc

        app_uri_path = urlparse(loc).path
        LOG.debug('SO container created: ' + app_uri_path)

        LOG.debug('Updating OCCI entity.identifier from: ' +
                  self.entity.identifier + ' to: ' +
                  app_uri_path.replace('/app/', self.entity.kind.location))
        self.entity.identifier = app_uri_path.replace(
            '/app/', self.entity.kind.location)

        LOG.debug('Setting occi.core.id to: ' +
                  app_uri_path.replace('/app/', ''))
        self.entity.attributes['occi.core.id'] = app_uri_path.replace(
            '/app/', '')

        # its a bit wrong to put this here, but we do not have the required information before.
        # this keeps things consistent as the timing is done right
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'].split('/'),
            'sm_name': self.entity.kind.term,
            'so_phase': 'init',
            'phase_event': 'start',
            'response_time': 0,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        # OpSv2 only: get git uri. this is where our bundle is pushed to
        # XXX this is fugly
        # TODO use the same name for the app URI
        if self.entity.extras['ops_version'] == 'v2':
            self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path)
        elif self.entity.extras['ops_version'] == 'v3':
            self.entity.extras['loc'] = self.__git_uri(app_uri_path)
Example #18
0
    def __create_app(self):

        # will generate an appname 24 chars long - compatible with v2 and v3
        # e.g. soandycd009b39c28790f3
        app_name = 'so' + self.entity.kind.term[0:4] + \
                   ''.join(random.choice('0123456789abcdef') for _ in range(16))
        heads = {'Content-Type': 'text/occi'}

        url = self.nburl + '/app/'

        if self.entity.extras['ops_version'] == 'v2':
            heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \
                                'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \
                                'small; scheme="http://schemas.openshift.com/template/app#"'
            heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name)
            LOG.debug('Ensuring SM SSH Key...')
            self.__ensure_ssh_key()
        elif self.entity.extras['ops_version'] == 'v3':

            # for OpSv3 bundle location is the repo id of the container image
            bundle_loc = CONFIG.get('service_manager', 'bundle_location', '')
            if bundle_loc == '':
                LOG.error('No bundle_location parameter supplied in sm.cfg')
                raise Exception('No bundle_location parameter supplied in sm.cfg')
            if bundle_loc.startswith('/'):
                LOG.warn('Bundle location does not look like an image reference!')
            LOG.debug('Bundle to execute: ' + bundle_loc)

            design_uri = CONFIG.get('service_manager', 'design_uri', '')
            if design_uri == '':
                raise Exception('No design_uri parameter supplied in sm.cfg')
            LOG.debug('Design URI: ' + design_uri)

            heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"'
            # TODO provide a means to provide additional docker env params
            attrs = 'occi.app.name="' + app_name + '", ' + \
                    'occi.app.image="' + bundle_loc + '", ' + \
                    'occi.app.env="DESIGN_URI=' + design_uri + '"'
            heads['X-OCCI-Attribute'] = str(attrs)
        else:
            LOG.error('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version'])
            raise Exception('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version'])

        LOG.debug('Requesting container to execute SO Bundle: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        r = http_retriable_request('POST', url, headers=heads, authenticate=True)

        loc = r.headers.get('Location', '')
        if loc == '':
            LOG.error("No OCCI Location attribute found in request")
            raise AttributeError("No OCCI Location attribute found in request")

        app_uri_path = urlparse(loc).path
        LOG.debug('SO container created: ' + app_uri_path)

        LOG.debug('Updating OCCI entity.identifier from: ' + self.entity.identifier + ' to: ' +
                  app_uri_path.replace('/app/', self.entity.kind.location))
        self.entity.identifier = app_uri_path.replace('/app/', self.entity.kind.location)

        LOG.debug('Setting occi.core.id to: ' + app_uri_path.replace('/app/', ''))
        self.entity.attributes['occi.core.id'] = app_uri_path.replace('/app/', '')

        # OpSv2 only: get git uri. this is where our bundle is pushed to
        # XXX this is fugly
        # TODO use the same name for the app URI
        if self.entity.extras['ops_version'] == 'v2':
            self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path)
        elif self.entity.extras['ops_version'] == 'v3':
            self.entity.extras['loc'] = self.__git_uri(app_uri_path)

            # wait until occi.app.state="active" - loop a GET
            # this may not be applicable to OpSv2
            LOG.info('checking: ' + loc)
            while not self.__is_complete(loc):
                time.sleep(3)