def __create_app(self):
        # name must be A-Za-z0-9 and <=32 chars
        app_name = self.entity.kind.term[0:4] + 'srvinst' + ''.join(random.choice('0123456789ABCDEF') for i in range(16))
        heads = {
            'Content-Type': 'text/occi',
            '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#"',
            'X-OCCI-Attribute': 'occi.app.name=' + app_name
            }

        url = self.nburl + '/app/'
        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 == '':
            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/', '')

        # get git uri. this is where our bundle is pushed to
        return self.__git_uri(app_uri_path)
Example #2
0
    def run(self):
        # 1. dispose the active SO, essentially kills the STG/ITG
        # 2. dispose the resources used to run the SO
        # example request to the SO
        # curl -v -X DELETE http://localhost:8051/orchestrator/default \
        #   -H 'X-Auth-Token: '$KID \
        #   -H 'X-Tenant-Name: '$TENANT

        self.start_time = time.time()
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'destroy',
            'phase_event': 'start',
            'response_time': 0,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute:'
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.info('Disposing service orchestrator with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('DELETE', url, headers=heads)

        url = self.nburl + self.entity.identifier.replace(
            '/' + self.entity.kind.term + '/', '/app/')
        heads = {
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        LOG.info('Disposing service orchestrator container via CC... ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('DELETE', url, headers=heads, authenticate=True)

        elapsed_time = time.time() - self.start_time
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'destroy',
            'phase_event': 'done',
            'response_time': elapsed_time,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        return self.entity, self.extras
Example #3
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 #4
0
    def deploy_complete(self, url):
        # XXX fugly - code copied from Resolver
        heads = {
            'Content-type': 'text/occi',
            'Accept': 'application/occi+json',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
        }

        LOG.info('checking service state at: ' + url)
        LOG.info('sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            stack_state = ''
            try:
                stack_state = attr_hash['occi.mcn.stack.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(stack_state))
            if stack_state == 'CREATE_COMPLETE' or stack_state == 'UPDATE_COMPLETE':
                LOG.info('Stack is ready')
                return True
            elif stack_state == 'CREATE_FAILED':
                raise RuntimeError('Heat stack creation failed.')
            else:
                LOG.info('Stack is not ready. Current state state: ' + stack_state)
                return False
Example #5
0
    def __init_so(self):
        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Category': 'orchestrator; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
            'X-OCCI-Attribute': 'occi.mcn.app.url="' + HTTP + self.host + '/orchestrator/default"'
        }

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute: ' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Initialising SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('PUT', url, headers=heads)
        elapsed_time = time.time() - self.start_time
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'activate',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
Example #6
0
    def run(self):
        # Deployment is done without any control by the client...
        # otherwise we won't be able to hand back a working service!
        LOG.debug('Deploying the SO bundle...')
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'deploy'}
        heads = {
            'Category':
            'deploy; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute:'
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Deploying SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        self.entity.attributes['mcn.service.state'] = 'deploy'
        LOG.debug('SO Deployed ')
        return self.entity, self.extras
Example #7
0
    def register_service(self):

        self.srv_ep = util.services.get_service_endpoint(identifier=self.srv_type.term, token=self.token,
                                                         endpoint=self.design_uri, tenant_name=self.tenant_name,
                                                         url_type='public')

        if self.srv_ep is None or self.srv_ep == '':
            LOG.debug('Registering the service with the keystone service...')

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

            # taken from the kind definition
            self.srv_ep = keystone.services.create(
                self.srv_type.scheme+self.srv_type.term,
                self.srv_type.scheme+self.srv_type.term,
                self.srv_type.title)

            internal_url = admin_url = public_url = self.service_endpoint

            self.ep = keystone.endpoints.create(self.region, self.srv_ep.id, public_url, admin_url, internal_url)
            LOG.info('Service is now registered with keystone: ' +
                     'Region: ' + self.ep.region +
                     ' Public URL:' + self.ep.publicurl +
                     ' Service ID: ' + self.srv_ep.id +
                     ' Endpoint ID: ' + self.ep.id)
        else:
            LOG.info('Service is already registered with keystone. Service endpoint is: ' + self.srv_ep)
Example #8
0
    def run(self):
        # 1. dispose the active SO, essentially kills the STG/ITG
        # 2. dispose the resources used to run the SO
        # example request to the SO
        # curl -v -X DELETE http://localhost:8051/orchestrator/default \
        #   -H 'X-Auth-Token: '$KID \
        #   -H 'X-Tenant-Name: '$TENANT
        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute:'
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.info('Disposing service orchestrator with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('DELETE', url, headers=heads)

        url = self.nburl + self.entity.identifier.replace(
            '/' + self.entity.kind.term + '/', '/app/')
        heads = {
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        LOG.info('Disposing service orchestrator container via CC... ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('DELETE', url, headers=heads, authenticate=True)

        return self.entity, self.extras
Example #9
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 #10
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))
    def run(self):
        # 1. dispose the active SO, essentially kills the STG/ITG
        # 2. dispose the resources used to run the SO
        # example request to the SO
        # curl -v -X DELETE http://localhost:8051/orchestrator/default \
        #   -H 'X-Auth-Token: '$KID \
        #   -H 'X-Tenant-Name: '$TENANT
        url = HTTP + self.host + '/orchestrator/default'
        heads = {'X-Auth-Token': self.extras['token'],
                 'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.info('Disposing service orchestrator with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('DELETE', url, headers=heads)

        url = self.nburl + self.entity.identifier.replace('/' + self.entity.kind.term + '/', '/app/')
        heads = {'Content-Type': 'text/occi',
                 'X-Auth-Token': self.extras['token'],
                 'X-Tenant-Name': self.extras['tenant_name']}
        LOG.info('Disposing service orchestrator container via CC... ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('DELETE', url, headers=heads, authenticate=True)

        return self.entity, self.extras
Example #12
0
    def __git_uri(self, app_uri_path):
        url = self.nburl + app_uri_path
        headers = {'Accept': 'text/occi'}
        LOG.debug('Requesting container\'s URL ' + url)
        LOG.info('Sending headers: ' + headers.__repr__())
        r = http_retriable_request('GET',
                                   url,
                                   headers=headers,
                                   authenticate=True)

        attrs = r.headers.get('X-OCCI-Attribute', '')
        if attrs == '':
            raise AttributeError("No occi attributes found in request")

        repo_uri = ''
        for attr in attrs.split(', '):
            if attr.find('occi.app.repo') != -1:
                repo_uri = attr.split('=')[1][
                    1:-1]  # scrubs trailing wrapped quotes
                break
            elif attr.find('occi.app.url') != -1:
                repo_uri = attr.split('=')[1][
                    1:-1]  # scrubs trailing wrapped quotes
                break
        if repo_uri == '':
            raise AttributeError(
                "No occi.app.repo or occi.app.url attribute found in request")

        LOG.debug('SO container URL: ' + repo_uri)

        return repo_uri
Example #13
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 #14
0
    def __init_so(self):
        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Category':
            'orchestrator; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
        }

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute: '
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Initialising SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('PUT', url, headers=heads)
        elapsed_time = time.time() - self.start_time
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'activate',
            'phase_event': 'done',
            'response_time': elapsed_time,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
Example #15
0
    def run(self):
        # this can only run until the deployment has complete!
        # this will block until run() returns

        url = HTTP + self.host + '/orchestrator/default'

        # with stuff like this, we need to have a callback mechanism... this will block otherwise
        while not self.deploy_complete(url):
            time.sleep(13)

        params = {'action': 'provision'}
        heads = {
            'Category': 'provision; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute: ' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Provisioning SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        self.entity.attributes['mcn.service.state'] = 'provision'
        return self.entity, self.extras
Example #16
0
    def __is_complete(self, url):
        # XXX copy/paste code - merge the two places!
        heads = {
                'Content-type': 'text/occi',
                'Accept': 'application/occi+json',
                'X-Auth-Token': self.extras['token'],
                'X-Tenant-Name': self.extras['tenant_name'],
            }

        LOG.info('Checking app state at: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads, authenticate=True)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            app_state = ''
            try:
                app_state = attr_hash['occi.app.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(app_state))
            if app_state == 'active':
                LOG.info('App is ready')
                return True
            else:
                LOG.info('App is not ready. Current state state: ' + app_state)
                return False
Example #17
0
    def deploy_complete(self, url):
        # XXX fugly - code copied from Resolver
        heads = {
            'Content-type': 'text/occi',
            'Accept': 'application/occi+json',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
        }

        LOG.info('checking service state at: ' + url)
        LOG.info('sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            stack_state = ''
            try:
                stack_state = attr_hash['occi.mcn.stack.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(stack_state))
            if stack_state == 'CREATE_COMPLETE' or stack_state == 'UPDATE_COMPLETE':
                LOG.info('Stack is ready')
                return True
            elif stack_state == 'CREATE_FAILED':
                raise RuntimeError('Heat stack creation failed.')
            else:
                LOG.info('Stack is not ready. Current state state: ' +
                         stack_state)
                return False
Example #18
0
    def __git_uri(self, app_uri_path):
        url = self.nburl + app_uri_path
        headers = {'Accept': 'text/occi'}
        LOG.debug('Requesting container\'s URL ' + url)
        LOG.info('Sending headers: ' + headers.__repr__())
        r = http_retriable_request('GET', url, headers=headers, authenticate=True)

        attrs = r.headers.get('X-OCCI-Attribute', '')
        if attrs == '':
            raise AttributeError("No occi attributes found in request")

        repo_uri = ''
        for attr in attrs.split(', '):
            if attr.find('occi.app.repo') != -1:
                repo_uri = attr.split('=')[1][1:-1]  # scrubs trailing wrapped quotes
                break
            elif attr.find('occi.app.url') != -1:
                repo_uri = attr.split('=')[1][1:-1]  # scrubs trailing wrapped quotes
                break
        if repo_uri == '':
            raise AttributeError("No occi.app.repo or occi.app.url attribute found in request")

        LOG.debug('SO container URL: ' + repo_uri)

        return repo_uri
Example #19
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 #20
0
    def run(self):
        # Deployment is done without any control by the client...
        # otherwise we won't be able to hand back a working service!
        #LOG.debug('DEPLOY SO START')

        self.start_time = time.time()
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'deploy',
            'phase_event': 'start',
            'response_time': 0,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        #LOG.debug('Deploying the SO bundle...')
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'deploy'}
        heads = {
            'Category':
            'deploy; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute:'
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Deploying SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        # also sleep here to keep phases consistent during greenfield
        while not self.deploy_complete(url):
            time.sleep(7)

        self.entity.attributes['mcn.service.state'] = 'deploy'
        LOG.debug('SO Deployed ')
        elapsed_time = time.time() - self.start_time
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'deploy',
            'phase_event': 'done',
            'response_time': elapsed_time,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
        #LOG.debug('DEPLOY SO DONE, elapsed: %f' % elapsed_time)
        return self.entity, self.extras
Example #21
0
    def run(self):
        # this can only run until the deployment has complete!
        # this will block until run() returns
        #LOG.debug('PROVISION SO START')

        self.start_time = time.time()
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'provision',
            'phase_event': 'start',
            'response_time': 0,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'

        # with stuff like this, we need to have a callback mechanism... this will block otherwise
        while not self.deploy_complete(url):
            time.sleep(13)

        params = {'action': 'provision'}
        heads = {
            'Category':
            'provision; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute: '
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Provisioning SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        elapsed_time = time.time() - self.start_time
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'provision',
            'phase_event': 'done',
            'response_time': elapsed_time,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
        #LOG.debug('PROVISION SO DONE, elapsed: %f' % elapsed_time)
        self.entity.attributes['mcn.service.state'] = 'provision'
        return self.entity, self.extras
Example #22
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 #23
0
    def run(self):
        # 1. dispose the active SO, essentially kills the STG/ITG
        # 2. dispose the resources used to run the SO
        # example request to the SO
        # curl -v -X DELETE http://localhost:8051/orchestrator/default \
        #   -H 'X-Auth-Token: '$KID \
        #   -H 'X-Tenant-Name: '$TENANT

        self.start_time = time.time()
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'destroy',
                    'phase_event': 'start',
                    'response_time': 0,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'
        heads = {'X-Auth-Token': self.extras['token'],
                 'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.info('Disposing service orchestrator with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('DELETE', url, headers=heads)

        url = self.nburl + self.entity.identifier.replace('/' + self.entity.kind.term + '/', '/app/')
        heads = {'Content-Type': 'text/occi',
                 'X-Auth-Token': self.extras['token'],
                 'X-Tenant-Name': self.extras['tenant_name']}
        LOG.info('Disposing service orchestrator container via CC... ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('DELETE', url, headers=heads, authenticate=True)

        elapsed_time = time.time() - self.start_time
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'destroy',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        return self.entity, self.extras
Example #24
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 #25
0
    def run(self):
        # Deployment is done without any control by the client...
        # otherwise we won't be able to hand back a working service!
        #LOG.debug('DEPLOY SO START')

        self.start_time = time.time()
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'deploy',
                    'phase_event': 'start',
                    'response_time': 0,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        #LOG.debug('Deploying the SO bundle...')
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'deploy'}
        heads = {
            'Category': 'deploy; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Deploying SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        # also sleep here to keep phases consistent during greenfield
        while not self.deploy_complete(url):
                    time.sleep(7)

        self.entity.attributes['mcn.service.state'] = 'deploy'
        LOG.debug('SO Deployed ')
        elapsed_time = time.time() - self.start_time
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'deploy',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
        #LOG.debug('DEPLOY SO DONE, elapsed: %f' % elapsed_time)
        return self.entity, self.extras
Example #26
0
    def run(self):
        # this can only run until the deployment has complete!
        # this will block until run() returns
        #LOG.debug('PROVISION SO START')

        self.start_time = time.time()
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'provision',
                    'phase_event': 'start',
                    'response_time': 0,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'

        # with stuff like this, we need to have a callback mechanism... this will block otherwise
        while not self.deploy_complete(url):
            time.sleep(13)

        params = {'action': 'provision'}
        heads = {
            'Category': 'provision; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute: ' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Provisioning SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        elapsed_time = time.time() - self.start_time
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'provision',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)
        #LOG.debug('PROVISION SO DONE, elapsed: %f' % elapsed_time)
        self.entity.attributes['mcn.service.state'] = 'provision'
        return self.entity, self.extras
Example #27
0
def deploy_complete(url, start_time, extras, entity):

    done = False

    while done == False:
        # XXX fugly - code copied from Resolver
        heads = {
            'Content-type': 'text/occi',
            'Accept': 'application/occi+json',
            'X-Auth-Token': extras['token'],
            'X-Tenant-Name': extras['tenant_name'],
        }

        LOG.info('checking service state at: ' + url)
        LOG.info('sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            stack_state = ''
            try:
                stack_state = attr_hash['occi.mcn.stack.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(stack_state))
            if stack_state == 'CREATE_COMPLETE' or stack_state == 'UPDATE_COMPLETE':
                LOG.info('Stack is ready')
                elapsed_time = time.time() - start_time
                infoDict = {
                    'so_id': entity.attributes['occi.core.id'],
                    'sm_name': entity.kind.term,
                    'so_phase': 'update',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': extras['tenant_name']
                }
                tmpJSON = json.dumps(infoDict)
                LOG.debug(tmpJSON)
                done = True
            else:
                LOG.info('Stack is not ready. Current state state: ' +
                         stack_state)
                done = False
                time.sleep(3)
Example #28
0
    def __init_so(self):
        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Category': 'orchestrator; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
        }

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute: ' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Initialising SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('PUT', url, headers=heads)
Example #29
0
def deploy_complete(url, start_time, extras, entity):

    done = False

    while done == False:
        # XXX fugly - code copied from Resolver
        heads = {
            'Content-type': 'text/occi',
            'Accept': 'application/occi+json',
            'X-Auth-Token': extras['token'],
            'X-Tenant-Name': extras['tenant_name'],
        }

        LOG.info('checking service state at: ' + url)
        LOG.info('sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            stack_state = ''
            try:
                stack_state = attr_hash['occi.mcn.stack.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(stack_state))
            if stack_state == 'CREATE_COMPLETE' or stack_state == 'UPDATE_COMPLETE':
                LOG.info('Stack is ready')
                elapsed_time = time.time() - start_time
                infoDict = {
                    'so_id': entity.attributes['occi.core.id'],
                    'sm_name': entity.kind.term,
                    'so_phase': 'update',
                    'phase_event': 'done',
                    'response_time': elapsed_time,
                    'tenant': extras['tenant_name']
                    }
                tmpJSON = json.dumps(infoDict)
                LOG.debug(tmpJSON)
                done = True
            else:
                LOG.info('Stack is not ready. Current state state: ' + stack_state)
                done = False
                time.sleep(3)
    def run(self):
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'provision'}
        heads = {
            'Category': 'provision; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute: ' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Provisioning SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        self.entity.attributes['mcn.service.state'] = 'provision'
        return self.entity, self.extras
Example #31
0
    def __create_app(self):
        # name must be A-Za-z0-9 and <=32 chars
        app_name = self.entity.kind.term[0:4] + 'srvinst' + ''.join(
            random.choice('0123456789ABCDEF') for i in range(16))
        heads = {
            'Content-Type':
            'text/occi',
            '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#"',
            'X-OCCI-Attribute':
            'occi.app.name=' + app_name
        }

        url = self.nburl + '/app/'
        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 == '':
            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/', '')

        # get git uri. this is where our bundle is pushed to
        return self.__git_uri(app_uri_path)
Example #32
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 #33
0
    def run(self):
        # take parameters from EEU and send them down to the SO instance
        # Trigger update on SO + service instance:
        #
        # $ curl -v -X POST http://localhost:8051/orchestrator/default \
        #       -H 'Content-Type: text/occi' \
        #       -H 'X-Auth-Token: '$KID \
        #       -H 'X-Tenant-Name: '$TENANT \
        #       -H 'X-OCCI-Attribute: occi.epc.attr_1="foo"'
        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)

        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        if len(self.new.attributes) > 0:
            LOG.info('Adding updated parameters... X-OCCI-Attribute: ' + self.new.attributes.__repr__())
            for k, v in self.new.attributes.items():
                occi_attrs = occi_attrs + ', ' + k + '=' + v
                self.entity.attributes[k] = v
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Updating (Provisioning) SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('POST', url, headers=heads)

        self.entity.attributes['mcn.service.state'] = 'update'
        return self.entity, self.extras
    def run(self):
        # Deployment is done without any control by the client...
        # otherwise we won't be able to hand back a working service!
        LOG.debug('Deploying the SO bundle...')
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'deploy'}
        heads = {
            'Category': 'deploy; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Deploying SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        self.entity.attributes['mcn.service.state'] = 'deploy'
        LOG.debug('SO Deployed ')
        return self.entity, self.extras
Example #35
0
    def run(self):
        url = HTTP + self.host + '/orchestrator/default'
        params = {'action': 'provision'}
        heads = {
            'Category':
            'provision; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"',
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }
        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)
        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute: '
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs
        LOG.debug('Provisioning SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())
        http_retriable_request('POST', url, headers=heads, params=params)

        self.entity.attributes['mcn.service.state'] = 'provision'
        return self.entity, self.extras
Example #36
0
    def run(self):
        # take parameters from EEU and send them down to the SO instance
        # Trigger update on SO + service instance:
        #
        # $ curl -v -X POST http://localhost:8051/orchestrator/default \
        #       -H 'Content-Type: text/occi' \
        #       -H 'X-Auth-Token: '$KID \
        #       -H 'X-Tenant-Name: '$TENANT \
        #       -H 'X-OCCI-Attribute: occi.epc.attr_1="foo"'

        self.start_time = time.time()
        infoDict = {
            'so_id': self.entity.attributes['occi.core.id'],
            'sm_name': self.entity.kind.term,
            'so_phase': 'update',
            'phase_event': 'start',
            'response_time': 0,
            'tenant': self.extras['tenant_name']
        }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']
        }

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)

        if len(occi_attrs) > 0:
            LOG.info(
                'Adding service-specific parameters to call... X-OCCI-Attribute:'
                + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        if len(self.new.attributes) > 0:
            LOG.info('Adding updated parameters... X-OCCI-Attribute: ' +
                     self.new.attributes.__repr__())
            for k, v in self.new.attributes.items():
                occi_attrs = occi_attrs + ', ' + k + '=' + v
                self.entity.attributes[k] = v
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Updating (Provisioning) SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('POST', url, headers=heads)

        self.entity.attributes['mcn.service.state'] = 'update'

        #start thread here
        thread = Thread(target=deploy_complete,
                        args=(url, self.start_time, self.extras, self.entity))
        thread.start()

        return self.entity, self.extras
Example #37
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 #38
0
    def run(self):
        # take parameters from EEU and send them down to the SO instance
        # Trigger update on SO + service instance:
        #
        # $ curl -v -X POST http://localhost:8051/orchestrator/default \
        #       -H 'Content-Type: text/occi' \
        #       -H 'X-Auth-Token: '$KID \
        #       -H 'X-Tenant-Name: '$TENANT \
        #       -H 'X-OCCI-Attribute: occi.epc.attr_1="foo"'

        self.start_time = time.time()
        infoDict = {
                    'so_id': self.entity.attributes['occi.core.id'],
                    'sm_name': self.entity.kind.term,
                    'so_phase': 'update',
                    'phase_event': 'start',
                    'response_time': 0,
                    'tenant': self.extras['tenant_name']
                    }
        tmpJSON = json.dumps(infoDict)
        LOG.debug(tmpJSON)

        url = HTTP + self.host + '/orchestrator/default'
        heads = {
            'Content-Type': 'text/occi',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name']}

        occi_attrs = self.extras['srv_prms'].service_parameters(self.state)

        if len(occi_attrs) > 0:
            LOG.info('Adding service-specific parameters to call... X-OCCI-Attribute:' + occi_attrs)
            heads['X-OCCI-Attribute'] = occi_attrs

        if len(self.new.attributes) > 0:
            LOG.info('Adding updated parameters... X-OCCI-Attribute: ' + self.new.attributes.__repr__())
            for k, v in self.new.attributes.items():
                occi_attrs = occi_attrs + ', ' + k + '=' + v
                self.entity.attributes[k] = v
            heads['X-OCCI-Attribute'] = occi_attrs

        LOG.debug('Updating (Provisioning) SO with: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        http_retriable_request('POST', url, headers=heads)

        self.entity.attributes['mcn.service.state'] = 'update'

        #start thread here
        thread = Thread(target = deploy_complete, args = (url, self.start_time, self.extras, self.entity ))
        thread.start()

        return self.entity, self.extras
Example #39
0
 def __detect_ops_version(self):
     # make a call to the cloud controller and based on the app kind, heuristically select version
     version = 'v2'
     heads = {
         'Content-Type': 'text/occi',
         'Accept': 'text/occi'
         }
     url = self.nburl + '/-/'
     LOG.debug('Requesting CC Query Interface: ' + url)
     LOG.info('Sending headers: ' + heads.__repr__())
     r = http_retriable_request('GET', url, headers=heads, authenticate=True)
     if r.headers['category'].find('occi.app.image') > -1 and r.headers['category'].find('occi.app.env') > -1:
         LOG.info('Found occi.app.image and occi.app.env - this is OpenShift V3')
         version = 'v3'
     else:
         LOG.info('This is OpenShift V2')
     return version
Example #40
0
 def __detect_ops_version(self):
     # make a call to the cloud controller and based on the app kind, heuristically select version
     version = 'v2'
     heads = {
         'Content-Type': 'text/occi',
         'Accept': 'text/occi'
         }
     url = self.nburl + '/-/'
     LOG.debug('Requesting CC Query Interface: ' + url)
     LOG.info('Sending headers: ' + heads.__repr__())
     r = http_retriable_request('GET', url, headers=heads, authenticate=True)
     if r.headers['category'].find('occi.app.image') > -1 and r.headers['category'].find('occi.app.env') > -1:
         LOG.info('Found occi.app.image and occi.app.env - this is OpenShift V3')
         version = 'v3'
     else:
         LOG.info('This is OpenShift V2')
     return version
Example #41
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 #42
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)
    def __get_heat_template(self, attributes):
        randomstring = "-"+str(uuid.uuid1())

        # this function will return the first of following values in the order
        # of occurrence:
        #   - given by the user during instantiation
        #   - set as a default value in the config file
        #   - an empty string
        def getAttr(attrName):
            if(attrName in attributes):
                return attributes[attrName]
            else:
                try:
                    retVal = config.get('cluster',attrName)
                    return retVal
                except:
                    return ""

        # the rootFolder is needed in order to load the config files
        self.rootFolder = CONFIG.get('disco','root_folder')
        if self.rootFolder=="":
            # if no rootFolder has been provided, take the path it's located
            # within the Docker image
            self.rootFolder = "data/"

        # setup parser for config file
        config = ConfigParser.RawConfigParser()
        config.read(os.path.join(self.rootFolder,'defaultSettings.cfg'))

        LOG.info("deploying stack...")

        # the needed variables for the Heat Orchestration Template will be set
        # on the following lines; the function getAttr() is returning the
        # appropriate value. As an empty value cannot be used for int/float
        # conversion, they have to be set within a try-except block.
        slaveCount = 1
        try:
            slaveCount = int(getAttr('icclab.haas.slave.number'))
        except:
            pass
        masterImage = getAttr('icclab.haas.master.image')
        slaveImage = getAttr('icclab.haas.slave.image')
        masterFlavor = getAttr('icclab.haas.master.flavor')
        slaveFlavor = getAttr('icclab.haas.slave.flavor')
        slaveOnMaster = True #getAttr('icclab.haas.master.slaveonmaster').lower() in ['true', '1']
        SSHPublicKeyName = getAttr('icclab.haas.master.sshkeyname')
        SSHMasterPublicKey = getAttr('icclab.haas.master.publickey')
        withFloatingIP = getAttr('icclab.haas.master.withfloatingip').lower() in ['true','1']
        master_name = getAttr('icclab.haas.master.name')+randomstring
        slave_name = getAttr('icclab.haas.slave.name')+randomstring+"-"
        subnet_cidr = getAttr('icclab.haas.network.subnet.cidr')
        subnet_gw_ip = getAttr('icclab.haas.network.gw.ip')
        subnet_allocation_pool_start = getAttr('icclab.haas.network.subnet.allocpool.start')
        subnet_allocation_pool_end = getAttr('icclab.haas.network.subnet.allocpool.end')
        subnet_dns_servers = getAttr('icclab.haas.network.dnsservers')
        image_id = getAttr('icclab.haas.master.imageid')
        floatingIpId = getAttr('icclab.haas.master.attachfloatingipwithid')

        externalNetwork = getAttr('icclab.haas.network.external')

        noDeployment = getAttr('icclab.haas.debug.donotdeploy').lower() in ['true','1']
        saveToLocalPath = getAttr('icclab.haas.debug.savetemplatetolocalpath')

        diskId = 'virtio-'+image_id[0:20]

        # masterSSHKeyEntry = ''

        def getFileContent(fileName):
            f = open(os.path.join(self.rootFolder, fileName))
            retVal = f.read()
            f.close()
            return retVal

        # read all the necessary files for creating the Heat template
        clusterTemplate = getFileContent("cluster.yaml");
        slaveTemplate = getFileContent("slave.yaml")
        masterBash = getFileContent("master_bash.sh")
        master_id_rsa = getFileContent("master.id_rsa").replace("\n","\\n")
        master_id_rsa_pub = getFileContent("master.id_rsa.pub").replace("\n","")
        yarn_site_xml = getFileContent("yarn-site.xml")
        core_site_xml = getFileContent("core-site.xml")
        mapred_site_xml = getFileContent("mapred-site.xml")
        hdfs_site_xml = getFileContent("hdfs-site.xml")
        hadoop_env_sh = getFileContent("hadoop-env.sh")
        jupyter_notebook_config_py = getFileContent("jupyter_notebook_config.py")

        slaves = ""
        hostFileContent = ""
        forLoopSlaves = ""
        paramsSlave = ""
        slavesFile = ""
        hostsListFile = ""


        slaveTemplate = slaveTemplate.replace("$master.id_rsa.pub$",master_id_rsa_pub)
        for i in xrange(1,slaveCount+1):
            slaves += slaveTemplate.replace("$slavenumber$",str(i))
            hostFileContent += "$slave"+str(i)+"address$\t"+slave_name+str(i)+"\n"
            forLoopSlaves += " $slave"+str(i)+"address$"
            paramsSlave += "            $slave"+str(i)+"address$: { get_attr: [hadoop_slave_"+str(i)+", first_address] }\n"
            slavesFile += slave_name+str(i)+"\n"
            hostsListFile += "$slave"+str(i)+"address$\n"

        # In the following section, the master's public SSH key will be setup.
        # This is done the following way: if no key name was provided for an
        # existing public SSH key, the same key will be used as was used for
        # the slaves as well. If a key name was provided but no public SSH key,
        # it's assumed that an existing public key is already registered in
        # keystone which should be used. If a key name and a public SSH key are
        # provided, a new public key entry will be created in keystone with the
        # give public key and the given name.
        masterSSHKeyResource = ""
        insertMasterPublicKey = ""
        if SSHPublicKeyName=="":
            masterSSHKeyEntry = "{ get_resource: sshpublickey }"
        else:
            insertMasterPublicKey = "su ubuntu -c \"cat /home/ubuntu/.ssh/id_rsa.pub >> /home/ubuntu/.ssh/authorized_keys\"\n"
            if SSHMasterPublicKey=="":
                masterSSHKeyEntry = SSHPublicKeyName
            else:
                masterSSHKeyResource = "  users_public_key:\n" \
                                       "    type: OS::Nova::KeyPair\n" \
                                       "    properties:\n" \
                                       "      name: " + SSHPublicKeyName + "\n" \
                                       "      public_key: " + SSHMasterPublicKey + "\n\n"
                masterSSHKeyEntry = "{ get_resource: users_public_key }"

        # if master has to act as a slave as well, set variable accordingly
        masterasslave = ""
        if slaveOnMaster==True:
            masterasslave = master_name+"\n"

        # setup bash script for master (write replace{r,e}s into dictionary and
        # replace them one by one
        replaceDict = { "$master.id_rsa$": master_id_rsa,
                        "$master.id_rsa.pub$": master_id_rsa_pub,
                        "$yarn-site.xml$": yarn_site_xml,
                        "$core-site.xml$": core_site_xml,
                        "$mapred-site.xml$": mapred_site_xml,
                        "$hdfs-site.xml$": hdfs_site_xml,
                        "$hadoop-env.sh$": hadoop_env_sh,
                        "$masternodeasslave$": masterasslave,
                        "$slavesfile$": slavesFile,
                        "$hostsfilecontent$": hostFileContent,
                        "$forloopslaves$": forLoopSlaves,
                        "$for_loop_slaves$": hostsListFile,
                        "$insert_master_pub_key$": insertMasterPublicKey,
                        "$disk_id$": diskId,
                        "$jupyter_notebook_config.py$": jupyter_notebook_config_py
                        }
        for key, value in replaceDict.iteritems():
            masterBash = masterBash.replace(key, value)

        # add some spaces in front of each line because the bash script has to
        # be indented within the Heat template
        masterBashLines = masterBash.splitlines(True)
        masterbash = ""
        for line in masterBashLines:
            masterbash += ' '*14+line

        # does the user want to have a floating IP created?
        floatingIpResource = ""
        floatingIpAssoc = ""
        externalIpOutput = ""

        # if a floating IP is to be setup for the master, the variables have to be set accordingly
        if True == withFloatingIP:
            ipid = floatingIpId
            floatingIpAssoc = "  floating_ip_assoc:\n" \
                              "    type: OS::Neutron::FloatingIPAssociation\n" \
                              "    properties:\n" \
                              "      floatingip_id: "
            if floatingIpId=="":
                floatingIpResource = "  hadoop_ip:\n" \
                                     "    type: OS::Neutron::FloatingIP\n" \
                                     "    properties:\n" \
                                     "      floating_network: \""+externalNetwork+"\"\n\n"
                floatingIpAssoc += "{ get_resource: hadoop_ip }"
                externalIpOutput = "  external_ip:\n" \
                                   "    description: The IP address of the deployed master node\n" \
                                   "    value: { get_attr: [ hadoop_ip, floating_ip_address ] }\n\n"
            else:
                floatingIpAssoc = floatingIpAssoc+floatingIpId
            floatingIpAssoc += "\n      port_id: { get_resource: hadoop_port }\n\n"


        memVals = self.__get_hadoop_memory_values(slaveFlavor)


        # the cluster's heat template will have to be configured
        replaceDict = {"$master_bash.sh$": masterbash,
                       "$paramsslave$": paramsSlave,
                       "$slaves$": slaves,
                       "$master_image$": masterImage,
                       "$slave_image$": slaveImage,
                       "$masternode$": master_name,
                       "$slavenode$": slave_name,
                       "$master_flavor$": masterFlavor,
                       "$slave_flavor$": slaveFlavor,
                       "$master_ssh_key_entry$": masterSSHKeyEntry,
                       "$users_ssh_public_key$": masterSSHKeyResource,
                       "$floating_ip_resource$": floatingIpResource,
                       "$floating_ip_assoc$": floatingIpAssoc,
                       "$external_ip_output$": externalIpOutput,
                       "$subnet_cidr$": subnet_cidr,
                       "$subnet_gw_ip$": subnet_gw_ip,
                       "$subnet_allocation_pool_start$":
                           subnet_allocation_pool_start,
                       "$subnet_allocation_pool_end$":
                           subnet_allocation_pool_end,
                       "$subnet_dns_servers$": subnet_dns_servers,
                       "$ssh_cluster_pub_key$": "ssh_pub_key_"+randomstring,
                       "$hadoop_security_group$": "security_group_"+randomstring,
                        "$network_name$": "network_"+randomstring,
                       "$external_network$": externalNetwork

                    }

        # do basic configuration
        for key, value in replaceDict.iteritems():
            clusterTemplate = clusterTemplate.replace(key, value)

        # insert memory values
        for key, value in memVals.iteritems():
            clusterTemplate = clusterTemplate.replace(key, str(value))

        # for debugging purposes, the template can be saved locally
        if saveToLocalPath is not "":
            try:
                f = open( saveToLocalPath,"w")
                f.write(clusterTemplate)
                f.close()
            except:
                LOG.info("Couldn't write to location "+saveToLocalPath)

        # debug output should be implemented as a parameter
        #   LOG.debug(clusterTemplate)
        # self.deployTemplate = clusterTemplate

        # deploy the created template
        if not noDeployment:
            return clusterTemplate
Example #44
0
 def shutdown_handler(self, signum=None, frame=None):
     LOG.info('Service shutting down... ')
     if not self.DEBUG:
         ioloop.IOLoop.instance().add_callback(self.deregister_service())
     else:
         self.deregister_service()
Example #45
0
 def shutdown_handler(self, signum = None, frame = None):
     LOG.info('Service shutting down... ')
     if self.reg_srv:
         self.deregister_service()
     sys.exit(0)
Example #46
0
 def shutdown_handler(self, signum=None, frame=None):
     LOG.info("Service shutting down... ")
     if self.reg_srv:
         self.deregister_service()
     sys.exit(0)
Example #47
0
    def __is_complete(self, url):
        # XXX copy/paste code - merge the two places!
        heads = {
                'Content-type': 'text/occi',
                'Accept': 'application/occi+json',
                'X-Auth-Token': self.extras['token'],
                'X-Tenant-Name': self.extras['tenant_name'],
            }

        LOG.info('Checking app state at: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET', url, headers=heads, authenticate=True)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            app_state = ''
            try:
                app_state = attr_hash['occi.app.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(app_state))
            if app_state == 'active':
                # check if it returns something valid instead of 503
                try:
                    tmpUrl = 'http://' + attr_hash['occi.app.url']
                except KeyError:
                    LOG.info(('App is not ready. app url is not yet set.'))
                    return False
                r = http_retriable_request('GET', tmpUrl, headers=heads, authenticate=True)
                if r.status_code == 200:
                    LOG.info('App is ready')
                    elapsed_time = time.time() - self.extras['occi.init.starttime']
                    del self.extras['occi.init.starttime']

                    infoDict = {
                                'so_id': self.entity.attributes['occi.core.id'],
                                'sm_name': self.entity.kind.term,
                                'so_phase': 'init',
                                'phase_event': 'done',
                                'response_time': elapsed_time,
                                'tenant': self.extras['tenant_name']
                                }
                    tmpJSON = json.dumps(infoDict)
                    LOG.debug(tmpJSON)
                    return True
                else:
                    LOG.info('App is not ready. app url returned: ' + r.status_code)
            else:
                LOG.info('App is not ready. Current state state: ' + app_state)
                return False
Example #48
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 #49
0
    def __is_complete(self, url):
        # XXX copy/paste code - merge the two places!
        heads = {
            'Content-type': 'text/occi',
            'Accept': 'application/occi+json',
            'X-Auth-Token': self.extras['token'],
            'X-Tenant-Name': self.extras['tenant_name'],
        }

        LOG.info('Checking app state at: ' + url)
        LOG.info('Sending headers: ' + heads.__repr__())

        r = http_retriable_request('GET',
                                   url,
                                   headers=heads,
                                   authenticate=True)
        attrs = json.loads(r.content)

        if len(attrs['attributes']) > 0:
            attr_hash = attrs['attributes']
            app_state = ''
            try:
                app_state = attr_hash['occi.app.state']
            except KeyError:
                pass

            LOG.info('Current service state: ' + str(app_state))
            if app_state == 'active':
                # check if it returns something valid instead of 503
                try:
                    tmpUrl = 'http://' + attr_hash['occi.app.url']
                except KeyError:
                    LOG.info(('App is not ready. app url is not yet set.'))
                    return False
                r = http_retriable_request('GET',
                                           tmpUrl,
                                           headers=heads,
                                           authenticate=True)
                if r.status_code == 200:
                    LOG.info('App is ready')
                    elapsed_time = time.time(
                    ) - self.extras['occi.init.starttime']
                    del self.extras['occi.init.starttime']

                    infoDict = {
                        'so_id': self.entity.attributes['occi.core.id'],
                        'sm_name': self.entity.kind.term,
                        'so_phase': 'init',
                        'phase_event': 'done',
                        'response_time': elapsed_time,
                        'tenant': self.extras['tenant_name']
                    }
                    tmpJSON = json.dumps(infoDict)
                    LOG.debug(tmpJSON)
                    return True
                else:
                    LOG.info('App is not ready. app url returned: ' +
                             r.status_code)
            else:
                LOG.info('App is not ready. Current state state: ' + app_state)
                return False
Example #50
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)