def get_service_credentials(self): token = CONFIG.get("service_manager_admin", "service_token", "") if token == "": raise Exception("No service_token parameter supplied in sm.cfg") tenant_name = CONFIG.get("service_manager_admin", "service_tenant_name", "") if tenant_name == "": raise Exception("No tenant_name parameter supplied in sm.cfg") return token, tenant_name
def get_service_credentials(self): token = CONFIG.get('service_manager_admin', 'service_token', '') if token == '': raise Exception('No service_token parameter supplied in sm.cfg') tenant_name = CONFIG.get('service_manager_admin', 'service_tenant_name', '') if tenant_name == '': raise Exception('No tenant_name parameter supplied in sm.cfg') return token, tenant_name
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)
def run(self): LOG.debug("running retrieve") self.start_time = time.time() infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'retrieve', 'phase_event': 'start', 'response_time': 0, } LOG.debug(json.dumps(infoDict)) self.entity.attributes['mcn.service.state'] = 'retrieve' argument = { 'design_uri': CONFIG.get('service_manager', 'design_uri', ''), 'username': self.entity.attributes['icclab.disco.deployer.username'], 'tenant_name': self.extras['tenant_name'], 'password': self.entity.attributes['icclab.disco.deployer.password'], 'stack_name': 'disco_' + str(uuid.uuid1()), 'region': self.entity.attributes['icclab.disco.deployer.region'], 'token': self.extras['token'] } deployer = OpenstackDeployer(argument) framework_directory = CONFIG.get('disco','framework_directory','') disco_config = {"deployer": deployer, "framework_directory": framework_directory, "root_component": "heat", "root_component_state": "end"} discoinst = OpenstackDisco(disco_config, self.entity.attributes) if 'stackid' in self.entity.attributes and \ self.entity.attributes['stackid'] is not "": stackinfo = discoinst.retrieve(self.entity.attributes['stackid']) try: for output in stackinfo: if output['output_value'] == None: output['output_value'] = "" self.entity.attributes[output['output_key']] = output['output_value'] current_stack = deployer.hc.stacks.get( self.entity.attributes['stackid']) self.entity.attributes['stack_status'] = copy.deepcopy( current_stack.stack_status) except: self.entity.attributes['external_ip'] = 'none' else: self.entity.attributes['disco_status'] = 'nothing here right now' # this has to be done because Hurtle doesn't convert a multiline string into a valid JSON if "ssh_private_key" in self.entity.attributes: self.entity.attributes["ssh_private_key"] = self.entity.attributes["ssh_private_key"].replace("\n","\\n") return self.entity, self.extras
def __call__(self, environ, response): token = environ.get('HTTP_X_AUTH_TOKEN', '') if token == '': LOG.error('No X-Auth-Token header supplied.') raise HTTPError(400, 'No X-Auth-Token header supplied.') tenant = environ.get('HTTP_X_TENANT_NAME', '') if tenant == '': LOG.error('No X-Tenant-Name header supplied.') raise HTTPError(400, 'No X-Tenant-Name header supplied.') design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') auth = KeyStoneAuthService(design_uri) if not auth.verify(token=token, tenant_name=tenant): raise HTTPError( 401, 'Token is not valid. You likely need an updated token.') return self._call_occi(environ, response, token=token, tenant_name=tenant, registry=self.registry)
def __add_openshift_files(self, bundle_loc, tmp_dir): # put OpenShift stuff in place # build and pre_start_python comes from 'support' directory in bundle LOG.debug('Adding OpenShift support files from: ' + bundle_loc + '/support') # 1. Write build LOG.debug('Writing build to: ' + os.path.join(tmp_dir, '.openshift', 'action_hooks', 'build')) shutil.copyfile( bundle_loc + '/support/build', os.path.join(tmp_dir, '.openshift', 'action_hooks', 'build')) # 1. Write pre_start_python LOG.debug('Writing pre_start_python to: ' + os.path.join( tmp_dir, '.openshift', 'action_hooks', 'pre_start_python')) pre_start_template = Template(filename=bundle_loc + '/support/pre_start_python') design_uri = CONFIG.get('service_manager', 'design_uri', '') content = pre_start_template.render(design_uri=design_uri) LOG.debug('Writing pre_start_python content as: ' + content) pre_start_file = open( os.path.join(tmp_dir, '.openshift', 'action_hooks', 'pre_start_python'), "w") pre_start_file.write(content) pre_start_file.close() os.system(' '.join([ 'chmod', '+x', os.path.join(tmp_dir, '.openshift', 'action_hooks', '*') ]))
def __init__(self): try: # added try as many sm.cfg still have no mongo section mongo_addr = CONFIG.get('mongo', 'host', None) except NoSectionError: mongo_addr = None sm_name = os.environ.get('SM_NAME', 'SAMPLE_SM') mongo_service_name = sm_name.upper().replace('-', '_') db_host_key = mongo_service_name + '_MONGO_SERVICE_HOST' db_port_key = mongo_service_name + '_MONGO_SERVICE_PORT' db_host = os.environ.get(db_host_key, False) db_port = os.environ.get(db_port_key, False) db_user = os.environ.get('DB_USER', False) db_password = os.environ.get('DB_PASSWORD', False) if db_host and db_port and db_user and db_password: mongo_addr = 'mongodb://%s:%s@%s:%s' % (db_user, db_password, db_host, db_port) if mongo_addr is None: reg = SMRegistry() else: reg = SMMongoRegistry(mongo_addr) super(MApplication, self).__init__(reg) self.register_backend(Link.kind, KindBackend())
def __deploy_app(self): """ Deploy the local SO bundle assumption here - a git repo is returned - the bundle is not managed by git """ # create temp dir...and clone the remote repo provided by OpS dir = tempfile.mkdtemp() LOG.debug('Cloning git repository: ' + self.repo_uri + ' to: ' + dir) cmd = ' '.join(['git', 'clone', self.repo_uri, dir]) os.system(cmd) # Get the SO bundle bundle_loc = CONFIG.get('service_manager', 'bundle_location', '') if bundle_loc == '': raise Exception('No bundle_location parameter supplied in sm.cfg') LOG.debug('Bundle to add to repo: ' + bundle_loc) dir_util.copy_tree(bundle_loc, dir) self.__add_openshift_files(bundle_loc, dir) # add & push to OpenShift os.system(' '.join(['cd', dir, '&&', 'git', 'add', '-A'])) os.system(' '.join(['cd', dir, '&&', 'git', 'commit', '-m', '"deployment of SO for tenant ' + \ self.extras['tenant_name'] + '"', '-a'])) LOG.debug('Pushing new code to remote repository...') os.system(' '.join(['cd', dir, '&&', 'git', 'push'])) shutil.rmtree(dir)
def __deploy_app(self): """ Deploy the local SO bundle assumption here - a git repo is returned - the bundle is not managed by git """ # create temp dir...and clone the remote repo provided by OpS tmp_dir = tempfile.mkdtemp() LOG.debug('Cloning git repository: ' + self.repo_uri + ' to: ' + tmp_dir) cmd = ' '.join(['git', 'clone', self.repo_uri, tmp_dir]) os.system(cmd) # Get the SO bundle bundle_loc = CONFIG.get('service_manager', 'bundle_location', '') if bundle_loc == '': raise Exception('No bundle_location parameter supplied in sm.cfg') LOG.debug('Bundle to add to repo: ' + bundle_loc) dir_util.copy_tree(bundle_loc, tmp_dir) self.__add_openshift_files(bundle_loc, tmp_dir) # add & push to OpenShift os.system(' '.join(['cd', tmp_dir, '&&', 'git', 'add', '-A'])) os.system(' '.join(['cd', tmp_dir, '&&', 'git', 'commit', '-m', '"deployment of SO for tenant ' + self.extras['tenant_name'] + '"', '-a'])) LOG.debug('Pushing new code to remote repository...') os.system(' '.join(['cd', tmp_dir, '&&', 'git', 'push'])) shutil.rmtree(tmp_dir)
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))
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 __init__(self, entity, extras): Task.__init__(self, entity, extras, state='destroy') if self.entity.extras['ops_version'] == 'v2': self.repo_uri = self.entity.extras['repo_uri'] self.host = urlparse(self.repo_uri).netloc.split('@')[1] elif self.entity.extras['ops_version'] == 'v3': self.host = self.entity.extras['loc'] self.nburl = CONFIG.get('cloud_controller', 'nb_api', '')
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)
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)
def run(self): LOG.debug("running update") self.start_time = time.time() infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'update', 'phase_event': 'start', 'response_time': 0, } LOG.debug(json.dumps(infoDict)) self.entity.attributes['mcn.service.state'] = 'update' # Do update work here self.entity.attributes['icclab.disco.deployer.auth_url'] = CONFIG.get('service_manager', 'design_uri', '') self.entity.attributes['icclab.disco.deployer.tenant_name'] = self.extras['tenant_name'] deployer = DeployerFactory.get_deployer(self.entity.attributes, self.extras) framework_directory = CONFIG.get('disco', 'framework_directory', '') disco_config = {"deployer": deployer, "framework_directory": framework_directory, "root_component": "heat", "root_component_state": "end"} discoinst = OpenstackDisco(disco_config, self.entity.attributes) try: if self.new.attributes['action']=='suspend': discoinst.suspend() self.entity.attributes['runstate'] = 'suspended' elif self.new.attributes['action']=='resume': discoinst.resume() self.entity.attributes['runstate'] = 'running' except Exception as e: LOG.error(str(e)) elapsed_time = time.time() - self.start_time infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'update', 'phase_event': 'done', 'response_time': elapsed_time, } LOG.debug(json.dumps(infoDict)) return self.entity, self.extras
def run(self): LOG.debug("running destroy") self.start_time = time.time() infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'destroy', 'phase_event': 'start', 'response_time': 0, } LOG.debug(json.dumps(infoDict)) self.entity.attributes['mcn.service.state'] = 'destroy' # Do destroy work here #TODO: following might lead to problems if icclab.disco.deployer.* is used differently argument = { 'design_uri': CONFIG.get('service_manager', 'design_uri', ''), 'username': self.entity.attributes['icclab.disco.deployer.username'], 'tenant_name': self.extras['tenant_name'], 'password': self.entity.attributes['icclab.disco.deployer.password'], 'stack_name': 'disco_' + str(uuid.uuid1()), 'region': self.entity.attributes['icclab.disco.deployer.region'], 'token': self.extras['token'] } deployer = OpenstackDeployer(argument) framework_directory = CONFIG.get('disco','framework_directory','') disco_config = {"deployer": deployer, "framework_directory": framework_directory, "root_component": "shell", "root_component_state": "end"} discoinst = OpenstackDisco(disco_config, self.entity.attributes) stackinfo = discoinst.delete(self.entity.attributes['stackid']) elapsed_time = time.time() - self.start_time infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'destroy', 'phase_event': 'done', 'response_time': elapsed_time, } LOG.debug(json.dumps(infoDict)) return self.entity, self.extras
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.')
def __init__(self): try: # added try as many sm.cfg still have no mongo section mongo_addr = CONFIG.get('mongo', 'host', None) except NoSectionError: mongo_addr = None if mongo_addr is None: reg = SMRegistry() else: reg = SMMongoRegistry(mongo_addr) super(MApplication, self).__init__(reg) self.register_backend(Link.kind, KindBackend())
def __init__(self): self.service_params = {} service_params_file_path = CONFIG.get('service_manager', 'service_params', '') if len(service_params_file_path) > 0: try: with open(service_params_file_path) as svc_params_content: self.service_params = json.load(svc_params_content) svc_params_content.close() except ValueError: # as e: LOG.error("Invalid JSON sent as service config file") except IOError: # as e: LOG.error('Cannot find the specified parameters file: ' + service_params_file_path) else: LOG.warn("No service parameters file found in config file, setting internal params to empty.")
def get_deployer(arguments, extras): attributes = {} # the HTTP parameters starting with icclab.disco.deployer. will be # handled here for key, value in arguments.iteritems(): if key.startswith("icclab.disco.deployer."): attributes[key.replace("icclab.disco.deployer.","")] = value # icclab.disco.deployer.type contains the deployer type if "type" in attributes: if attributes["type"]=="FileDeployer": return FileDeployer(attributes) # default case: OpenstackDeployer (if no deployer is mentioned) attributes["design_uri"] = CONFIG.get('service_manager', 'design_uri', '') attributes["token"] = extras["token"] attributes["stack_name"] = 'disco_' + str(uuid.uuid1()) attributes["tenant_name"] = extras["tenant_name"] return OpenstackDeployer(attributes)
def getOrchestrator( extras ): # first, a connection to keystone has to be established in order to load the service catalog for the orchestration endpoint (heat) # the design_uri has to be given in the sm.cfg file so that no other OpenStack deployment can be used kc = keystoneclient.Client(auth_url=CONFIG.get('service_manager','design_uri',''), username=extras['username'], password=extras['password'], tenant_name=extras['tenant_name'] ) # get the orchestration part of the service catalog orch = kc.service_catalog.get_endpoints(service_type='orchestration', region_name=extras['region'], endpoint_type='publicURL' ) # create a heat client with acquired public endpoint # if the correct region had been given, there is supposed to be but one entry for the orchestrator URLs hc = heatclient.Client(HEAT_VERSION, endpoint=orch['orchestration'][0]['publicURL'],token=kc.auth_token) return hc
def __call__(self, environ, response): token = environ.get('HTTP_X_AUTH_TOKEN', '') # design_uri is needed for the case that no token was given design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') tenantname = environ.get('HTTP_X_TENANT_NAME', '') region = environ.get('HTTP_X_REGION_NAME','') username = environ.get('HTTP_X_USER_NAME','') password = environ.get('HTTP_X_PASSWORD','') # for checking the authenticity auth = KeyStoneAuthService(design_uri) # get the token from username, tenant and region combination from HTTP # headers if token is '': try: # get all the required variables - as the tenant name has a # special role, it's queried separately kc = client.Client(auth_url=design_uri, username=username, password=password, tenant_name=tenantname ) environ['HTTP_X_AUTH_TOKEN'] = kc.auth_token token = kc.auth_token except: raise Exception('Either no design uri, username, ' 'password, or tenant name respectively ' 'provided or the login didn\'t succeed') else: if not auth.verify(token=token, tenant_name=tenantname): LOG.error('Token has probably expired') raise HTTPError(401, 'Token is not valid. You likely need an updated token.') # the arguments at the back will become the extras variable within the individual SM classes return self._call_occi(environ, response, username=username, design_uri=design_uri, password=password, token=token, tenant_name=tenantname, registry=self.registry, region=region)
def __extract_public_key(self): ssh_key_file = CONFIG.get('service_manager', 'ssh_key_location', '') if ssh_key_file == '': raise Exception('No ssh_key_location parameter supplied in sm.cfg') LOG.debug('Using SSH key file: ' + ssh_key_file) with open(ssh_key_file, 'r') as content_file: content = content_file.read() content = content.split() if content[0] == 'ssh-dsa': raise Exception("The supplied key is not a RSA ssh key. Location: " + ssh_key_file) key_content = content[1] key_name = 'servicemanager' if len(content) == 3: key_name = content[2] return key_name, key_content
def __deploy_to_so(self): # from this point on, the SO will be contacted in order to deploy the # distributed computing cluster heads = { 'X-Auth-Token':self.extras['token'], 'X-Tenant-Name':CONFIG.get('openstackso','tenantname'), 'Content-Type':'text/occi', 'Accept':'text/occi', 'Category':'orchestrator; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"' } # TODO: "http://" and / or port will result in a problem r = requests.put("http://"+self.sofloatingip+':8080/orchestrator/default', headers=heads) # everything that has to be changed in the head is the Category which # is switched to deploy heads['Category']='deploy; scheme="http://schemas.mobile-cloud-networking.eu/occi/service#"' # the attributes for the SO have to be transferred to it as well attributeString = ",".join("%s=\"%s\"" % (key,val) for (key,val) in self.entity.attributes.iteritems()) heads['X-OCCI-Attribute']=attributeString # TODO: "http://" and / or port will result in a problem r = requests.post("http://"+self.sofloatingip+':8080/orchestrator/default?action=deploy', headers=heads)
def __add_openshift_files(self, bundle_loc, tmp_dir): # put OpenShift stuff in place # build and pre_start_python comes from 'support' directory in bundle LOG.debug('Adding OpenShift support files from: ' + bundle_loc + '/support') # 1. Write build LOG.debug('Writing build to: ' + os.path.join(tmp_dir, '.openshift', 'action_hooks', 'build')) shutil.copyfile(bundle_loc+'/support/build', os.path.join(tmp_dir, '.openshift', 'action_hooks', 'build')) # 1. Write pre_start_python LOG.debug('Writing pre_start_python to: ' + os.path.join(tmp_dir, '.openshift', 'action_hooks', 'pre_start_python')) pre_start_template = Template(filename=bundle_loc+'/support/pre_start_python') design_uri = CONFIG.get('service_manager', 'design_uri', '') content = pre_start_template.render(design_uri=design_uri) LOG.debug('Writing pre_start_python content as: ' + content) pre_start_file = open(os.path.join(tmp_dir, '.openshift', 'action_hooks', 'pre_start_python'), "w") pre_start_file.write(content) pre_start_file.close() os.system(' '.join(['chmod', '+x', os.path.join(tmp_dir, '.openshift', 'action_hooks', '*')]))
def __call__(self, environ, response): token = environ.get("HTTP_X_AUTH_TOKEN", "") if token == "": LOG.error("No X-Auth-Token header supplied.") raise HTTPError(400, "No X-Auth-Token header supplied.") tenant = environ.get("HTTP_X_TENANT_NAME", "") if tenant == "": LOG.error("No X-Tenant-Name header supplied.") raise HTTPError(400, "No X-Tenant-Name header supplied.") design_uri = CONFIG.get("service_manager", "design_uri", "") if design_uri == "": LOG.fatal("No design_uri parameter supplied in sm.cfg") raise Exception("No design_uri parameter supplied in sm.cfg") auth = KeyStoneAuthService(design_uri) if not auth.verify(token=token, tenant_name=tenant): raise HTTPError(401, "Token is not valid. You likely need an updated token.") return self._call_occi(environ, response, token=token, tenant_name=tenant, registry=self.registry)
def __call__(self, environ, response): token = environ.get('HTTP_X_AUTH_TOKEN', '') if token == '': LOG.error('No X-Auth-Token header supplied.') raise HTTPError(400, 'No X-Auth-Token header supplied.') tenant = environ.get('HTTP_X_TENANT_NAME', '') if tenant == '': LOG.error('No X-Tenant-Name header supplied.') raise HTTPError(400, 'No X-Tenant-Name header supplied.') design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') auth = KeyStoneAuthService(design_uri) if not auth.verify(token=token, tenant_name=tenant): raise HTTPError(401, 'Token is not valid. You likely need an updated token.') return self._call_occi(environ, response, token=token, tenant_name=tenant, registry=self.registry)
def config_logger(log_level=logging.DEBUG): logging.basicConfig(format='%(levelname)s %(asctime)s: \t%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', log_level=log_level) logger = logging.getLogger(__name__) logger.setLevel(log_level) if CONFIG.get('general', 'log_file', '') != '': hdlr = logging.FileHandler(CONFIG.get('general', 'log_file', '')) formatter = logging.Formatter(fmt='%(levelname)s %(asctime)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') hdlr.setFormatter(formatter) logger.addHandler(hdlr) if CONFIG.get('general', 'graylog_api', '') != '' and CONFIG.get('general', 'graylog_port', '') != '': gray_handler = graypy.GELFHandler(CONFIG.get('general', 'graylog_api', ''), CONFIG.getint('general', 'graylog_port')) logger.addHandler(gray_handler) return logger
def config_logger(log_level=logging.DEBUG): logging.basicConfig(format='%(levelname)s %(asctime)s: \t%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', log_level=log_level) logger = logging.getLogger(__name__) logger.setLevel(log_level) if CONFIG.get('general', 'log_file', '') != '': hdlr = logging.FileHandler(CONFIG.get('general', 'log_file', '')) formatter = logging.Formatter( fmt='%(levelname)s %(asctime)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') hdlr.setFormatter(formatter) logger.addHandler(hdlr) if CONFIG.get('general', 'graylog_api', '') != '' and CONFIG.get( 'general', 'graylog_port', '') != '': gray_handler = graypy.GELFHandler( CONFIG.get('general', 'graylog_api', ''), CONFIG.getint('general', 'graylog_port')) logger.addHandler(gray_handler) return logger
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)
def __init__(self, entity, extras): Task.__init__(self, entity, extras, state='destroy') self.nburl = CONFIG.get('cloud_controller', 'nb_api', '') repo_uri = self.entity.extras['repo_uri'] self.host = urlparse(repo_uri).netloc.split('@')[1]
import json import time import os from pymongo import MongoClient from sm.config import CONFIG, CONFIG_PATH import sys sys.stdout = sys.stderr app = Flask('hurtle-sm') print 'Using CONFIG_PATH %s' % CONFIG_PATH stg_path = CONFIG.get('service_manager', 'manifest', False) if not stg_path: raise RuntimeError('No STG specified in the configuration file.') with open(stg_path) as stg_content: stg = json.load(stg_content) so_buildconfig_name = stg['service_type'].split('#')[1].replace('_', '-') service_shema = stg['service_type'] sm_name = os.environ.get('SM_NAME', 'SAMPLE_SM') mongo_service_name = sm_name.upper().replace('-', '_') cc_url = os.environ.get('CC_URL', False) cc_admin_url = os.environ.get('CC_ADMIN_URL', False) db_host_key = mongo_service_name + '_MONGO_SERVICE_HOST' db_port_key = mongo_service_name + '_MONGO_SERVICE_PORT' print 'getting mongo connection details via env: %s & %s' % (db_host_key, db_port_key) db_host = os.environ.get(db_host_key)
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)
def __deploy_so_vm(self): global soStackId global stackName # this will be the template that deploys the SO's VM on OpenStack template = """heat_template_version: 2014-10-16 parameters: resources: so_port: type: OS::Neutron::Port properties: network: e6340b75-252a-4b71-a810-418f3c3c006d fixed_ips: - subnet_id: 17b5a076-7699-4658-82cd-c844a23bbbe7 security_groups: [{ get_resource: so_sec_group }] floating_ip_assoc: type: OS::Neutron::FloatingIPAssociation properties: floatingip_id: $floatingip$ port_id: { get_resource: so_port } so_sec_group: type: OS::Neutron::SecurityGroup properties: # name: so_sg_$randomstring$ rules: [ {"direction":"ingress","protocol":"tcp","port_range_min":"22","port_range_max":"22"}, {"direction":"ingress","protocol":"tcp","port_range_min":"8080","port_range_max":"8080"}, ] hadoop_master: type: OS::Nova::Server properties: name: testso_$randomstring$ image: serviceorchestrator # Ubuntu-Trusty-Tahr-14.04.2-LTS flavor: m1.smaller # m1.tiny key_name: MNMBA2 networks: - port: { get_resource: so_port } user_data: | #!/bin/bash { SECONDS=0 # apt-get update # apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade # apt-get install -y python git python-pip python-dev # cd ~ # git clone https://github.com/icclab/hurtle_cc_sdk.git # cd ~/hurtle_cc_sdk # pip install --upgrade requests # python setup.py install # cd ~ # git clone https://github.com/icclab/hurtle_sm.git # cd ~/hurtle_sm # python setup.py install cd ~ git clone $sogitaddress$ export DESIGN_URI='$design_uri$' python $soapplication$ } 2> ~/error.log | tee ~/debug.log outputs: """ # set the needed values within the VM randomstring = str(uuid.uuid1()) template = template.replace("$design_uri$",CONFIG.get('service_manager','design_uri')) template = template.replace("$floatingip$",self.sofloatingipid) template = template.replace("$randomstring$",randomstring) template = template.replace("$sogitaddress$",CONFIG.get('openstackso','sogitaddress')) template = template.replace("$soapplication$",CONFIG.get('openstackso','soapplication')) LOG.debug('deploying template '+template) # deyloy the Heat orchestration template on OpenStack: token = self.extras['token'] # design_uri contains the keystone endpoint design_uri = CONFIG.get('openstackso', 'heat_endpoint', '') if design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') # get the connection handle to keytone heatClient = client.Client(HEAT_VERSION, design_uri, token=token) curStackName = 'so_'+randomstring body = { 'stack_name': curStackName, 'template': template } LOG.debug('the stack\'s name is '+body['stack_name']) # here is where the actual SO deployment happens tmp = heatClient.stacks.create(**body) soStackId[self.sofloatingip] = tmp['stack']['id'] stackName[self.sofloatingip] = curStackName LOG.debug("new stack's ID: "+tmp['stack']['id'])
import tempfile import time from threading import Thread from urlparse import urlparse import uuid from occi.core_model import Resource, Link from sm.config import CONFIG from sm.log import LOG from sm.retry_http import http_retriable_request __author__ = 'andy' HTTP = 'http://' WAIT = int(CONFIG.get('cloud_controller', 'wait_time', 2000)) ATTEMPTS = int(CONFIG.get('cloud_controller', 'max_attempts', 5)) class ServiceParameters: def __init__(self): self.service_params = {} service_params_file_path = CONFIG.get('service_manager', 'service_params', '') if len(service_params_file_path) > 0: try: with open(service_params_file_path) as svc_params_content: self.service_params = json.load(svc_params_content) svc_params_content.close() except ValueError: # as e: LOG.error("Invalid JSON sent as service config file") except IOError: # as e:
# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from occi.backend import KindBackend from sm.config import CONFIG manager = CONFIG.get('general', 'manager', default='so_manager') # generic manager stuff from sm.managers.generic import ServiceParameters from sm.managers.generic import AsychExe # depending on config, we import a different manager and ensure consistent names if manager == 'so_manager': from sm.managers.so_manager import InitSO as Init from sm.managers.so_manager import ActivateSO as Activate from sm.managers.so_manager import DeploySO as Deploy from sm.managers.so_manager import ProvisionSO as Provision from sm.managers.so_manager import RetrieveSO as Retrieve from sm.managers.so_manager import UpdateSO as Update from sm.managers.so_manager import DestroySO as Destroy elif manager == 'openbaton':
import requests import json import time import os from pymongo import MongoClient from sm.config import CONFIG, CONFIG_PATH import sys sys.stdout = sys.stderr app = Flask('hurtle-sm') print 'Using CONFIG_PATH %s' % CONFIG_PATH stg_path = CONFIG.get('service_manager', 'manifest', False) if not stg_path: raise RuntimeError('No STG specified in the configuration file.') with open(stg_path) as stg_content: stg = json.load(stg_content) so_buildconfig_name = stg['service_type'].split('#')[1].replace('_', '-') service_shema = stg['service_type'] sm_name = os.environ.get('SM_NAME', 'SAMPLE_SM') mongo_service_name = sm_name.upper().replace('-', '_') cc_url = os.environ.get('CC_URL', False) cc_admin_url = os.environ.get('CC_ADMIN_URL', False) db_host_key = mongo_service_name + '_MONGO_SERVICE_HOST' db_port_key = mongo_service_name + '_MONGO_SERVICE_PORT' print 'getting mongo connection details via env: %s & %s' % (db_host_key, db_port_key)
import tempfile import time from threading import Thread from urlparse import urlparse import uuid from occi.core_model import Resource, Link from sm.config import CONFIG from sm.log import LOG from sm.retry_http import http_retriable_request from sm.managers.generic import Task __author__ = 'andy' HTTP = 'http://' WAIT = int(CONFIG.get('cloud_controller', 'wait_time', 2000)) ATTEMPTS = int(CONFIG.get('cloud_controller', 'max_attempts', 5)) # instantiate container class InitSO(Task): def __init__(self, entity, extras): Task.__init__(self, entity, extras, state='initialise') self.nburl = os.environ.get('CC_URL', False) if not self.nburl: 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: ' +
def run(self): LOG.debug("running destroy") self.start_time = time.time() infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'destroy', 'phase_event': 'start', 'response_time': 0, } LOG.debug(json.dumps(infoDict)) self.entity.attributes['mcn.service.state'] = 'destroy' # Do destroy work here # first, the SO has to be notified that it should destroy the computing # cluster... token = self.extras['token'] heads = { 'X-Auth-Token':token, 'X-Tenant-Name':CONFIG.get('openstackso','tenantname'), 'Content-Type':'text/occi', 'Accept':'text/occi' } # this happens with the delete command self.sofloatingip = self.entity.attributes['sofloatingip'] http_retriable_request('DELETE', "http://"+self.sofloatingip+':8080/orchestrator/default', headers=heads) # this time, we don't have to wait anymore until the SO's VM is # destroyed because it's OpenStack's duty to worry about that...so # let's destroy the SO's VM straight away global soStackId # design_uri contains the keystone endpoint design_uri = CONFIG.get('openstackso', 'heat_endpoint', '') if design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') # get the connection handle to keytone heatClient = client.Client(HEAT_VERSION, design_uri, token=token) # get the floating IP of the SO's VM try: self.sofloatingip = self.entity.attributes['sofloatingip'] except: raise Exception("argument sofloatingip not given") try: from novaclient import client as novaclient # the following doesn't work, but maybe with nova.servers.remove_floating_ip(server,ip) # heatClient.v2.floating_ips.delete(self.sofloatingip) heatClient.stacks.delete(soStackId[self.sofloatingip]) except: LOG.debug("either openstack_so_manager::heatClient or openstack_so_manager::soStackId wasn't defined") # at this point, the computing cluster as well as the SO's VM have been # deleted on OpenStack elapsed_time = time.time() - self.start_time infoDict = { 'sm_name': self.entity.kind.term, 'phase': 'destroy', 'phase_event': 'done', 'response_time': elapsed_time, } LOG.debug(json.dumps(infoDict)) return self.entity, self.extras
# not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from occi.backend import KindBackend from sm.config import CONFIG manager = CONFIG.get('general', 'manager', default='so_manager') # generic manager stuff from sm.managers.generic import ServiceParameters from sm.managers.generic import AsychExe # depending on config, we import a different manager and ensure consistent names if manager == 'so_manager': from sm.managers.so_manager import InitSO as Init from sm.managers.so_manager import ActivateSO as Activate from sm.managers.so_manager import DeploySO as Deploy from sm.managers.so_manager import ProvisionSO as Provision from sm.managers.so_manager import RetrieveSO as Retrieve from sm.managers.so_manager import UpdateSO as Update from sm.managers.so_manager import DestroySO as Destroy elif manager == 'openbaton':
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)