class EventManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def addEvent(self, user_id, msg, msg_type="info", group_id=""): event_dao = self.locator.getDAO('event') dic = {} dic['user_id'] = user_id dic['msg'] = msg dic['msg_type'] = msg_type dic['group_id'] = group_id event = event_dao.insert(dic) return True def listEvents(self, search, search_or, sort, page, res_params): event_dao = self.locator.getDAO('event') output = [] (events, total_count) = event_dao.select(search=search, search_or=search_or, sort=sort, page=page) for event in events: event_info = self.locator.getInfo('EventInfo', event) output.append(event_info) return (output, total_count)
class SingularityManager(Manager): GLOBAL_CONF = config.getGlobalConfig() # param: # r_dic : dictionary for singularity request # sample : # { # "id": "dragon fly", # "owners": [ # "*****@*****.**" # ], # "daemon": True, # "rackSensitive": False, # "loadBalanced": False # } def createRequest(self, r_dic, endpoint='127.0.0.1'): # TODO: client = RestClient(endpoint,port=7099) s_url='/singularity/api/requests' (code,result) = client.request('POST', url=s_url, params=r_dic, content_type="json") self.logger.debug("Singularity(%s): %s" % (code,result)) if code == 200: self.logger.debug("Singularity(request): %s" % result) return result else: raise ERROR_NOT_FOUND(key="singularity", value=r_dic) # Connect to singularity # Call request API # return result def deployTask(self, r_dic, endpoint='127.0.0.1'): # TODO: client = RestClient(endpoint, port=7099) s_url='/singularity/api/deploys' (code, result) = client.request('POST', url=s_url, params=r_dic, content_type="json") self.logger.debug("Singularity(%s): %s" % (code, result)) if code == 200: return result else: raise ERROR_NOT_FOUND(key="singularity", value=r_dic) def checkPending(self): client = RestClient('127.0.0.1', port=7099) s_url = '/singularity/api/deploys/pending' (code, result) = client.request('GET', url=s_url, content_type="json") if code == 200: return result else: raise ERROR_NOT_FOUND(key="singularity", value=s_url)
class WorkspaceManager(Manager): GLOBAL_CONF = config.getGlobalConfig() ######################################## # CreateXXX ######################################## def createWorkspace(self, params): ws_dao = self.locator.getDAO('workspace') # TODO: check exist (user_id + name) dic = {} dic['user_id'] = params['user_id'] dic['name'] = params['name'] ws = ws_dao.insert(dic) # Update ws2user ws2user_dao = self.locator.getDAO('ws2user') if params.has_key('owner'): owners = params['owner'] for owner in owners: dic2 = {} dic2['workspace_uuid'] = ws.uuid dic2['email'] = owner dic2['role'] = 'owner' ws2user = ws2user_dao.insert(dic2) # else, failed to create request # Disable workspace status return self.locator.getInfo('WorkspaceInfo', ws) def createWorkflow(self, params): wf_dao = self.locator.getDAO('workflow') dic = {} dic['workspace_uuid'] = params['workspace_id'] dic['name'] = params['name'] wf = wf_dao.insert(dic) return self.locator.getInfo('WorkflowInfo', wf) def deployWorkflow(self, params): wf_dao = self.locator.getDAO('workflow') if params.has_key('workflow_id'): wfs = wf_dao.getVOfromKey(uuid=params['workflow_id']) if wfs.count() == 0: raise ERROR_NOT_FOUND(key='workflow_id', value=params['workflow_id']) #TODO: check user_id, workspace_id else: raise ERROR_REQUIRED_PARAM(key='workflow_id') ws_dao = self.locator.getDAO('workspace') wss = ws_dao.getVOfromKey(uuid=params['workspace_id']) if wss.count() == 0: raise ERROR_NOT_FOUND(key="workspace_id", value=params['workspace_id']) workspace_name = wss[0].name ###################################### # TODO: # Singularity Manager # This code is for DEMO ###################################### # Create Singularity request # TODO: update request parameter name1 = "%s_gerrit" % workspace_name sg_mgr = self.locator.getManager('SingularityManager') req = { "id": name1, "daemon": True, "rackSensitive": False, "loadBalanced": False } sg_mgr.createRequest(req) # If success # singularity deploy # Create Git d_git = { "deploy": { "requestId": name1, "id": "gerrit", "env": { "GERRIT_IP": "10.240.0.3" }, "containerInfo": { "type": "DOCKER", "docker": { "network": "HOST", "image": "jhyoo/gerrit-boca:latest" #"portMappings": [ # { # "containerPort": 8080, # "hostPort": 8080, # "protocol": "tcp" # }, # { # "containerPort": 29418, # "hostPort": 29418, # "protocol": "tcp" # } #] } }, "resources": { "cpus": 0.1, "memoryMb": 512 }, "skipHealthchecksOnDeploy": True } } result1 = sg_mgr.deployTask(d_git) # Update task information self.logger.info("Singularity Output:%s" % result1) for i in range(10): waiting = sg_mgr.checkPending() self.logger.info("Singularity waiting:%s" % waiting) if len(waiting) == 0: break time.sleep(2) # Create Jenkins name2 = "%s_jenkins" % workspace_name req = { "id": name2, "daemon": True, "rackSensitive": False, "loadBalanced": False } sg_mgr.createRequest(req) d_jenkins = { "deploy": { "requestId": name2, "id": "jenkins", "env": { "GERRIT_IP": "10.240.0.3" }, "containerInfo": { "type": "DOCKER", "docker": { "network": "BRIDGE", #"image": "jenkins:latest", "image": "jhyoo/jenkins-boca:dev-0.5", "privileged": True, "portMappings": [{ "containerPortType": "LITERAL", "containerPort": 8080, "hostPortType": "FROM_OFFER", "hostPort": 0, "protocol": "tcp" }, { "containerPortType": "LITERAL", "containerPort": 50000, "hostPortType": "FROM_OFFER", "hostPort": 1, "protocol": "tcp" }] } }, "resources": { "cpus": 0.1, "memoryMb": 512, "numPorts": 2 }, "skipHealthchecksOnDeploy": True } } time.sleep(5) result2 = sg_mgr.deployTask(d_jenkins) # Update task information self.logger.info("Singularity Output:%s" % result2) return self.locator.getInfo('WorkflowInfo', wfs[0]) ##################################################### # Workflow/Task # params['deploy'] = # { "name" : "Git + Gerrit", # "framework" : "singularity", # "endpoint" : "127.0.0.1", # "config" : # { # "deploy": { # "requestId": "{put your workspace name}", # "id": "git+gerrit", # "containerInfo": { # "type": "DOCKER", # "docker": { # "network": "BRIDGE", # "image": "bocabaton/git:latest", # "portMappings": [ # { # "containerPortType": "LITERAL", # "containerPort": 80, # "hostPortType": "FROM_OFFER", # "hostPort": 0, # "protocol": "tcp" # } # ] # } # }, # "resources": { # "cpus": 0.1, # "memoryMb": 256, # "numPorts": 1 # }, # "skipHealthchecksOnDeploy": True, # "healthcheckUri": "/healthcheck" # } # } # } ##################################################### def deployBpmnTask(self, params): sg_mgr = self.locator.getManager('SingularityManager') # create sigularity request request_name = params['deploy']['config']['deploy']['requestId'] endpoint = params['deploy']['endpoint'] req = { "id": request_name, "daemon": True, "rackSensitive": False, "loadBalanced": False } sg_mgr.createRequest(req, endpoint='127.0.0.1') config = params['deploy']['config'] result = sg_mgr.deployTask(config, endpoint) # deploy container return {"success": True} ################################################ # ListXXX ################################################ def listWorkspaces(self, search, sort, page, res_params): ws_dao = self.locator.getDAO('workspace') output = [] (wss, total_count) = ws_dao.select(search=search, sort=sort, page=page) for ws in wss: ws_info = self.locator.getInfo('WorkspaceInfo', ws, res_params=res_params) output.append(ws_info) return (output, total_count) #################################################### # getXXX #################################################### def getWorkspace(self, params): ws_dao = self.locator.getDAO('workspace') if params.has_key('name'): wss = ws_dao.getVOfromKey(name=params['name']) if wss.count() == 0: raise ERROR_NOT_FOUND(key='name', value=params['name']) else: raise ERROR_REQUIRED_PARAM(key='name') return self.locator.getInfo('WorkspaceInfo', wss[0]) ##################################################### # Workflow/Task # params['add'] = # { "name" : "Git + Gerrit", # "fw_type" : "singularity", # "category" : "DevOps", # "config" : # { # "deploy": { # "requestId": "{put your workspace name}", # "id": "git+gerrit", # "containerInfo": { # "type": "DOCKER", # "docker": { # "network": "BRIDGE", # "image": "bocabaton/git:latest", # "portMappings": [ # { # "containerPortType": "LITERAL", # "containerPort": 80, # "hostPortType": "FROM_OFFER", # "hostPort": 0, # "protocol": "tcp" # } # ] # } # }, # "resources": { # "cpus": 0.1, # "memoryMb": 256, # "numPorts": 1 # }, # "skipHealthchecksOnDeploy": True, # "healthcheckUri": "/healthcheck" # } # } # } ##################################################### def addWorkflowTask(self, params): wft_dao = self.locator.getDAO('task_template') p = params['add'] dic = {} dic['name'] = p['name'] dic['fw_type'] = p['fw_type'] dic['category'] = p['category'] # param is dictionary # save as json content dic['config'] = json.dumps(p['config']) wft = wft_dao.insert(dic) return self.locator.getInfo('WorkflowTaskInfo', wft) def getWorkflowTask(self, params): wft_dao = self.locator.getDAO('task_template') wfts = wft_dao.getVOfromKey(name=params['get']['name']) if wfts.count() == 0: raise ERROR_NOT_FOUND(key='name', value=params['get']['name']) return self.locator.getInfo('WorkflowTaskInfo', wfts[0])
class BaremetalDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def discover(self, param, ctx): """ @param: "auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", "region_name":"your prefered region name", } } """ auth = param['auth'] if auth.has_key('access_key_id') == False: raise ERROR_AUTH_FAILED(reason="Access Key ID is needed") else: a_key = auth['access_key_id'] if auth.has_key('secret_access_key') == False: raise ERROR_AUTH_FAILED(reason="Secret Access Key is needed") else: sa_key = auth['secret_access_key'] if auth.has_key('region_name') == False: self.logger.info("Use default region_name:us-east-1") r_name = 'us-east-1' else: r_name = auth['region_name'] client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) # base on endpoint, Create Region cloudMgr = self.locator.getManager('CloudManager') # 1. Create Region regions = self._getRegions(client.describe_regions()) output = [] total_count = 0 for region in regions: param = {'name':region} region_info = cloudMgr.createRegion(param) total_count = total_count + 1 output.append(region_info) # 2. Detect Availability Zones az_list = self.getAvailabilityZones(a_key, sa_key, region) for az in az_list: param = {'name': az, 'region_id': region_info.output['region_id'], 'zone_type': 'aws'} zone_info = cloudMgr.createZone(param) # return Zones return (output, total_count) def _getRegions(self, region_info): """ @param: value of 'ec2.describe_regions()' {'Regions': [{'Endpoint': 'ec2.eu-west-1.amazonaws.com', 'RegionName': 'eu-west-1'}, {'Endpoint': 'ec2.ap-southeast-1.amazonaws.com', 'RegionName': 'ap-southeast-1'}, {'Endpoint': 'ec2.ap-southeast-2.amazonaws.com', 'RegionName': 'ap-southeast-2'}, {'Endpoint': 'ec2.eu-central-1.amazonaws.com', 'RegionName': 'eu-central-1'}, {'Endpoint': 'ec2.ap-northeast-2.amazonaws.com', 'RegionName': 'ap-northeast-2'}, {'Endpoint': 'ec2.ap-northeast-1.amazonaws.com', 'RegionName': 'ap-northeast-1'}, {'Endpoint': 'ec2.us-east-1.amazonaws.com', 'RegionName': 'us-east-1'}, {'Endpoint': 'ec2.sa-east-1.amazonaws.com', 'RegionName': 'sa-east-1'}, {'Endpoint': 'ec2.us-west-1.amazonaws.com', 'RegionName': 'us-west-1'}, {'Endpoint': 'ec2.us-west-2.amazonaws.com', 'RegionName': 'us-west-2'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '123456789-1234-1234-1234-123456789'}} """ region = set() for item in region_info['Regions']: if item.has_key('RegionName'): region.add(item['RegionName']) return region def getAvailabilityZones(self, a_key, sa_key, r_name): """ @params: - a_key: access key id - sa_key : secret access key - region_name: Region name (ex. us-east-1) """ self.logger.debug("Discover Zone at %s" % r_name) client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) az_infos = client.describe_availability_zones(DryRun=False, Filters=[{'Name':'region-name','Values':[r_name]}]) """ {u'AvailabilityZones': [{u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2a'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2b'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2c'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'e4e83d6c-022f-443f-ba58-eb81e49bda27'}} """ output = [] for az_info in az_infos['AvailabilityZones']: if az_info['State'] == 'available': output.append(az_info['ZoneName']) return output ############################################### # Deploy ############################################### def deployServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", } } @param: zone_id @param: req (Dic) { "private_ip_address":"10.1.1.1", "ipmi_ip_address":"10.1.1.101", "ipmi_account":"root", "ipmi_password":"******" ... } """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) # 3. Create Server # For bare-metal, we just register server information # which is passed by req parameter # TODO: check the server information is correct? server = {} # TODO: what is server_id? import uuid server['server_id'] = uuid.uuid4() server['private_ip_address'] = req['private_ip_address'] return server def getServerStatus(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) # 2. Check Server Status body = {'server_id':server_id, 'cmd':'hostname'} # 3. Get Show server details return {'status':'ACTIVE'} def addFloatingIP(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ pass
class InfraManager(Manager): GLOBAL_CONF = config.getGlobalConfig() ######################################## # CreateXXX ######################################## def createRegion(self, params): region_dao = self.locator.getDAO('region') if region_dao.isExist(name=params['name']): raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] region = region_dao.insert(dic) return self.locator.getInfo('RegionInfo', region) def createZone(self, params): # exist region region_dao = self.locator.getDAO('region') if region_dao.isExist(uuid=params['region_id']) == False: raise ERROR_EXIST_RESOURCE(key='region', value=params['region_id']) zone_dao = self.locator.getDAO('zone') if zone_dao.isExist(name=params['name']): raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] dic['region_uuid'] = params['region_id'] zone = zone_dao.insert(dic) return self.locator.getInfo('ZoneInfo', zone) def createCluster(self, params): # exist zone zone_dao = self.locator.getDAO('zone') if zone_dao.isExist(uuid=params['zone_id']) == False: raise ERROR_EXIST_RESOURCE(key='zone', value=params['zone_id']) cluster_dao = self.locator.getDAO('cluster') if cluster_dao.isExist(name=params['name']): raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] dic['zone_uuid'] = params['zone_id'] cluster = cluster_dao.insert(dic) return self.locator.getInfo('ClusterInfo', cluster) def createHost(self, params): # exist cluster cluster_dao = self.locator.getDAO('cluster') if cluster_dao.isExist(uuid=params['cluster_id']) == False: raise ERROR_EXIST_RESOURCE(key='cluster', value=params['cluster_id']) host_dao = self.locator.getDAO('host') if host_dao.isExist(name=params['name']): raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] dic['ipv4'] = params['ipv4'] dic['user_id'] = params['user_id'] if params.has_key('password'): dic['password'] = params['password'] if params.has_key('id_rsa'): dic['id_rsa'] = params['id_rsa'] if params.has_key('id_dsa'): dic['id_dsa'] = params['id_dsa'] if params.has_key('domain'): dic['domain'] = params['domain'] dic['cluster_uuid'] = params['cluster_id'] host = host_dao.insert(dic) return self.getHost(host.uuid) ################################################ # ListXXX ################################################ def listRegions(self, search, sort, page, res_params): region_dao = self.locator.getDAO('region') output = [] (regions, total_count) = region_dao.select(search=search, sort=sort, page=page) for region in regions: region_info = self.locator.getInfo('RegionInfo', region, res_params=res_params) output.append(region_info) return (output, total_count) def listZones(self, search, sort, page, res_params): zone_dao = self.locator.getDAO('zone') region_dao = self.locator.getDAO('region') output = [] (zones, total_count) = zone_dao.select(search=search, sort=sort, page=page) for zone in zones: zone_info = self.locator.getInfo('ZoneInfo', zone, res_params=res_params) output.append(zone_info) return (output, total_count) def listClusters(self, search, sort, page, res_params): cluster_dao = self.locator.getDAO('cluster') output = [] (clusters, total_count) = cluster_dao.select(search=search, sort=sort, page=page) for cluster in clusters: cluster_info = self.locator.getInfo('ClusterInfo', cluster, res_params=res_params) output.append(cluster_info) return (output, total_count) def listHosts(self, search, sort, page, res_params): host_dao = self.locator.getDAO('host') output = [] (hosts, total_count) = host_dao.select(search=search, sort=sort, page=page) for host in hosts: host_dic = self.getHost(host.uuid) output.append(host_dic) return (output, total_count) #################################################### # getXXX #################################################### def getRegion(self, params): region_dao = self.locator.getDAO('region') if params.has_key('region_id'): regions = region_dao.getVOfromKey(uuid=params['region_id']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='region_id', value=params['region_id']) else: raise ERROR_REQUIRED_PARAM(key='region_id') return self.locator.getInfo('RegionInfo', regions[0]) def getZone(self, params): zone_dao = self.locator.getDAO('zone') if params.has_key('zone_id'): zones = zone_dao.getVOfromKey(uuid=params['zone_id']) if zones.count() == 0: raise ERROR_NOT_FOUND(key='zone_id', value=params['zone_id']) else: raise ERROR_REQUIRED_PARAM(key='zone_id') return self.locator.getInfo('ZoneInfo', zones[0]) def getCluster(self, params): cluster_dao = self.locator.getDAO('cluster') if params.has_key('cluster_id'): clusters = cluster_dao.getVOfromKey(uuid=params['cluster_id']) if clusters.count() == 0: raise ERROR_NOT_FOUND(key='cluster_id', value=params['cluster_id']) else: raise ERROR_REQUIRED_PARAM(key='cluster_id') return self.locator.getInfo('ClusterInfo', clusters[0]) ############################################## # Get Host # param: host_id # return: dictionary ############################################## def getHost(self, host_id): host_dao = self.locator.getDAO('host') cluster_dao = self.locator.getDAO('cluster') zone_dao = self.locator.getDAO('zone') region_dao = self.locator.getDAO('region') hosts = host_dao.getVOfromKey(uuid=host_id) if hosts.count() == 0: raise ERROR_NOT_FOUND(key='host_id', value=params['host_id']) host = {} # Temp (Choonho Son) host['name'] = hosts[0].name host['host_id'] = str(hosts[0].uuid) if hosts[0].domain: host['domain'] = hosts[0].domain host['ipv4'] = hosts[0].ipv4 host['created'] = hosts[0].created.strftime('%Y-%m-%d %H:%M:%S') host['status'] = hosts[0].status # Cluster clusters = cluster_dao.getVOfromKey(uuid=hosts[0].cluster_uuid) host['cluster_name'] = clusters[0].name # Zone zones = zone_dao.getVOfromKey(uuid=clusters[0].zone_uuid) host['zone_name'] = zones[0].name # Region regions = region_dao.getVOfromKey(uuid=zones[0].region_uuid) host['region_name'] = regions[0].name return host #return self.locator.getInfo('HostInfo', hosts[0]) ################################################################ # Discover Host ################################################################ def discoverHost(self, host_id): distro = self.detect_distro(host_id) # Update host DB host_dao = self.locator.getDAO('host') dic = {'status': 'discovered'} host = host_dao.update(host_id, dic, 'uuid') return distro def connect(self, host_id): host_dao = self.locator.getDAO('host') hosts = host_dao.getVOfromKey(uuid=host_id) if hosts.count() == 0: raise ERROR_NOT_FOUND(key='host_id', value=host_id) host = hosts[0] ip = host.ipv4 port = 22 user_id = host.user_id passwd = host.password id_rsa = host.id_rsa id_dsa = host.id_dsa try: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) if passwd != '': client.connect(ip, port, user_id, passwd, timeout=10) elif id_rsa != '': pkeyfile = paramiko.RSAKey.from_private_key( StringIO.StringIO(id_rsa)) client.connect(ip, port, user_id, pkey=pkeyfile, timeout=10) elif id_dsa != '': pkeyfile = paramiko.DSSKey.from_private_key( StringIO.StringIO(id_dsa)) client.connect(ip, port, user_id, pkey=pkeyfile, timeout=10) return client except: return None # execute commands with/out sudo # cmds : list of commands # return: output of command # None, if failed def exec_cmd(self, host_id, cmds, sudo=False): output = [] client = self.connect(host_id) if client == None: return None for cmd in cmds: if sudo == True: new_cmd = "sudo %s" % cmd else: new_cmd = cmd print new_cmd stdin, stdout, stderr = client.exec_command(new_cmd) output.append(stdout.readlines()) client.close() return output def detect_distro(self, host_id): dist = "python -c 'import platform;print platform.linux_distribution()'" distro = self.exec_cmd(host_id, [dist])[0] msg = distro[0][1:-2].encode('ascii', 'ignore') items = msg.split(",") result = { "distname": items[0].split("'")[1], "ver": items[1].split("'")[1], "id": items[2].split("'")[1] } return result
class CloudManager(Manager): GLOBAL_CONF = config.getGlobalConfig() ########################################## # Region ########################################## def createRegion(self, params): region_dao = self.locator.getDAO('region') if region_dao.isExist(name=params['name']): return self.getRegionByName(params) #raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] region = region_dao.insert(dic) return self.locator.getInfo('RegionInfo', region) def updateRegion(self, params): region_dao = self.locator.getDAO('region') if not region_dao.isExist(region_id=params['region_id']): raise ERROR_INVALID_PARAMETER(key='region_id', value=params['region_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] region = region_dao.update(params['region_id'], dic, 'region_id') return self.locator.getInfo('RegionInfo', region) def deleteRegion(self, params): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='region_id', value=params['region_id']) # TODO: Delete Zones # call deleteZone search = [{ 'key': 'region_id', 'value': params['region_id'], 'option': 'eq' }] (infos, total_count) = self.listZones(search) for info in infos: zone_id = info.output['zone_id'] param = {'zone_id': zone_id} self.deleteZone(param) regions.delete() return {} def getRegion(self, params): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='region_id', value=params['region_id']) return self.locator.getInfo('RegionInfo', regions[0]) def getRegionByName(self, params): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(name=params['name']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='name', value=params['name']) return self.locator.getInfo('RegionInfo', regions[0]) def listRegions(self, search, brief=False): region_dao = self.locator.getDAO('region') output = [] (regions, total_count) = region_dao.select(search=search) for region in regions: region_info = self.locator.getInfo('RegionInfo', region) # Brief if brief == True: # get zone # get server list total_servers = 0 z_params = [{ 'key': 'region_id', 'value': region_info.output['region_id'], 'option': 'eq' }] (zones, total_zones) = self.listZones(z_params) for zone in zones: s_params = [{ 'key': 'zone_id', 'value': zone.output['zone_id'], 'option': 'eq' }] (servers, total) = self.listServers(s_params) total_servers = total_servers + total dic = { 'total_servers': total_servers, 'total_zones': total_zones } region_info.output['brief'] = dic output.append(region_info) return (output, total_count) ########################################## # Zone ########################################## def createZone(self, params): zone_dao = self.locator.getDAO('zone') dic = {} dic['name'] = params['name'] if params.has_key('region_id'): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_INVALID_PARAMETER(key='region_id', value=params['region_id']) dic['region'] = regions[0] dic['zone_type'] = params['zone_type'] zone = zone_dao.insert(dic) return self.locator.getInfo('ZoneInfo', zone) def updateZone(self, params): zone_dao = self.locator.getDAO('zone') if not zone_dao.isExist(zone_id=params['zone_id']): raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] zone = zone_dao.update(params['zone_id'], dic, 'zone_id') return self.locator.getInfo('ZoneInfo', zone) def deleteZone(self, params): zone_dao = self.locator.getDAO('zone') zones = zone_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_NOT_FOUND(key='zone_id', value=params['zone_id']) zones.delete() return {} def getZone(self, params): zone_dao = self.locator.getDAO('zone') zones = zone_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_NOT_FOUND(key='zone_id', value=params['zone_id']) return self.locator.getInfo('ZoneInfo', zones[0]) def listZones(self, search): zone_dao = self.locator.getDAO('zone') output = [] (zones, total_count) = zone_dao.select(search=search) for zone in zones: zone_info = self.locator.getInfo('ZoneInfo', zone) output.append(zone_info) return (output, total_count) def createZoneDetail(self, params): """ @param [{'key':'k1','value':'v1'}] """ dao = self.locator.getDAO('zone_detail') for kv in params['create']: self.logger.debug("Create") self.logger.debug(kv) search = [{ 'key': 'zone_id', 'value': params['zone_id'], 'option': 'eq' }, { 'key': 'key', 'value': kv['key'], 'option': 'eq' }] (items, total_count) = dao.select(search=search) if total_count == 0: # Create z_dao = self.locator.getDAO('zone') zones = z_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() != 1: raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic = {} dic['zone'] = zones[0] dic['key'] = kv['key'] dic['value'] = kv['value'] dao.insert(dic) else: # Delete and Insert # TODO: pass def _getZoneDetail(self, zone_id): """ @param: zone_id @description: get zone detail for driver @return: dictionary of zone_detail """ dao = self.locator.getDAO('zone_detail') details = dao.getVOfromKey(zone_id=zone_id) dic = {} for detail in details: dic[detail.key] = detail.value return dic def _getZonePlatform(self, zone_id): """ @return: platform name """ param = {'zone_id': zone_id} zone_info = self.getZone(param) return zone_info.output['zone_type'] def _getRegionZone(self, zone_id): """ @param: zone_id @return: (region_name, zone_name) """ param = {'zone_id': zone_id} zone_info = self.getZone(param) param = {'region_id': zone_info.output['region_id']} region_info = self.getRegion(param) return (region_info.output['name'], zone_info.output['name']) def syncZone(self, params, ctx=None): """ sync server information Param: params: {'zone_id':'xxxxx'} ctx: {'user_id':'xxxx'} Return: """ # List Servers at zone (A) # Discover Servers at zone (B) # Add Servers (B-A) # Change state (A-B) # Return servers at zone ########################################### # Cloud Discover ########################################### def discoverCloud(self, params, ctx=None): """ params: {"discover": { "type":"openstack", "keystone":"http://10.1.0.1:5000/v2.0", "auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } } """ value = params['discover'] if value.has_key('type') == False: raise ERROR_INVALID_PARAMETER(key='discover', value=params['discover']) if value.has_key('auth') == False: # Discover Auth from ctx auth_params = {'get': ctx['user_id'], 'platform': value['type']} usr_mgr = self.locator.getManager('UserManager') auth = usr_mgr.getUserInfo(auth_params) value.update(auth) # OpenStack Driver if value['type'] == 'openstack': driver = self.locator.getManager('OpenStackDriver') (output, total_count) = driver.discover(value, ctx) return (output, total_count) """ {"discover": { "type":"aws", "auth":{ "access_key_id":"aws access key id", "secret_access_key":"aws secret access key" } } """ if value['type'] == 'aws': driver = self.locator.getManager('AwsDriver') (output, total_count) = driver.discover(value, ctx) return (output, total_count) # TODO: GCE Driver, Joyent Driver """ {"discover": { "type":"joyent", "auth":{ "key_id":"/{account}/keys/{key_id_name}", "secret_access_key":"/root/.ssh/joyent_id_rsa" } } """ if value['type'] == 'joyent': driver = self.locator.getManager('JoyentDriver') (output, total_count) = driver.discover(value, ctx) return (output, total_count) def discoverServers(self, params, ctx): """ discover Servers based on auth @params: {'zone_id':xxxxxx} """ # Discover Auth from ctx auth_params = {'get': ctx['user_id'], 'platform': value['type']} usr_mgr = self.locator.getManager('UserManager') auth = usr_mgr.getUserInfo(auth_params) zone_id = params['zone_id'] (driver, platform) = self._getDriver(zone_id) servers = driver.discoverServers(auth, zone_id) ############################################### # Server ############################################### def registerServerByServerInfo(self, zone_id, discovered_server, ctx): """ @params: discovered_server : dictionary server_info['server_id'] server_info['private_ip_address'] server_info['floating_ip'] """ # Create DB first dao = self.locator.getDAO('server') dic = {} if discovered_server.has_key('name'): dic['name'] = discovered_server['name'] else: dic['name'] = '' dic['cpus'] = 0 dic['memory'] = 0 dic['disk'] = 0 if discovered_server.has_key('status'): dic['status'] = discovered_server['status'] else: dic['status'] = 'unknown' if zone_id: z_dao = self.locator.getDAO('zone') zones = z_dao.getVOfromKey(zone_id=zone_id) if zones.count() == 0: raise ERROR_INVALID_PARAMETER(key='zone_id', value=zone_id) dic['zone'] = zones[0] if ctx: # Update User user_id = ctx['user_id'] u_dao = self.locator.getDAO('user') users = u_dao.getVOfromKey(user_id=user_id) if users.count() != 1: raise ERROR_INVALID_PARAMETER(key='user_id', value=user_id) dic['user'] = users[0] server = dao.insert(dic) self.updateServerInfo(server.server_id, 'server_id', discovered_server['server_id']) # Update Private IP address if discovered_server.has_key('private_ip_address'): self.updateServerInfo(server.server_id, 'private_ip_address', discovered_server['private_ip_address']) if discovered_server.has_key('floating_ip'): self.updateServerInfo(server.server_id, 'floatingip', discovered_server['floating_ip']) return self.locator.getInfo('ServerInfo', server) def registerServer(self, params, ctx): """ Find Server based on server_id then register it @param: {"zone_id":"xxxx-xxx-xxxxx-xxxxx", "name":"vm1", "floatingIP":True, "key_name":"my_keypair_name", "stack_id":"xxx-xxxx-xxxxxx", "register":True, "request":{ "server_id":"xxxx-xxxx-xxxxx" } } @ctx: context ctx['user_id'] """ # Update DB first dao = self.locator.getDAO('server') dic = {} dic['name'] = params['name'] if params.has_key('zone_id'): z_dao = self.locator.getDAO('zone') zones = z_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic['zone'] = zones[0] # Update User u_dao = self.locator.getDAO('user') users = u_dao.getVOfromKey(user_id=ctx['user_id']) if users.count() != 1: raise ERROR_INVALID_PARAMETER(key='user_id', value=ctx['user_id']) dic['user'] = users[0] server = dao.insert(dic) # 1. Detect Driver (driver, platform) = self._getDriver(params['zone_id']) # 2. Call deploy usr_mgr = self.locator.getManager('UserManager') auth_params = {'get': ctx['user_id'], 'platform': platform} self.logger.debug("auth:%s" % auth_params) auth = usr_mgr.getUserInfo(auth_params) #auth = {"auth":{ # "tenantName":"choonho.son", # "passwordCredentials":{ # "username": "******", # "password": "******" # } #} #} zone_id = params['zone_id'] """ 'req': {'server_id':'xxxx-xxxx-xxxxx'} """ req = params['request'] discovered_server = driver.discoverServer(auth, zone_id, req) self.logger.debug("Discovered server:%s" % discovered_server) # Update server_info # Detect server information # params['request'] # @private_ip_address # @public_ip_address # self.updateServerInfo(server.server_id, 'server_id', discovered_server['server_id']) # Update Private IP address if discovered_server.has_key('private_ip_address'): self.updateServerInfo(server.server_id, 'private_ip_address', discovered_server['private_ip_address']) if discovered_server.has_key('floating_ip'): self.updateServerInfo(server.server_id, 'floatingip', discovered_server['floating_ip']) ######################## # Update Stack ID ######################## if params.has_key('stack_id') == True: self.updateServerInfo(server.server_id, 'stack_id', params['stack_id']) ########################## # Update Server state ########################## if discovered_server.has_key('status'): self.logger.debug("Update Server status:%s" % discovered_server['status']) server = self.updateServer(server.server_id, 'status', discovered_server['status']) return self.locator.getInfo('ServerInfo', server) def createServer(self, params, ctx): """ @param: {"zone_id":"xxxx-xxx-xxxxx-xxxxx", "name":"vm1", "floatingIP":True, "key_name":"my_keypair_name", "stack_id":"xxx-xxxx-xxxxxx", "request":{ "server":{ "name":"vm1", "imageRef":"http://xxxx", "flaverRef":"http://xxxx", } } } # For baremetal {"zone_id":"xxxx-xxx-xxxxx-xxxxx", "name":"server01", "floatingIP":False, "key_name":"my_keypair_name", "stack_id":"xxxx-xxxx-xxx-xxx", "request": { "private_ip_address":"192.168.1.1", } } @ctx: context ctx['user_id'] """ # Update DB first dao = self.locator.getDAO('server') dic = {} dic['name'] = params['name'] dic['cpus'] = 1 dic['memory'] = 1 dic['disk'] = 1 # Update Zone if params.has_key('zone_id'): z_dao = self.locator.getDAO('zone') zones = z_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic['zone'] = zones[0] # Update User u_dao = self.locator.getDAO('user') users = u_dao.getVOfromKey(user_id=ctx['user_id']) if users.count() != 1: raise ERROR_INVALID_PARAMETER(key='user_id', value=ctx['user_id']) dic['user'] = users[0] server = dao.insert(dic) # 1. Detect Driver (driver, platform) = self._getDriver(params['zone_id']) # 2. Call deploy usr_mgr = self.locator.getManager('UserManager') auth_params = {'get': ctx['user_id'], 'platform': platform} self.logger.debug("auth:%s" % auth_params) auth = usr_mgr.getUserInfo(auth_params) #auth = {"auth":{ # "tenantName":"choonho.son", # "passwordCredentials":{ # "username": "******", # "password": "******" # } #} #} zone_id = params['zone_id'] req = params['request'] created_server = driver.deployServer(auth, zone_id, req) self.updateServerInfo(server.server_id, 'server_id', created_server['server_id']) ############################################ # Post-processing # Specific operations based on cloud type ############################################ if platform == "aws": # AWS cannot specify instance name. driver.updateName(auth, zone_id, server.server_id, params['name']) ############################ # Update server_info table ############################ # Update Private IP address if created_server.has_key('private_ip_address'): self.updateServerInfo(server.server_id, 'private_ip_address', created_server['private_ip_address']) if created_server.has_key('floating_ip'): self.updateServerInfo(server.server_id, 'floatingip', created_server['floating_ip']) # Update server_info # ex) server_id from nova # Check Server Status if params.has_key( 'floatingIP') == True and params['floatingIP'] == True: for i in range(10): status = driver.getServerStatus(auth, zone_id, created_server['server_id']) if status.has_key('status'): self.logger.debug("Server Status:%s" % status['status']) if status['status'] == 'ACTIVE' or status[ 'status'] == 'running': # Can find private address self.updateServerInfo(server.server_id, "private_ip_address", status['private_ip_address']) break else: self.logger.info('Wait to active:%s' % status['status']) time.sleep(5) else: self.logger.info('Status not found') # 3. Floating IP if params.has_key('floatingIP') == True: self.logger.debug("Call floating IP") if params['floatingIP'] == True: address = driver.addFloatingIP(auth, zone_id, created_server['server_id']) self.updateServerInfo(server.server_id, 'floatingip', address) else: self.logger.debug("No Floating IP") ####################### # Update Keypair ####################### if params.has_key('key_name') == True: # get value of keypair req = {'user_id': ctx['user_id'], 'get': params['key_name']} k_info = usr_mgr.getUserKeypair(req) if platform == "aws": key_user_id = "ec2-user" elif platform == "openstack": key_user_id = "root" elif platform == "joyent": key_user_id = "root" else: key_user_id = "root" if params.has_key('login_id') == True: key_user_id = params['login_id'] #TODO: GCE self.updateServerInfo(server.server_id, 'user_id', key_user_id) self.updateServerInfo(server.server_id, 'key_type', k_info['key_type']) self.updateServerInfo(server.server_id, k_info['key_type'], k_info['value']) else: # TODO: Temporary(Remove) self.updateServerInfo(server.server_id, 'user_id', 'root') self.updateServerInfo(server.server_id, 'password', '123456') ######################## # Update Stack ID ######################## if params.has_key('stack_id') == True: self.updateServerInfo(server.server_id, 'stack_id', params['stack_id']) ######################### # Update Server # (cpu, memory, disk) ######################### if created_server.has_key('cpus'): server = self.updateServer(server.server_id, 'cpus', created_server['cpus']) if created_server.has_key('memory'): server = self.updateServer(server.server_id, 'memory', created_server['memory']) if created_server.has_key('disk'): server = self.updateServer(server.server_id, 'disk', created_server['disk']) ########################## # Update Server state ########################## if created_server.has_key('status'): self.logger.debug("Update Server status:%s" % created_server['status']) server = self.updateServer(server.server_id, 'status', created_server['status']) return self.locator.getInfo('ServerInfo', server) def updateServer(self, server_id, key, value): """ update server table field=key, value=value @return: server dao """ self.logger.debug("Update Server at %s,%s=%s" % (server_id, key, value)) server_dao = self.locator.getDAO('server') dic = {} dic[key] = value server = server_dao.update(server_id, dic, 'server_id') return server def updateServerInfo(self, server_id, key, value): """ update server_info table """ dao = self.locator.getDAO('server_info') dic = {} s_dao = self.locator.getDAO('server') servers = s_dao.getVOfromKey(server_id=server_id) dic['server'] = servers[0] dic['key'] = key dic['value'] = value info = dao.insert(dic) def getServerInfo(self, server_id): """ return server_info table """ dao = self.locator.getDAO('server_info') infos = dao.getVOfromKey(server_id=server_id) item = {} for info in infos: key = info.key value = info.value item[key] = value return item def getServerInfo2(self, params): """ @params: {'get':key, 'server_id':server_id} return server_info item """ items = self.getServerInfo(params['server_id']) for key in items.keys(): if key == params['get']: return {key: items[key]} return {} def listServersByStackID(self, stack_id): """ Return: list of server_id """ dao = self.locator.getDAO('server_info') search = [{ 'key': 'key', 'value': 'stack_id', 'option': 'eq' }, { 'key': 'value', 'value': stack_id, 'option': 'eq' }] (infos, total_count) = dao.select(search=search) s_list = [] for info in infos: s_list.append(info.server_id.urn[9:]) return s_list def listServers(self, search, brief=False): server_dao = self.locator.getDAO('server') output = [] (servers, total_count) = server_dao.select(search=search) for server in servers: server_info = self.locator.getInfo('ServerInfo', server) if brief == True: server_info2 = self.getServerBrief( {'server_id': server_info.output['server_id']}) #server_info3 = self.locator.getInfo('ServerInfoBrief', server_info2) server_info.output['brief'] = server_info2 output.append(server_info) return (output, total_count) def getServerBrief(self, params): """ @params: {'server_id':xxxxx} Assume: server_id is always exist """ server_id = params['server_id'] s_info = self.getServerInfo(server_id) dic = {} if s_info.has_key('private_ip_address'): dic['private_ip'] = s_info['private_ip_address'] else: dic['private_ip'] = "" if s_info.has_key('floatingip'): dic['public_ip'] = s_info['floatingip'] else: dic['public_ip'] = "" if s_info.has_key('user_id'): dic['login_id'] = s_info['user_id'] else: dic['login_id'] = "" if s_info.has_key('server_id'): dic['server_id'] = s_info['server_id'] else: dic['server_id'] = "" if s_info.has_key('stack_id'): dic['stack_id'] = s_info['stack_id'] pmgr = self.locator.getManager('PackageManager') stack_info = pmgr.getStackByID(s_info['stack_id']) dic['stack_name'] = stack_info.output['name'] else: dic['stack_id'] = "" dic['stack_name'] = "" return dic def deleteServer(self, params, ctx): dao = self.locator.getDAO('server') servers = dao.getVOfromKey(server_id=params['server_id']) if servers.count() == 0: raise ERROR_NOT_FOUND(key='server_id', value=params['server_id']) # Update Status to "deleting" self.updateServer(servers[0].server_id, 'status', 'deleting') # 1. Detect Driver (driver, platform) = self._getDriver(servers[0].zone_id) self.logger.debug("Detected (%s,%s)" % (driver, platform)) # Delete server_info first si_dao = self.locator.getDAO('server_info') sis = si_dao.getVOfromKey(server=servers[0]) # Detected server_id at server_info param2 = {'get': 'server_id', 'server_id': params['server_id']} server_info = self.getServerInfo2(param2) ignore_driver = False if server_info.has_key('server_id') == False: #raise ERROR_NOT_FOUND(key='server_id', value=params['server_id']) # May be wrong DB, ignore self.logger.error("server_info has no server_id:%s" % params['server_id']) ignore_driver = True # 2. Call delete usr_mgr = self.locator.getManager('UserManager') auth_params = {'get': ctx['user_id'], 'platform': platform} self.logger.debug("auth:%s" % auth_params) auth = usr_mgr.getUserInfo(auth_params) #auth = {"auth":{ # "tenantName":"choonho.son", # "passwordCredentials":{ # "username": "******", # "password": "******" # } #} #} zone_id = servers[0].zone_id self.logger.debug("Server at Zone ID:%s" % zone_id) """ 'req': {'server_id':'xxxx-xxxx-xxxxx'} """ if ignore_driver == False: req = {'server_id': server_info['server_id']} deleted_server = driver.deleteServer(auth, zone_id, req) self.logger.debug("Delete Server Info(%s)" % len(sis)) sis.delete() self.logger.debug("Delete Server(%s)" % len(servers)) servers.delete() return {} ##################################### # SSH executor ##################################### def executeCmd(self, params): # Connect to Node using ssh (ip, user_id, password ) TRY_COUNT = 5 for i in range(TRY_COUNT): (tf, ssh, user_id) = self._makeSSHClient(params) if tf == True: break self.logger.info("Failed to connect, try again(%s)" % i + 1) time.sleep(30) if tf == False: return {"error": ssh} # We have ssh connection self.logger.debug("CMD: %s" % params['cmd']) # Assume, execute as root privileges if user_id != "root": cmd = "sudo %s" % params['cmd'] else: cmd = params['cmd'] stdin, stdout, stderr = ssh.exec_command(cmd, bufsize=348160, timeout=300, get_pty=False) return {'result': stdout.readlines()} def _makeSSHClient(self, params): # extract information for ssh server_info = self.getServerInfo(params['server_id']) if server_info.has_key('floatingip'): ip = server_info['floatingip'] elif server_info.has_key('private_ip_address'): ip = server_info['private_ip_address'] else: self.logger.info("Can not find IP: %s" % server_info) self.logger.debug("SSH IP : %s" % ip) if params.has_key('port') == True: port = params['port'] else: port = 22 # User ID if params.has_key('user_id') == True: user_id = params['user_id'] else: if server_info.has_key('user_id') == True: user_id = server_info['user_id'] else: raise ERROR_NOT_FOUND(key='user_id', value='no user_id') # Password auth_type = "password" if params.has_key('password') == True: password = params['password'] elif params.has_key('id_rsa') == True: auth_type = 'id_rsa' id_rsa = params['id_rsa'] elif params.has_key('id_dsa') == True: auth_type = 'id_dsa' id_dsa = params['id_dsa'] else: # Find from server_info if server_info.has_key('key_type') == True: auth_type = server_info['key_type'] if auth_type == 'password': password = server_info['password'] elif auth_type == 'id_rsa': id_rsa = server_info['id_rsa'] elif auth_type == 'id_dsa': id_dsa = server_info['id_dsa'] ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) connected = False self.logger.debug("Auth Type:%s" % auth_type) self.logger.debug("User ID:%s" % user_id) if auth_type == 'password': self.logger.debug("Password:%s" % password) time.sleep(10) try: ssh.connect(ip, port, user_id, password) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False elif auth_type == 'id_rsa': # Connect by id_rsa try: pkey = paramiko.RSAKey.from_private_key( StringIO.StringIO(id_rsa)) ssh.connect(ip, port, user_id, pkey=pkey) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False self.logger.debug(e) elif auth_type == 'id_dsa': # Connect by id_dsa try: pkey = paramiko.DSSKey.from_private_key( StringIO.StringIO(id_dsa)) ssh.connect(ip, port, user_id, pkey=pkey) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False if connected == False: self.logger.debug(err_msg) return (False, "Can not connect", user_id) return (True, ssh, user_id) def _getDriver(self, zone_id): """ @params - zone_id: zone ID @return - driver instance of cloud (ex OpenStackDriver, AwsDriver) - platform name """ driver_dic = { 'openstack': 'OpenStackDriver', 'aws': 'AwsDriver', 'bare-metal': 'BaremetalDriver', 'joyent': 'JoyentDriver', 'docker': 'DockerDriver', } param = {'zone_id': zone_id} zone_info = self.getZone(param) zone_type = zone_info.output['zone_type'] return (self.locator.getManager(driver_dic[zone_type]), zone_type)
import os, sys import django path = os.path.abspath(__file__ + "/../..") if path not in sys.path: sys.path.append(path) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyengine.settings") django.setup() from django.contrib.auth.hashers import make_password from pyengine.lib.locator import Locator from pyengine.lib import config GLOBAL_CONF = config.getGlobalConfig() locator = Locator() user_dao = locator.getDAO("user") def deleteRootUser(): users = user_dao.getVOfromKey(user_id=ROOT_USER) users.delete() def createRootUser(password): dic = {} dic["user_id"] = ROOT_USER dic["password"] = make_password(password) dic["language"] = GLOBAL_CONF["DEFAULT_LANGUAGE"]
class CloudManager(Manager): GLOBAL_CONF = config.getGlobalConfig() ########################################## # Region ########################################## def createRegion(self, params): region_dao = self.locator.getDAO('region') if region_dao.isExist(name=params['name']): raise ERROR_EXIST_RESOURCE(key='name', value=params['name']) dic = {} dic['name'] = params['name'] region = region_dao.insert(dic) return self.locator.getInfo('RegionInfo', region) def updateRegion(self, params): region_dao = self.locator.getDAO('region') if not region_dao.isExist(region_id=params['region_id']): raise ERROR_INVALID_PARAMETER(key='region_id', value=params['region_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] region = region_dao.update(params['region_id'], dic, 'region_id') return self.locator.getInfo('RegionInfo', region) def deleteRegion(self, params): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='region_id', value=params['region_id']) # TODO: Delete Zones # call deleteZone search = [{ 'key': 'region_id', 'value': params['region_id'], 'option': 'eq' }] (infos, total_count) = self.listZones(search) for info in infos: zone_id = info.output['zone_id'] param = {'zone_id': zone_id} self.deleteZone(param) regions.delete() return {} def getRegion(self, params): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_NOT_FOUND(key='region_id', value=params['region_id']) return self.locator.getInfo('RegionInfo', regions[0]) def listRegions(self, search): region_dao = self.locator.getDAO('region') output = [] (regions, total_count) = region_dao.select(search=search) for region in regions: region_info = self.locator.getInfo('RegionInfo', region) output.append(region_info) return (output, total_count) ########################################## # Zone ########################################## def createZone(self, params): zone_dao = self.locator.getDAO('zone') dic = {} dic['name'] = params['name'] if params.has_key('region_id'): region_dao = self.locator.getDAO('region') regions = region_dao.getVOfromKey(region_id=params['region_id']) if regions.count() == 0: raise ERROR_INVALID_PARAMETER(key='region_id', value=params['region_id']) dic['region'] = regions[0] dic['zone_type'] = params['zone_type'] zone = zone_dao.insert(dic) return self.locator.getInfo('ZoneInfo', zone) def updateZone(self, params): zone_dao = self.locator.getDAO('zone') if not zone_dao.isExist(zone_id=params['zone_id']): raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] zone = zone_dao.update(params['zone_id'], dic, 'zone_id') return self.locator.getInfo('ZoneInfo', zone) def deleteZone(self, params): zone_dao = self.locator.getDAO('zone') zones = zone_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_NOT_FOUND(key='zone_id', value=params['zone_id']) zones.delete() return {} def getZone(self, params): zone_dao = self.locator.getDAO('zone') zones = zone_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_NOT_FOUND(key='zone_id', value=params['zone_id']) return self.locator.getInfo('ZoneInfo', zones[0]) def listZones(self, search): zone_dao = self.locator.getDAO('zone') output = [] (zones, total_count) = zone_dao.select(search=search) for zone in zones: zone_info = self.locator.getInfo('ZoneInfo', zone) output.append(zone_info) return (output, total_count) def createZoneDetail(self, params): """ @param [{'key':'k1','value':'v1'}] """ dao = self.locator.getDAO('zone_detail') for kv in params['create']: search = [{ 'key': 'zone_id', 'value': params['zone_id'], 'option': 'eq' }, { 'key': 'key', 'value': kv['key'], 'option': 'eq' }] (items, total_count) = dao.select(search=search) if total_count == 0: # Create dic = {} dic['zone_id'] = params['zone_id'] dic['key'] = kv['key'] dic['value'] = kv['value'] dao.insert(dic) else: # Delete and Insert # TODO: pass def _getRegionZone(self, zone_id): """ @param: zone_id @return: (region_name, zone_name) """ param = {'zone_id': zone_id} zone_info = self.getZone(param) param = {'region_id': zone_info.output['region_id']} region_info = self.getRegion(param) return (region_info.output['name'], zone_info.output['name']) ########################################### # Cloud Discover ########################################### def discoverCloud(self, params): """ params: {"discover": { "type":"openstack", "keystone":"http://10.1.0.1:5000/v2.0", "auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } } """ value = params['discover'] if value.has_key('type') == False: raise ERROR_INVALID_PARAMETER(key='discover', value=params['discover']) # OpenStack Driver if value['type'] == 'openstack': driver = self.locator.getManager('OpenStackDriver') (output, total_count) = driver.discover(value) return (output, total_count) """ {"discover": { "type":"aws", "auth":{ "access_key_id":"aws access key id", "secret_access_key":"aws secret access key" } } """ if value['type'] == 'aws': driver = self.locator.getManager('AwsDriver') (output, total_count) = driver.discover(value) return (output, total_count) # TODO: GCE Driver, Joyent Driver ############################################### # Server ############################################### def createServer(self, params, ctx): """ @param: {"zone_id":"xxxx-xxx-xxxxx-xxxxx", "name":"vm1", "floatingIP":True, "key_name":"my_keypair_name", "request":{ "server":{ "name":"vm1", "imageRef":"http://xxxx", "flaverRef":"http://xxxx", } } } # For baremetal {"zone_id":"xxxx-xxx-xxxxx-xxxxx", "name":"server01", "floatingIP":False, "key_name":"my_keypair_name", "request": { "private_ip_address":"192.168.1.1", } } @ctx: context ctx['user_id'] """ # Update DB first dao = self.locator.getDAO('server') dic = {} dic['name'] = params['name'] if params.has_key('zone_id'): z_dao = self.locator.getDAO('zone') zones = z_dao.getVOfromKey(zone_id=params['zone_id']) if zones.count() == 0: raise ERROR_INVALID_PARAMETER(key='zone_id', value=params['zone_id']) dic['zone'] = zones[0] server = dao.insert(dic) # 1. Detect Driver (driver, platform) = self._getDriver(params['zone_id']) # 2. Call deploy usr_mgr = self.locator.getManager('UserManager') auth_params = {'get': ctx['user_id'], 'platform': platform} self.logger.debug("auth:%s" % auth_params) auth = usr_mgr.getUserInfo(auth_params) #auth = {"auth":{ # "tenantName":"choonho.son", # "passwordCredentials":{ # "username": "******", # "password": "******" # } #} #} zone_id = params['zone_id'] req = params['request'] created_server = driver.deployServer(auth, zone_id, req) self.updateServerInfo(server.server_id, 'server_id', created_server['server_id']) # Update Private IP address if created_server.has_key('private_ip_address'): self.updateServerInfo(server.server_id, 'private_ip_address', created_server['private_ip_address']) # Update server_info # ex) server_id from nova # Check Server Status if params.has_key( 'floatingIP') == True and params['floatingIP'] == True: for i in range(10): status = driver.getServerStatus(auth, zone_id, created_server['server_id']) if status.has_key('status'): self.logger.debug("Server Status:%s" % status['status']) if status['status'] == 'ACTIVE' or status[ 'status'] == 'running': # Can find private address self.updateServerInfo(server.server_id, "private_ip_address", status['private_ip_address']) break else: self.logger.info('Wait to active:%s' % status['status']) time.sleep(5) else: self.logger.info('Status not found') # 3. Floating IP if params.has_key('floatingIP') == True: self.logger.debug("Call floating IP") if params['floatingIP'] == True: address = driver.addFloatingIP(auth, zone_id, created_server['server_id']) self.updateServerInfo(server.server_id, 'floatingip', address) else: self.logger.debug("No Floating IP") ####################### # Update Keypair ####################### if params.has_key('key_name') == True: # get value of keypair req = {'user_id': ctx['user_id'], 'get': params['key_name']} k_info = usr_mgr.getUserKeypair(req) if platform == "aws": key_user_id = "ec2-user" elif platform == "openstack": key_user_id = "root" else: key_user_id = "root" if params.has_key('login_id') == True: key_user_id = params['login_id'] #TODO: GCE self.updateServerInfo(server.server_id, 'user_id', key_user_id) self.updateServerInfo(server.server_id, 'key_type', k_info['key_type']) self.updateServerInfo(server.server_id, k_info['key_type'], k_info['value']) else: # TODO: Temporary(Remove) self.updateServerInfo(server.server_id, 'user_id', 'root') self.updateServerInfo(server.server_id, 'password', '123456') return self.locator.getInfo('ServerInfo', server) def updateServerInfo(self, server_id, key, value): """ update server_info table """ dao = self.locator.getDAO('server_info') dic = {} s_dao = self.locator.getDAO('server') servers = s_dao.getVOfromKey(server_id=server_id) dic['server'] = servers[0] dic['key'] = key dic['value'] = value info = dao.insert(dic) def getServerInfo(self, server_id): """ return server_info table """ dao = self.locator.getDAO('server_info') infos = dao.getVOfromKey(server_id=server_id) item = {} for info in infos: key = info.key value = info.value item[key] = value return item def getServerInfo2(self, params): """ @params: {'get':key, 'server_id':server_id} return server_info item """ items = self.getServerInfo(params['server_id']) for key in items.keys(): if key == params['get']: return {key: items[key]} return {} def listServers(self, search): server_dao = self.locator.getDAO('server') output = [] (servers, total_count) = server_dao.select(search=search) for server in servers: server_info = self.locator.getInfo('ServerInfo', server) output.append(server_info) return (output, total_count) ##################################### # SSH executor ##################################### def executeCmd(self, params): # Connect to Node using ssh (ip, user_id, password ) TRY_COUNT = 5 for i in range(TRY_COUNT): (tf, ssh, user_id) = self._makeSSHClient(params) if tf == True: break self.logger.info("Failed to connect, try again(%s)" % i + 1) time.sleep(30) if tf == False: return {"error": ssh} # We have ssh connection self.logger.debug("CMD: %s" % params['cmd']) # Assume, execute as root privileges if user_id != "root": cmd = "sudo %s" % params['cmd'] else: cmd = params['cmd'] stdin, stdout, stderr = ssh.exec_command(cmd, bufsize=348160, timeout=300, get_pty=False) return {'result': stdout.readlines()} def _makeSSHClient(self, params): # extract information for ssh server_info = self.getServerInfo(params['server_id']) if server_info.has_key('floatingip'): ip = server_info['floatingip'] elif server_info.has_key('private_ip_address'): ip = server_info['private_ip_address'] else: self.logger.info("Can not find IP: %s" % server_info) self.logger.debug("SSH IP : %s" % ip) if params.has_key('port') == True: port = params['port'] else: port = 22 # User ID if params.has_key('user_id') == True: user_id = params['user_id'] else: if server_info.has_key('user_id') == True: user_id = server_info['user_id'] else: raise ERROR_NOT_FOUND(key='user_id', value='no user_id') # Password auth_type = "password" if params.has_key('password') == True: password = params['password'] elif params.has_key('id_rsa') == True: auth_type = 'id_rsa' id_rsa = params['id_rsa'] elif params.has_key('id_dsa') == True: auth_type = 'id_dsa' id_dsa = params['id_dsa'] else: # Find from server_info if server_info.has_key('key_type') == True: auth_type = server_info['key_type'] if auth_type == 'password': password = server_info['password'] elif auth_type == 'id_rsa': id_rsa = server_info['id_rsa'] elif auth_type == 'id_dsa': id_dsa = server_info['id_dsa'] ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) connected = False self.logger.debug("Auth Type:%s" % auth_type) self.logger.debug("User ID:%s" % user_id) if auth_type == 'password': self.logger.debug("Password:%s" % password) time.sleep(10) try: ssh.connect(ip, port, user_id, password) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False elif auth_type == 'id_rsa': # Connect by id_rsa try: pkey = paramiko.RSAKey.from_private_key( StringIO.StringIO(id_rsa)) ssh.connect(ip, port, user_id, pkey=pkey) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False self.logger.debug(e) elif auth_type == 'id_dsa': # Connect by id_dsa try: pkey = paramiko.DSSKey.from_private_key( StringIO.StringIO(id_dsa)) ssh.connect(ip, port, user_id, pkey=pkey) connected = True except BadHostKeyException as e: err_msg = "Bad Host Key Exception" connected = False except AuthenticationException as e: err_msg = "Authentication Exception" connected = False except SSHException as e: err_msg = "SSH Exception" connected = False except socket.error as e: err_msg = "socket error" connected = False if connected == False: self.logger.debug(err_msg) return (False, "Can not connect", user_id) return (True, ssh, user_id) def _getDriver(self, zone_id): """ @params - zone_id: zone ID @return - driver instance of cloud (ex OpenStackDriver, AwsDriver) - platform name """ driver_dic = { 'openstack': 'OpenStackDriver', 'aws': 'AwsDriver', 'bare-metal': 'BaremetalDriver', } param = {'zone_id': zone_id} zone_info = self.getZone(param) zone_type = zone_info.output['zone_type'] return (self.locator.getManager(driver_dic[zone_type]), zone_type)
class UserManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def createUser(self, params): user_dao = self.locator.getDAO('user') if user_dao.isExist(user_id=params['user_id']): raise ERROR_EXIST_RESOURCE(key='user_id', value=params['user_id']) if not utils.checkIDFormat(params['user_id']): raise ERROR_INVALID_ID_FORMAT() if not utils.checkPasswordFormat(params['password']): raise ERROR_INVALID_PASSWORD_FORMAT() dic = {} dic['user_id'] = params['user_id'] dic['password'] = make_password(params['password']) if params.has_key('name'): dic['name'] = params['name'] if params.has_key('email'): dic['email'] = params['email'] if params.has_key('language'): dic['language'] = params['language'] else: dic['language'] = self.GLOBAL_CONF['DEFAULT_LANGUAGE'] if params.has_key('timezone'): dic['timezone'] = params['timezone'] else: dic['timezone'] = self.GLOBAL_CONF['DEFAULT_TIMEZONE'] if params.has_key('group_id'): group_dao = self.locator.getDAO('group') groups = group_dao.getVOfromKey(uuid=params['group_id']) if groups.count() == 0: raise ERROR_INVALID_PARAMETER(key='group_id', value=params['group_id']) dic['group'] = groups[0] user = user_dao.insert(dic) return self.locator.getInfo('UserInfo', user) def updateUser(self, params): user_dao = self.locator.getDAO('user') if not user_dao.isExist(user_id=params['user_id']): raise ERROR_INVALID_PARAMETER(key='user_id', value=params['user_id']) dic = {} if params.has_key('password'): if not utils.checkPasswordFormat(params['password']): raise ERROR_INVALID_PASSWORD_FORMAT() dic['password'] = make_password(params['password']) if params.has_key('name'): dic['name'] = params['name'] if params.has_key('state'): dic['state'] = params['state'] if params.has_key('email'): dic['email'] = params['email'] if params.has_key('language'): dic['language'] = params['language'] if params.has_key('timezone'): dic['timezone'] = params['timezone'] if params.has_key('group_id'): group_dao = self.locator.getDAO('group') groups = group_dao.getVOfromKey(uuid=params['group_id']) if groups.count() == 0: raise ERROR_INVALID_PARAMETER(key='group_id', value=params['group_id']) dic['group'] = groups[0] user = user_dao.update(params['user_id'], dic, 'user_id') return self.locator.getInfo('UserInfo', user) def deleteUser(self, params): user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) users.delete() return {} def enableUser(self, params): params['state'] = 'enable' return self.updateUser(params) def disableUser(self, params): params['state'] = 'disable' return self.updateUser(params) def getUser(self, params): user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) return self.locator.getInfo('UserInfo', users[0]) def listUsers(self, search, search_or, sort, page, res_params): user_dao = self.locator.getDAO('user') if len(res_params) > 0: related_parent = [] for p in res_params: if p == 'group_name': related_parent.append('group') else: # DAO - Join Example # parent_model = ['<model_name>'] # parent_parent_model = ['<model_name.model_name>'] related_parent = ['group'] output = [] (users, total_count) = user_dao.select(search=search, search_or=search_or, sort=sort, page=page, related_parent=related_parent) for user in users: user_info = self.locator.getInfo('UserInfo', user, res_params=res_params) output.append(user_info) return (output, total_count)
class Auth: logger = logging.getLogger(__name__) GLOBAL_CONF = config.getGlobalConfig() def verify(self, api_request): api_request['meta']['user'] = {} if api_request['meta']['sub_module'] in self.GLOBAL_CONF[ 'NO_AUTH_MODULES']: return api_request elif api_request['meta']['sub_module'] in self.GLOBAL_CONF[ 'SYSTEM_AUTH_MODULES']: return self._systemAuth(api_request) else: if self.GLOBAL_CONF['AUTH_TYPE'] == 'xauth': return self._xAuth(api_request) else: return self._noAuth(api_request) def _systemAuth(self, api_request): if not api_request['params'].has_key('system_key'): raise ERROR_AUTH_FAILED(reason='Required system key.') if api_request['params']['system_key'] != self.GLOBAL_CONF[ 'SYSTEM_KEY']: raise ERROR_AUTH_FAILED(reason='System key is invalid.') api_request['meta']['user']['user_id'] = 'system' api_request['meta']['user']['permissions'] = '*' api_request['meta']['user']['timezone'] = self.GLOBAL_CONF[ 'DEFAULT_TIMEZONE'] return api_request def _xAuth(self, api_request): if not api_request['meta'].has_key('xtoken'): raise ERROR_AUTH_FAILED(reason='Required X-Auth-Token.') http_options = {} http_options['protocol'] = self.GLOBAL_CONF.get( 'AUTH_PROTOCOL', 'http') http_options['port'] = self.GLOBAL_CONF.get('AUTH_PORT', 80) sc = SystemClient(self.GLOBAL_CONF['AUTH_HOST'], **http_options) req_params = {} req_params['system_key'] = self.GLOBAL_CONF['SYSTEM_KEY'] req_params['token'] = api_request['meta']['xtoken'] response = sc.request('GET', self.GLOBAL_CONF['AUTH_URL'], params=req_params) if response['status'] == False: raise ERROR_AUTH_FAILED(reason=response['message']) api_request['meta']['user'] = response['response'] return api_request def _noAuth(self, api_request): api_request['meta']['user']['user_id'] = 'anonymous' api_request['meta']['user']['permissions'] = 'all' api_request['meta']['user']['timezone'] = self.GLOBAL_CONF[ 'DEFAULT_TIMEZONE'] return api_request
class Command(object): __metaclass__ = abc.ABCMeta VAR_TYPE = { 'bool' : type(bool()), 'str' : type(str()), 'int' : type(int()), 'float' : type(float()), 'dic' : type(dict()), 'list' : type(list()), 'tuple' : type(tuple()), 'unicode' : type(unicode()), 'any' : None, } # Every API specify valid parameters # Override in xxxCommand req_params = {} logger = logging.getLogger(__name__) locator = Locator() GLOBAL_CONF = config.getGlobalConfig() def __init__(self, api_request): self.user_meta = api_request['meta']['user'] self.plugins = api_request['meta']['plugin'] self.params = self._checkParam(api_request['params']) if api_request['meta'].has_key('xtoken'): self.xtoken = api_request['meta']['xtoken'] def _checkParam(self, api_params): """ @param param : request parameters from Service API @return : update self.params """ params = {} for key in self.req_params: # Key Exists if api_params.has_key(key): # Check Variable Type if self.VAR_TYPE[self.req_params[key][1]] == type(api_params[key]) or self.req_params[key][1] == 'any': params[key] = api_params[key] else: # Convert Unicode to String if self.req_params[key][1] == 'str' and type(api_params[key]) == self.VAR_TYPE['unicode']: params[key] = api_params[key].encode('utf-8') else: raise ERROR_INVALID_PARAM_TYPE(key=key, ptype=self.req_params[key][1]) # Check Enum Value if len(self.req_params[key]) >= 3: if not api_params[key] in self.req_params[key][2]: raise ERROR_INVALID_PARAMETER(key=key, value=str(self.req_params[key][2])) else: if self.req_params[key][0] == 'r': raise ERROR_REQUIRED_PARAM(key=key) return params def makeSearch(self, *args): """ Append search option with (k, params[k],"eq") """ search = self.params.get('search', []) for k in args: if self.params.has_key(k) == True: additional = {'key':k, 'value':self.params[k], 'option':'eq'} search.append(additional) # Convert Timezone tz = pytz.timezone(self.user_meta['timezone']) for s in search: if s['key'] in self.GLOBAL_CONF['DATETIME_FIELDS']: try: s['value'] = tz.localize(parse_datetime(s['value']), is_dst=None) except Exception as e: self.logger.debug(e) raise ERROR_INVALID_TIME_FORMAT() return search def rollback(self): """ Override in API rollback process """ pass @abc.abstractmethod def execute(self): """ Override in API implementation """ pass
class OpenStackDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def discover(self, param, ctx): """ @param: "keystone":"http://10.1.0.1:5000/v2.0", "auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } """ access = self.getAccess(param['keystone'], {'auth': param['auth']}) # Parse serviceCatalog catalog = access['serviceCatalog'] token = access['token'] # base on endpoint, Create Region cloudMgr = self.locator.getManager('CloudManager') # 1. Create Region regions = self._getRegions(catalog) tenantId = self._getTenantId(token) tokenId = self._getTokenId(token) output = [] total_count = 0 for region in regions: param = {'name': region} region_info = cloudMgr.createRegion(param) total_count = total_count + 1 output.append(region_info) # 2. Detect Availability Zones endpoint = self._getEndpoint(catalog, region) az_list = self.getAvailabilityZones(tokenId, endpoint, tenantId) for az in az_list: param = { 'name': az, 'region_id': region_info.output['region_id'], 'zone_type': 'openstack' } zone_info = cloudMgr.createZone(param) # return Zones return (output, total_count) def _getRegions(self, catalog): """ @param: value of 'serviceCatalog' [ { u'endpoints': [ { u'adminURL': u'http://10.1.0.1:8774/v2/9063caa05aab41cd8e34ef6a115e0915', u'id': u'7862b9253c364fd989b137c860db8e9a', u'internalURL': u'http://10.1.0.1:8774/v2/9063caa05aab41cd8e34ef6a115e0915', u'publicURL': u'http://10.1.0.1:8774/v2/9063caa05aab41cd8e34ef6a115e0915', u'region': u'RegionOne'}], u'endpoints_links': [], u'name': u'nova', u'type': u'compute'}, { u'endpoints': [ { u'adminURL': u'http://10.1.0.1:9696', u'id': u'83381d4f04cb443290b886c06c2f71a5', u'internalURL': u'http://10.1.0.1:9696', u'publicURL': u'http://10.1.0.1:9696', u'region': u'RegionOne'}], u'endpoints_links': [], u'name': u'neutron', u'type': u'network'}, """ region = set() for item in catalog: if item.has_key('type'): if item['type'] == 'compute': for endpoint in item['endpoints']: region.add(endpoint['region']) return region def _getEndpoint(self, catalog, region, svc_type='compute', url_type='publicURL'): """ return the endpoint of specific regions and type @param: value of 'serviceCatalog' """ for item in catalog: if item['type'] == svc_type: for endpoint in item['endpoints']: if endpoint['region'] == region: return endpoint[url_type] return None def _getTenantId(self, token): """ @param: access['token'] @return: tenant ID """ return token['tenant']['id'] def _getTokenId(self, token): """ @param: access['token'] @return: Token ID """ return token['id'] def getAccess(self, keystone, auth): """ @keystone: http://192.168.1.1:5000/v2.0 @auth: {"auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username":"******", "password":"******" } } @return: access """ # make get token request hdr = {'Content-Type': 'application/json'} r_data = auth url = "%s/tokens" % keystone self.logger.debug("Req URL:%s" % url) r = requests.post(url, headers=hdr, data=json.dumps(r_data)) self.logger.debug("Output:%s" % r.text) if r.status_code == 200 or r.status_code == 203: result = json.loads(r.text) return result['access'] # Error elif r.status_code == 403: raise ERROR_AUTH_FAILED(reason="userDisabled") elif r.status_code == 400: raise ERROR_AUTH_FAILED(reason="Bad Request") elif r.status_code == 401: raise ERROR_AUTH_FAILED(reason="Unauthorized") elif r.status_code == 403: raise ERROR_AUTH_FAILED(reason="Forbidden") elif r.status_code == 404: raise ERROR_AUTH_FAILED(reason="Not Found") elif r.status_code == 405: raise ERROR_AUTH_FAILED(reason="Method Not Allowed") elif r.status_code == 413: raise ERROR_AUTH_FAILED(reason="Request Entity Too Large") elif r.status_code == 503: raise ERROR_AUTH_FAILED(reason="Service Unavailable") else: raise ERROR_AUTH_FAILED(reason="Unknown") def getAvailabilityZones(self, token, endpoint, tenant_id): """ url: /v2.1/{tenant_id}/os-availability-zone method: GET response { "availabilityZoneInfo": [ { "zoneState": { "available": true }, "hosts": null, "zoneName": "nova" } ] } @return: list of availability zone ex) ['nova'] """ hdr = {'Content-Type': 'application/json', 'X-Auth-Token': token} url = "%s/os-availability-zone" % endpoint r = requests.get(url, headers=hdr) output = [] if r.status_code == 200: result = json.loads(r.text) self.logger.debug("Show availability zone =>\n %s" % r.text) az_infos = result['availabilityZoneInfo'] for az in az_infos: # TODO: check state output.append(az['zoneName']) return output # TODO: Error check raise ERROR_OPENSTACK(reason=url) ############################################### # Deploy ############################################### def deployServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } } @param: zone_id @param: req """ # 1. Get Token # . find keystone url from zone_detail # keystone = 'http://10.1.0.1:5000/v2.0' access = self.getAccess(keystone, auth) token_id = self._getTokenId(access['token']) # 2. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) endpoint = self._getEndpoint(access['serviceCatalog'], r_name, 'compute', 'publicURL') # 3. Create Server hdr = {'Content-Type': 'application/json', 'X-Auth-Token': token_id} r_data = req url = '%s/servers' % endpoint r = requests.post(url, headers=hdr, data=json.dumps(r_data)) if r.status_code == 202: result = json.loads(r.text) self.logger.debug(r.text) server = {} # Server ID server['server_id'] = result['server']['id'] # Address """ "addresses": { "subnet-choonho.son": [ {"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:8a:ba:e5", "version": 4, "addr": "192.168.1.120", "OS-EXT-IPS:type": "fixed"}] }, """ if result['server'].has_key('addresses'): temp = result['server']['addresses'] for key in temp.keys(): v2 = temp[key] for item in v2: addr = item['addr'] # TODO: we assume VM has one IP server['private_ip_address'] = addr return server return {"failed": json.loads(r.text)} def addFloatingIP(self, auth, zone_id, server_id): """ @param : - auth : user info for keystone token {"auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } } - server_id: OpenStack server_id """ # 1. Get Token # . find keystone url from zone_detail # keystone = 'http://10.1.0.1:5000/v2.0' access = self.getAccess(keystone, auth) token_id = self._getTokenId(access['token']) # 2. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) endpoint = self._getEndpoint(access['serviceCatalog'], r_name, 'compute', 'publicURL') # 3. List Pools hdr = {'Content-Type': 'application/json', 'X-Auth-Token': token_id} url = '%s/os-floating-ip-pools' % endpoint r = requests.get(url, headers=hdr) pool_list = [] if r.status_code == 200: """ { "floating_ip_pools": [ { "name": "pool1" }, { "name": "pool2" } ] } """ result = json.loads(r.text) pools = result['floating_ip_pools'] for pool in pools: pool_list.append(pool['name']) # TODO: no pool # For each pool, find usable floating IP FIP_FOUND = False for pool in pool_list: # list floating IP url = '%s/os-floating-ips' % endpoint r = requests.get(url, headers=hdr) """ {u'floating_ips': [{u'instance_id': u'b28a2edb-9590-4aa5-87b0-047f00026a0d', u'ip': u'192.168.0.16', u'fixed_ip': u'192.168.1.102', u'id': u'062e476d-d783-4d0b-bcc7-814a31a3c798', u'pool': u'public01'}, {u'instance_id': None, u'ip': u'192.168.0.66', u'fixed_ip': None, u'id': u'0b1d6b74-d0b0-4ea1-bea6-21b623479f15', u'pool': u'public01'}, """ if r.status_code == 200: result = json.loads(r.text) fips = result['floating_ips'] for fip in fips: if fip['instance_id'] == None: address = fip['ip'] FIP_FOUND = True break selected_pool = random.choice(pool_list) # 4. Create floating IP address if FIP_FOUND == False: url = '%s/os-floating-ips' % endpoint body = {'pool': selected_pool} r = requests.post(url, headers=hdr, data=json.dumps(body)) if r.status_code == 200: """ { "floating_ip": { "instance_id": null, "ip": "172.24.4.4", "fixed_ip": null, "id": "c9c04158-3ed4-449c-953a-aa21fb47cde7", "pool": "public" } } """ result = json.loads(r.text) address = result['floating_ip']['ip'] # 5. Add floating IP url = '%s/servers/%s/action' % (endpoint, server_id) body = {'addFloatingIp': {'address': address}} r = requests.post(url, headers=hdr, data=json.dumps(body)) if r.status_code == 202: pass else: self.logger.debug(r.text) self.logger.debug('url:%s' % url) raise ERROR_OPENSTACK(key='addFloatingIp', value=address) return address def getServerStatus(self, auth, zone_id, server_id): """ @param : - auth : user info for keystone token {"auth":{ "tenantName":"choonho.son", "passwordCredentials":{ "username": "******", "password": "******" } } } - server_id: OpenStack server_id """ # 1. Get Token # . find keystone url from zone_detail # keystone = 'http://10.1.0.1:5000/v2.0' access = self.getAccess(keystone, auth) token_id = self._getTokenId(access['token']) # 2. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) endpoint = self._getEndpoint(access['serviceCatalog'], r_name, 'compute', 'publicURL') # 3. Get Show server details hdr = {'Content-Type': 'application/json', 'X-Auth-Token': token_id} url = '%s/servers/%s' % (endpoint, server_id) r = requests.get(url, headers=hdr) if r.status_code == 200: result = json.loads(r.text) self.logger.debug(r.text) # Address """ "addresses": { "subnet-choonho.son": [ {"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:8a:ba:e5", "version": 4, "addr": "192.168.1.120", "OS-EXT-IPS:type": "fixed"}] }, """ addr = "" if result['server'].has_key('addresses'): temp = result['server']['addresses'] for key in temp.keys(): v2 = temp[key] for item in v2: addr = item['addr'] # TODO: we assume VM has one IP return { 'status': result['server']['status'], 'private_ip_address': addr } else: return {'status': 'unknown'}
class UserManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def createUser(self, params): user_dao = self.locator.getDAO('user') if user_dao.isExist(user_id=params['user_id']): raise ERROR_EXIST_RESOURCE(key='user_id', value=params['user_id']) if not utils.checkIDFormat(params['user_id']): raise ERROR_INVALID_ID_FORMAT() if not utils.checkPasswordFormat(params['password']): raise ERROR_INVALID_PASSWORD_FORMAT() dic = {} dic['user_id'] = params['user_id'] dic['password'] = make_password(params['password']) if params.has_key('name'): dic['name'] = params['name'] if params.has_key('email'): dic['email'] = params['email'] if params.has_key('language'): dic['language'] = params['language'] else: dic['language'] = self.GLOBAL_CONF['DEFAULT_LANGUAGE'] if params.has_key('timezone'): dic['timezone'] = params['timezone'] else: dic['timezone'] = self.GLOBAL_CONF['DEFAULT_TIMEZONE'] if params.has_key('group_id'): group_dao = self.locator.getDAO('group') groups = group_dao.getVOfromKey(uuid=params['group_id']) if groups.count() == 0: raise ERROR_INVALID_PARAMETER(key='group_id', value=params['group_id']) dic['group'] = groups[0] user = user_dao.insert(dic) return self.locator.getInfo('UserInfo', user) def updateUser(self, params): user_dao = self.locator.getDAO('user') if not user_dao.isExist(user_id=params['user_id']): raise ERROR_INVALID_PARAMETER(key='user_id', value=params['user_id']) dic = {} if params.has_key('password'): if not utils.checkPasswordFormat(params['password']): raise ERROR_INVALID_PASSWORD_FORMAT() dic['password'] = make_password(params['password']) if params.has_key('name'): dic['name'] = params['name'] if params.has_key('state'): dic['state'] = params['state'] if params.has_key('email'): dic['email'] = params['email'] if params.has_key('language'): dic['language'] = params['language'] if params.has_key('timezone'): dic['timezone'] = params['timezone'] if params.has_key('group_id'): group_dao = self.locator.getDAO('group') groups = group_dao.getVOfromKey(uuid=params['group_id']) if groups.count() == 0: raise ERROR_INVALID_PARAMETER(key='group_id', value=params['group_id']) dic['group'] = groups[0] user = user_dao.update(params['user_id'], dic, 'user_id') return self.locator.getInfo('UserInfo', user) def deleteUser(self, params): user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) users.delete() return {} def enableUser(self, params): params['state'] = 'enable' return self.updateUser(params) def disableUser(self, params): params['state'] = 'disable' return self.updateUser(params) def getUser(self, params): user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) return self.locator.getInfo('UserInfo', users[0]) def listUsers(self, search, search_or, sort, page, res_params): user_dao = self.locator.getDAO('user') if len(res_params) > 0: related_parent = [] for p in res_params: if p == 'group_name': related_parent.append('group') else: # DAO - Join Example # parent_model = ['<model_name>'] # parent_parent_model = ['<model_name.model_name>'] related_parent = ['group'] output = [] (users, total_count) = user_dao.select(search=search, search_or=search_or, sort=sort, page=page, related_parent=related_parent) for user in users: user_info = self.locator.getInfo('UserInfo', user, res_params=res_params) output.append(user_info) return (output, total_count) def addUserInfo(self, params): # TODO: encrypt password # TODO: Other user can not add user info user_dao = self.locator.getDAO('user') dao = self.locator.getDAO('user_detail') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) dic = {} dic['user'] = users[0] dic['platform'] = params['platform'] items = params['add'] for key in items.keys(): dic['key'] = key dic['value'] = items[key] info = dao.insert(dic) return {} def getUserInfo(self, params): # TODO: decrypt password # TODO: Other user can not get user info dao = self.locator.getDAO('user_detail') user_dao = self.locator.getDAO('user') dao = self.locator.getDAO('user_detail') users = user_dao.getVOfromKey(user_id=params['get']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) search = [{ 'key': 'user_id', 'value': params['get'], 'option': 'eq' }, { 'key': 'platform', 'value': params['platform'], 'option': 'eq' }] self.logger.debug("search:%s" % search) search_or = [] sort = {} page = {} (items, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) output = {} for item in items: self.logger.debug(item) key = item.key value = item.value output[key] = value result = {} self.logger.debug("output:%s" % output) #TODO: for each platform, has specific format if params['platform'] == 'openstack': result['auth'] = { 'tenantName': output['tenantName'], 'passwordCredentials': { 'username': output['username'], 'password': output['password'] } } elif params['platform'] == 'aws': result['auth'] = { 'access_key_id': output['access_key_id'], 'secret_access_key': output['secret_access_key'] } elif params['platform'] == 'bare-metal': # TODO: what should we do? pass return result ############################ # Keypair ############################ def addUserKeypair(self, params): # TODO: encrypt password # TODO: Other user can not add user info user_dao = self.locator.getDAO('user') dao = self.locator.getDAO('user_keypair') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) item = params['add'] if item.has_key('name') == False: raise ERROR_REQUIRED_PARAM(key='add.name') if item.has_key('key_type') == False: raise ERROR_REQUIRED_PARAM(key='add.key_type') if item.has_key('value') == False: raise ERROR_REQUIRED_PARAM(key='add.value') dic = {} dic['user'] = users[0] dic['name'] = item['name'] dic['key_type'] = item['key_type'] dic['value'] = item['value'] info = dao.insert(dic) return {} def getUserKeypair(self, params): dao = self.locator.getDAO('user_keypair') user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_NOT_FOUND(key='user_id', value=params['user_id']) search = [{'key': 'name', 'value': params['get'], 'option': 'eq'}] self.logger.debug("search:%s" % search) search_or = [] sort = {} page = {} (items, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) if total_count == 0: raise ERROR_NOT_FOUND(key='name', value=params['get']) item = items[0] output = {} output['name'] = item.name output['key_type'] = item.key_type output['value'] = item.value return output
class OpenVpnManager(Manager): GLOBAL_CONF = config.getGlobalConfig() SERVER = GLOBAL_CONF['SERVER_ADDRESS'] URL = "http://%s/static/keys" % GLOBAL_CONF['SERVER_ADDRESS'] def createKey(self, params): """ To create openvpn key, we need root permission add /etc/sudoer www-data ALL=(ALL) NOPASSWD: ALL """ name = params['user_name'] email = params['emailAddress'] if params.has_key('organizationUnitName'): ou = params['organizationUnitName'] else: ou = 'My Organization' dao = self.locator.getDAO('openvpn_user') users = dao.getVOfromKey(name=name) if users.count() > 0: raise ERROR_EXIST_RESOURCE(key=name, value=name) # Execute Cmd cmd = [ "sudo", "/etc/openvpn/easy-rsa/pyengine-build-key.sh", name, email, ou ] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) self.logger.debug("%s" % result) ca = "%s/ca.crt" % KEY_DIR crt = "%s/%s.crt" % (KEY_DIR, params['user_name']) key = "%s/%s.key" % (KEY_DIR, params['user_name']) client_content = """ client dev tun proto udp remote %s 1194 resolv-retry infinite nobind user nobody group nogroup persist-key persist-tun ca %s.ca cert %s.crt key %s.key ns-cert-type server comp-lzo verb 3 """ % (self.SERVER, params['user_name'], params['user_name'], params['user_name']) # Copy key files to destination USER_DIR = "%s/%s" % (TARGET_DIR, params['user_name']) USER_TAR = "%s/%s.tar" % (TARGET_DIR, params['user_name']) cmd = ["sudo", "rm", "-rf", USER_DIR] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = ["sudo", "mkdir", USER_DIR] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = ["sudo", "cp", ca, "%s/%s.ca" % (USER_DIR, params['user_name'])] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = [ "sudo", "cp", crt, "%s/%s.crt" % (USER_DIR, params['user_name']) ] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = [ "sudo", "cp", key, "%s/%s.key" % (USER_DIR, params['user_name']) ] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) temp_path = "/tmp/client.ovpn" client_path = "%s/client.ovpn" % USER_DIR fp = open(temp_path, 'w') fp.write(client_content) fp.close() cmd = ["sudo", "cp", "/tmp/client.ovpn", client_path] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = [ "sudo", "tar", "-C", TARGET_DIR, "-cvf", USER_TAR, params['user_name'] ] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) cmd = ["sudo", "rm", "-rf", USER_DIR] result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) result = { "url": "%s/%s.tar" % (self.URL, params['user_name']), "openvpn_binary": "%s/openvpn-install-2.3.6-I603-i686.exe" % self.URL } # update DB dic = {} dic['name'] = name dic['ou'] = ou dic['email'] = email dic['ca'] = ca dic['crt'] = crt dic['key'] = key dic['ovpn'] = client_content user = dao.insert(dic) return result
class AwsDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def discover(self, param, ctx): """ @param: "auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", "region_name":"your prefered region name", } } """ auth = param['auth'] if auth.has_key('access_key_id') == False: raise ERROR_AUTH_FAILED(reason="Access Key ID is needed") else: a_key = auth['access_key_id'] if auth.has_key('secret_access_key') == False: raise ERROR_AUTH_FAILED(reason="Secret Access Key is needed") else: sa_key = auth['secret_access_key'] if auth.has_key('region_name') == False: self.logger.info("Use default region_name:us-east-1") r_name = 'us-east-1' else: r_name = auth['region_name'] client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) # base on endpoint, Create Region cloudMgr = self.locator.getManager('CloudManager') # 1. Create Region regions = self._getRegions(client.describe_regions()) output = [] total_count = 0 for region in regions: # Check Already Exist try: region_info = cloudMgr.getRegionByName({'name':region}) except ERROR_NOT_FOUND: param = {'name':region} region_info = cloudMgr.createRegion(param) region_id = region_info.output['region_id'] total_count = total_count + 1 output.append(region_info) # 1. Detect Availability Zones az_list = self.getAvailabilityZones(a_key, sa_key, region) for az in az_list: param = {'name': az, 'region_id': region_info.output['region_id'], 'zone_type': 'aws'} zone_info = cloudMgr.createZone(param) zone_id = zone_info.output['zone_id'] # Discover ALL servers and register them servers = self.discoverServers({'auth':auth}, zone_id) for server in servers: cloudMgr.registerServerByServerInfo(zone_id, server, ctx) # 2. Detect VPC (tf, vpcs) = self.getAwsVpcs(a_key, sa_key, region) if tf == True: # loop all VPC for vpc in vpcs: # Crete VPC name = self.findNameInTags(vpc) if name == None: name = vpc['VpcId'] param = {'name':name, 'cidr':vpc['CidrBlock'],'region_id':region_id} vpc_info = cloudMgr.createVpc(param) vpc_id = vpc_info.output['vpc_id'] # Find Subnets aws_vpc_id = vpc['VpcId'] (tf, subnets) = self.getAwsSubnets(a_key, sa_key, region, aws_vpc_id) if tf == True: for subnet in subnets: # Create Subnet name = self.findNameInTags(subnet) if name == None: name = subnet['SubnetId'] # find zone_id zone_info = cloudMgr.getZoneByName(subnet['AvailabilityZone'],region_id) zone_id = zone_info.output['zone_id'] param = {'name':name, 'cidr':subnet['CidrBlock'],'vpc_id':vpc_id, 'zone_id':zone_id} subnet_info = cloudMgr.createSubnet(param) # return Zones return (output, total_count) def _getRegions(self, region_info): """ @param: value of 'ec2.describe_regions()' {'Regions': [{'Endpoint': 'ec2.eu-west-1.amazonaws.com', 'RegionName': 'eu-west-1'}, {'Endpoint': 'ec2.ap-southeast-1.amazonaws.com', 'RegionName': 'ap-southeast-1'}, {'Endpoint': 'ec2.ap-southeast-2.amazonaws.com', 'RegionName': 'ap-southeast-2'}, {'Endpoint': 'ec2.eu-central-1.amazonaws.com', 'RegionName': 'eu-central-1'}, {'Endpoint': 'ec2.ap-northeast-2.amazonaws.com', 'RegionName': 'ap-northeast-2'}, {'Endpoint': 'ec2.ap-northeast-1.amazonaws.com', 'RegionName': 'ap-northeast-1'}, {'Endpoint': 'ec2.us-east-1.amazonaws.com', 'RegionName': 'us-east-1'}, {'Endpoint': 'ec2.sa-east-1.amazonaws.com', 'RegionName': 'sa-east-1'}, {'Endpoint': 'ec2.us-west-1.amazonaws.com', 'RegionName': 'us-west-1'}, {'Endpoint': 'ec2.us-west-2.amazonaws.com', 'RegionName': 'us-west-2'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '123456789-1234-1234-1234-123456789'}} """ region = set() for item in region_info['Regions']: if item.has_key('RegionName'): region.add(item['RegionName']) return region def getAvailabilityZones(self, a_key, sa_key, r_name): """ @params: - a_key: access key id - sa_key : secret access key - region_name: Region name (ex. us-east-1) """ self.logger.debug("Discover Zone at %s" % r_name) client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) az_infos = client.describe_availability_zones(DryRun=False, Filters=[{'Name':'region-name','Values':[r_name]}]) """ {u'AvailabilityZones': [{u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2a'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2b'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2c'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'e4e83d6c-022f-443f-ba58-eb81e49bda27'}} """ output = [] for az_info in az_infos['AvailabilityZones']: if az_info['State'] == 'available': output.append(az_info['ZoneName']) return output def getAwsVpcs(self, a_key, sa_key, r_name): """ @params: - a_key: access key id - sa_key : secret access key - region_name: Region name (ex. us-east-1) """ self.logger.debug("Discover VPCs at %s" % r_name) client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) myfilters = [{'Name':'state','Values':['available']}] vpcs = client.describe_vpcs(DryRun=False, Filters=myfilters) if vpcs.has_key('Vpcs'): return (True, vpcs['Vpcs']) else: return (False, None) def getAwsSubnets(self, a_key, sa_key, r_name, vpc_id): """ @params: - a_key: access key id - sa_key : secret access key - vpc_id: aws vpc_id """ self.logger.debug("Discover Subnets at %s" % vpc_id) client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) myfilters = [{'Name':'vpc-id','Values':[vpc_id]},{'Name':'state','Values':['available']}] subnets = client.describe_subnets(DryRun=False, Filters=myfilters) if subnets.has_key('Subnets'): return (True, subnets['Subnets']) else: return (False, None) ############################################### # Deploy ############################################### def deployServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", } } @param: zone_id @param: req (Dic) """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Create Server # Add placement based on zone_name placement = {'Placement':{'AvailabilityZone':z_name}} req.update(placement) self.logger.debug(req) instances = ec2.create_instances(**req) # We support only one instance instance = instances[0] instance.wait_until_running() instance.reload() instance_info = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } server = {} server['server_id'] = instance_info['instance_id'] #server['private_ip_address'] = instance_info['private_ip_address'] self.logger.debug("Create Server => private IP:%s" % instance_info['private_ip_address']) server['status'] = instance_info['state']['Name'] # CPU, Memory, Disk # based on instance_type, get cpu, memory, disk size manaually # notice: There are no API for get CPU, Memory, Disk return server def updateName(self, auth, zone_id, server_id, name): # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) s_info = cloudMgr.getServerInfo(server_id) #Assume server_id is always existing cloud_id = s_info['server_id'] auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create EC2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') ec2.create_tags(Resources = [cloud_id], Tags = [{'Key':'Name','Value':name}]) def discoverServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", } } @param: zone_id @param: req (Dic) {"server_id":"xxx-xxxx-xxx"} {"name":"server_name"} """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create EC2 session client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) if req.has_key('server_id'): server_id = req['server_id'] res = client.describe_instances(InstanceIds=[server_id]) elif req.has_key('name'): name = req['Name'] myfilter= [{'Name':'tag:Name','Values':[name]}] res = client.describe_instances(Filters=myfilter) if res.has_key('Reservations') and len(res['Reservations']) > 0: machines = res['Reservations'][0]['Instances'] self.logger.debug("Num machines should 1 = (%d)" % len(machines)) else: machines = [] for machine in machines: dic = {} name = self.findNameInTags(machine) if name: dic['name'] = name else: dic['name'] = machine['InstanceId'] dic['server_id'] = machine['InstanceId'] dic['ip_address'] = machine['PrivateIpAddress'] if machine.has_key('PublicIpAddress'): dic['floating_ip'] = machine['PublicIpAddress'] dic['status'] = machine['State']['Name'] dic['SubnetId'] = machine['SubnetId'] dic['VpcId'] = machine['VpcId'] return dic return None def discoverServers(self, auth, zone_id): """ find all servers at zone @return: list of server info """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create EC2 session client = boto3.client('ec2',region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) myfilter = [{'Name':'availability-zone','Values':[z_name]}] res = client.describe_instances(Filters=myfilter) if res.has_key('Reservations') and len(res['Reservations']) > 0: machines = res['Reservations'][0]['Instances'] else: machines = [] output = [] for machine in machines: dic = {} name = self.findNameInTags(machine) if name: dic['name'] = name else: dic['name'] = machine['InstanceId'] dic['server_id'] = machine['InstanceId'] dic['ip_address'] = machine['PrivateIpAddress'] if machine.has_key('PublicIpAddress'): dic['floating_ip'] = machine['PublicIpAddress'] dic['status'] = machine['State']['Name'] dic['SubnetId'] = machine['SubnetId'] dic['VpcId'] = machine['VpcId'] # Register Machine output.append(dic) return output def stopServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "key_id":"Key ID", "secret":"Secret Key", } } @param: zone_id @param: req (Dic) {"server_id":"xxx-xxxx-xxx"} """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create EC2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') if req.has_key('server_id') == True: mid = req['server_id'] machines = ec2.instances.filter(InstanceIds=[mid]).stop() for machine in machines: dic = {} dic['status'] = machine.state['Name'] return dic # This is error return {} def deleteServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "key_id":"Key ID", "secret":"Secret Key", } } @param: zone_id @param: req (Dic) {"server_id":"xxx-xxxx-xxx"} """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create EC2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') if req.has_key('server_id'): mid = req['server_id'] machines = ec2.instances.filter(InstanceIds=[mid]).terminate() for machine in machines: dic = {} dic['status'] = machine.state['Name'] return dic # This is error return {dic['status']:'not_found'} def getServerStatus(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Create Server # 3. Get Show server details instances = ec2.instances.filter(Filters=[{'Name':'instance-id','Values':[server_id]}]) i_json = {} for instance in instances: i_json = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } self.logger.debug("Get Server Status => private IP:%s" % i_json['private_ip_address']) return {'status': i_json['state']['Name'], 'private_ip_address':i_json['private_ip_address']} return {'status':'unknown'} def addFloatingIP(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Get Show server details for i in range(50): instances = ec2.instances.filter(Filters=[{'Name':'instance-id','Values':[server_id]}]) self.logger.debug("[count: %d] get server detail" % i) i_json = {} for instance in instances: i_json = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } if i_json['public_ip_address'] != None: return i_json['public_ip_address'] self.logger.info("Instance is not ready") time.sleep(10) ############## # AWS utils ############## def findNameInTags(self, dic): """ find name in tags list 'Tags': [ { 'Key': 'Name', 'Value': 'string' }, ], """ if dic.has_key('Tags'): tags = dic['Tags'] else: return None for dic in tags: if dic['Key'] == 'Name': return dic['Value'] return None
class WorkflowManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def registerWorkflow(self, params): dao = self.locator.getDAO('workflow') dic = {} dic['template'] = params['template'] dic['template_type'] = params['template_type'] workflow = dao.insert(dic) return self.locator.getInfo('WorkflowInfo', workflow) def listWorkflows(self, search, search_or, sort, page): dao = self.locator.getDAO('workflow') output = [] (workflows, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in workflows: info = self.locator.getInfo('WorkflowInfo', item) output.append(info) return (output, total_count) def getWorkflow(self, params): dao = self.locator.getDAO('workflow') workflows = dao.getVOfromKey(workflow_id=params['workflow_id']) if workflows.count() == 0: raise ERROR_NOT_FOUND(key='workflow_id', value=params['workflow_id']) return self.locator.getInfo('WorkflowInfo', workflows[0]) def getWorkflowId(self, template, template_type): """ find Workflow ID """ search = [{'key':'template', 'value':template, 'option':'eq'}, {'key':'template_type', 'value':template_type, 'option':'eq'}] search_or = [] sort = {} page = {} (items, count) = self.listWorkflows(search, search_or, sort, page) if count == 0: raise ERROR_NOT_FOUND(key='template', value=template) return items[0].output['workflow_id'] def deleteWorkflow(self, params): dao = self.locator.getDAO('workflow') workflows = dao.getVOfromKey(workflow_id=params['workflow_id']) if workflows.count() == 0: raise ERROR_NOT_FOUND(key='workflow_id', value=params['workflow_id']) workflows.delete() return {} ############################################## # Task map/unmap ############################################## def mapTask(self, params): dao = self.locator.getDAO('task') item = params['map'] dic = {} dic['name'] = item['name'] # Check Workflow w_dao = self.locator.getDAO('workflow') workflows = w_dao.getVOfromKey(workflow_id=params['workflow_id']) if workflows.count() == 0: raise ERROR_INVALID_PARAMETER(key='workflow_id', value=params['workflow_id']) dic['workflow'] = workflows[0] dic['task_uri'] = item['task_uri'] dic['task_type'] = item['task_type'] task = dao.insert(dic) return self.locator.getInfo('TaskInfo', task) def listTasks(self, workflow_id): dao = self.locator.getDAO('task') output = [] search = [{'key':'workflow_id', 'value':workflow_id, 'option':'eq'}] search_or = [] sort = {} page = {} (tasks, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) def getTaskByName(self, workflow_id, name): dao = self.locator.getDAO('task') search = [{'key':'workflow_id', 'value':workflow_id, 'option':'eq'}, {'key':'name', 'value':name, 'option':'eq'}] search_or = [] sort = {} page = {} (tasks, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) if tasks.count() == 0: raise ERROR_NOT_FOUND(key='name', value=name) return self.locator.getInfo('TaskInfo', tasks[0])
import os, sys import django path = os.path.abspath(__file__ + '/../..') if path not in sys.path: sys.path.append(path) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyengine.settings") django.setup() from django.contrib.auth.hashers import make_password from pyengine.lib.locator import Locator from pyengine.lib import config GLOBAL_CONF = config.getGlobalConfig() locator = Locator() user_dao = locator.getDAO('user') def deleteUser(user_id): users = user_dao.getVOfromKey(user_id=user_id) users.delete() def createUser(user_id, password): dic = {} dic['user_id'] = user_id dic['password'] = make_password(password) dic['language'] = GLOBAL_CONF['DEFAULT_LANGUAGE']
class ProductManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def createProduct(self, params): dao = self.locator.getDAO('product') dic = {} # Check Portfolio p_dao = self.locator.getDAO('portfolio') portfolios = p_dao.getVOfromKey(portfolio_id=params['portfolio_id']) if portfolios.count() == 0: raise ERROR_INVALID_PARAMETER(key='portfolio_id', value=params['portfolio_id']) dic['portfolio'] = portfolios[0] dic['name'] = params['name'] dic['short_description'] = params['short_description'] dic['description'] = params['description'] dic['provided_by'] = params['provided_by'] if params.has_key('vendor'): dic['vendor'] = params['vendor'] product = dao.insert(dic) return self.locator.getInfo('ProductInfo', product) def listProducts(self, search, search_or, sort, page): dao = self.locator.getDAO('product') output = [] (products, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in products: info = self.locator.getInfo('ProductInfo', item) output.append(info) return (output, total_count) def updateProduct(self, params): dao = self.locator.getDAO('product') if not dao.isExist(product_id=params['product_id']): raise ERROR_INVALID_PARAMETER(key='product_id', value=params['product_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] if params.has_key('short_description'): dic['short_description'] = params['short_description'] if params.has_key('description'): dic['description'] = params['description'] if params.has_key('provided_by'): dic['provided_by'] = params['provided_by'] if params.has_key('vendor'): dic['vendor'] = params['vendor'] product = dao.update(params['product_id'], dic, 'product_id') return self.locator.getInfo('ProductInfo', product) def getProduct(self, params): dao = self.locator.getDAO('product') products = dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_NOT_FOUND(key='product_id', value=params['product_id']) return self.locator.getInfo('ProductInfo', products[0]) def deleteProduct(self, params): dao = self.locator.getDAO('product') products = dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_NOT_FOUND(key='product_id', value=params['product_id']) products.delete() return {} ##################################################### # Product Detail # # API # # - Create/Update Product Detail # # - Delete Product Detail # # - Get Product Detail # ##################################################### def createProductDetail(self, params): p_dao = self.locator.getDAO('product') dic = {} # Get Product dao = self.locator.getDAO('product') products = p_dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_INVALID_PARAMETER(key='product_id', value=params['product_id']) dic['product'] = products[0] if params.has_key('email'): dic['email'] = params['email'] if params.has_key('support_link'): dic['support_link'] = params['support_link'] if params.has_key('support_description'): dic['support_description'] = params['support_description'] dao = self.locator.getDAO('product_detail') if not dao.isExist(product_id=params['product_id']): # Insert product = dao.insert(dic) else: # Update product = dao.update(params['product_id'], dic, 'product_id') return self.locator.getInfo('ProductDetailInfo', product) def getProductDetail(self, params): dao = self.locator.getDAO('product_detail') products = dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_NOT_FOUND(key='product_id', value=params['product_id']) return self.locator.getInfo('ProductDetailInfo', products[0]) def deleteProductDetail(self, params): dao = self.locator.getDAO('product_detail') products = dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_NOT_FOUND(key='product_id', value=params['product_id']) products.delete() return {} ######################################################### # Tag # # API # # - create Tag # # - update Tag # # - list Tags # # - delete Tag # ######################################################### def createTag(self, params): p_dao = self.locator.getDAO('product') dic = {} # Get Product dao = self.locator.getDAO('product') # product_uuid is necessary if params['create'].has_key('key') == False: raise ERROR_INVALID_PARAMETER(key='key', value=params['create']['key']) if params['create'].has_key('value') == False: raise ERROR_INVALID_PARAMETER(key='value', value=params['create']['value']) products = p_dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_INVALID_PARAMETER(key='product_id', value=params['product_id']) dic['product'] = products[0] dic['key'] = params['create']['key'] dic['value'] = params['create']['value'] dao = self.locator.getDAO('tag') tag = dao.insert(dic) return self.locator.getInfo('TagInfo', tag) def updateTag(self, params): p_dao = self.locator.getDAO('product') dic = {} # Get Product dao = self.locator.getDAO('product') # product_uuid is necessary if params['update'].has_key('uuid') == False: raise ERROR_INVALID_PARAMETER(key='uuid', value=params['update']['uuid']) if params['update'].has_key('key') == False: raise ERROR_INVALID_PARAMETER(key='key', value=params['update']['key']) if params['update'].has_key('value') == False: raise ERROR_INVALID_PARAMETER(key='value', value=params['update']['value']) products = p_dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_INVALID_PARAMETER(key='product_id', value=params['product_id']) dic['product'] = products[0] dic['key'] = params['update']['key'] dic['value'] = params['update']['value'] dao = self.locator.getDAO('tag') if not dao.isExist(uuid=params['update']['uuid']): raise ERROR_INVALID_PARAMETER(key='uuid', value=params['update']['uuid']) tag = dao.update(params['update']['uuid'], dic, 'uuid') return self.locator.getInfo('TagInfo', tag) def listTags(self, search, search_or, sort, page): dao = self.locator.getDAO('tag') output = [] (tags, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in tags: info = self.locator.getInfo('TagInfo', item) output.append(info) return (output, total_count) def deleteTag(self, params): dao = self.locator.getDAO('tag') tags = dao.getVOfromKey(uuid=params['delete']) if tags.count() == 0: raise ERROR_NOT_FOUND(key='uuid', value=params['delete']) tags.delete() return {}
class PackageManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def createPackage(self, params): dao = self.locator.getDAO('package') dic = {} # Check Product p_dao = self.locator.getDAO('product') products = p_dao.getVOfromKey(product_id=params['product_id']) if products.count() == 0: raise ERROR_INVALID_PARAMETER(key='product_id', value=params['product_id']) dic['product'] = products[0] dic['version'] = params['version'] if params.has_key('pkg_type'): dic['pkg_type'] = params['pkg_type'] if params.has_key('template'): dic['template'] = params['template'] if params.has_key('description'): dic['description'] = params['description'] package = dao.insert(dic) return self.locator.getInfo('PackageInfo', package) def listPackages(self, search, search_or, sort, page): dao = self.locator.getDAO('package') output = [] (packages, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in packages: info = self.locator.getInfo('PackageInfo', item) output.append(info) return (output, total_count) def updatePackage(self, params): dao = self.locator.getDAO('package') if not dao.isExist(package_id=params['package_id']): raise ERROR_INVALID_PARAMETER(key='package_id', value=params['package_id']) dic = {} if params.has_key('pkg_type'): dic['pkg_type'] = params['pkg_type'] if params.has_key('template'): dic['template'] = params['template'] if params.has_key('version'): dic['version'] = params['version'] if params.has_key('description'): dic['description'] = params['description'] package = dao.update(params['package_id'], dic, 'package_id') return self.locator.getInfo('PackageInfo', package) def getPackage(self, params): dao = self.locator.getDAO('package') packages = dao.getVOfromKey(package_id=params['package_id']) if packages.count() == 0: raise ERROR_NOT_FOUND(key='package_id', value=params['package_id']) return self.locator.getInfo('PackageInfo', packages[0]) def deletePackage(self, params): dao = self.locator.getDAO('package') packages = dao.getVOfromKey(package_id=params['package_id']) if packages.count() == 0: raise ERROR_NOT_FOUND(key='package_id', value=params['package_id']) packages.delete() return {} ############################################## # Stack ############################################## def deployStack(self, params, ctx): """ @params: - name - package_id - env @ctx: context of account - ctx['user_id'] - ctx['xtoken'] - ctx['name'] : project name """ # find pkg_type, template search = {'package_id':params['package_id']} info = self.getPackage(search) pkg_type = info.output['pkg_type'] template = info.output['template'] if params.has_key('env'): env = params['env'] else: env = {} dao = self.locator.getDAO('stack') dic = {} # Check Package p_dao = self.locator.getDAO('package') packages = p_dao.getVOfromKey(package_id=params['package_id']) if packages.count() == 0: raise ERROR_INVALID_PARAMETER(key='package_id', value=params['package_id']) dic['package'] = packages[0] dic['env'] = json.dumps(env) # User user_dao = self.locator.getDAO('user') users = user_dao.getVOfromKey(user_id=ctx['user_id']) if users.count() != 1: raise ERROR_NOT_FOUND(key='user_id', value=ctx['user_id']) dic['user'] = users[0] # Name if params.has_key('name'): dic['name'] = params['name'] else: dic['name'] = '' stack = dao.insert(dic) if ctx.has_key('name') == False: ctx['name'] = stack.name[:8] self.logger.debug("### Stack ID:%s" % stack.stack_id) # Update Env # TODO: HOST_IP update from config file HOST_IP = '127.0.0.1' url = 'http://%s/api/v1/catalog/stacks/%s/env' % (HOST_IP, stack.stack_id) item = {'METADATA':url} self.addEnv2(stack.stack_id, item) # Update Env(token) # Add Stack ID for provisioning item = {'jeju':{'TOKEN':ctx['xtoken'],'STACK_ID':"%s" % stack.stack_id}} self.addEnv2(stack.stack_id, item) if pkg_type == "bpmn": # BPMN Driver self.logger.debug("Launch BPMN Driver") driver = self.locator.getManager('BpmnDriver') thread = StackThread(driver, template, env, stack.stack_id, ctx) thread.start() #driver.run(template, env, stack.stack_id) elif pkg_type == "docker-compose": # Docker-Compose self.logger.debug("Launch Docker-Compose driver") driver = self.locator.getManager('DockerComposeDriver') self.logger.debug(driver) thread = StackThread(driver, template, env, stack.stack_id, ctx) thread.start() return self.getStackByID(stack.stack_id) def listStacks(self, search, search_or, sort, page): dao = self.locator.getDAO('stack') output = [] (stacks, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in stacks: info = self.locator.getInfo('StackInfo', item) output.append(info) return (output, total_count) def getStack(self, params): return self.getStackByID(params['stack_id']) def getStackByID(self, stack_id): dao = self.locator.getDAO('stack') stacks = dao.getVOfromKey(stack_id=stack_id) if stacks.count() == 0: raise ERROR_NOT_FOUND(key='stack_id', value=stack_id) return self.locator.getInfo('StackInfo', stacks[0]) def getEnv(self, stack_id): """ return: dict of env """ dao = self.locator.getDAO('stack') stacks = dao.getVOfromKey(stack_id=stack_id) if stacks.count() == 0: raise ERROR_NOT_FOUND(key='stack_id', value=stack_id) return self.locator.getInfo('StackInfo', stacks[0]) def getEnv2(self, stack_id, key): """ get value of env @param: - stack_id - key: string for key @return: dic """ info = self.getEnv(stack_id) env = info.output['env'] if env.has_key(key): return env[key] else: return {} def addEnv(self, params): """ @params: {"add" : {'key':'value'}} """ stack_id = params['stack_id'] info = self.getEnv(stack_id) env = info.output['env'] self.logger.debug("Previous Env: %s" % env) keys = params['add'].keys() value = params['add'] for key in keys: if env.has_key(key) == False: env.update(params['add']) else: # Env has already key and dictionary type if type(env[key]) == dict and type(value[key]) == dict: value1 = env[key] value1.update(value[key]) self.logger.debug("Next Env: %s" % env) dic = {} dic['env'] = json.dumps(env) dao = self.locator.getDAO('stack') stack = dao.update(stack_id, dic, 'stack_id') return self.locator.getInfo('StackInfo', stack) def addEnv2(self, stack_id, item): """ @param: - stack_id - item: dictionary for data """ params = {'stack_id':stack_id, 'add':item} return self.addEnv(params) def updateStackState(self, stack_id, state): """ @params: - stack_id - state : string of state """ dic = {} dic['state'] = state dao = self.locator.getDAO('stack') stack = dao.update(stack_id, dic, 'stack_id') return self.locator.getInfo('StackInfo', stack)
class TokenManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def getToken(self, params): user_dao = self.locator.getDAO('user') token_dao = self.locator.getDAO('token') users = user_dao.getVOfromKey(user_id=params['user_id']) if users.count() == 0: raise ERROR_INVALID_PASSWORD() user = users[0] if not check_password(params['password'], user.password): raise ERROR_INVALID_PASSWORD() if user.state == 'disable': raise ERROR_NO_PERMISSIONS() dic = {} dic['user'] = user token = token_dao.insert(dic) return {'token': str(token.token)} def expireToken(self, params): token_dao = self.locator.getDAO('token') timeout_ts = int(time.time()) - int( self.GLOBAL_CONF['TOKEN_EXPIRE_TIME']) search = [{ 'key': 'created', 'value': datetime.fromtimestamp(timeout_ts), 'option': 'lt' }] (tokens, total_count) = token_dao.select(search=search) tokens.delete() return {} def authToken(self, params): token_dao = self.locator.getDAO('token') timeout_ts = int(time.time()) - int( self.GLOBAL_CONF['TOKEN_EXPIRE_TIME']) try: token_uuid = uuid.UUID(params['token']) except: raise ERROR_INVALID_TOKEN() search = [] search.append({ 'key': 'created', 'value': datetime.fromtimestamp(timeout_ts), 'option': 'gte' }) search.append({'key': 'token', 'value': token_uuid, 'option': 'eq'}) (tokens, total_count) = token_dao.select(search=search) if tokens.count() == 0: raise ERROR_INVALID_TOKEN() token = tokens[0] if token.user.state == 'disable': raise ERROR_NO_PERMISSIONS() dic = {} dic['user_id'] = token.user.user_id dic['permissions'] = '*' dic['timezone'] = token.user.timezone return dic
class Info(object): logger = logging.getLogger(__name__) locator = Locator() GLOBAL_CONF = config.getGlobalConfig() def __init__(self, vo, options): self.vo = vo self.options = options self.output = {} def checkResponseParams(self): if len(self.options.get('res_params', [])) > 0: return True else: return False def _recursionInfo(self, key, value, tz): # UUID Type to String if type(value) == uuid.UUID: return str(value) # Time Conversion elif key in self.GLOBAL_CONF['DATETIME_FIELDS']: if value != None: value = value.replace(tzinfo=pytz.utc).astimezone(tz) return value.strftime('%Y-%m-%d %H:%M:%S') else: return '' # Instance elif isinstance(value, Info) == True: return value.result(tz) # List elif type(value) == type(list()): # Default list_output = [] for v in value: if type(v) == type(dict()): dic_output = {} for k in v: dic_output[k] = self._recursionInfo(k, v[k], tz) list_output.append(dic_output) elif isinstance(v, Info) == True: list_output.append(v.result(tz)) else: list_output.append(v) return list_output # Dictionary elif type(value) == type(dict()): output = {} for k in value: output[k] = self._recursionInfo(k, value[k], tz) return output # No Change else: return value def result(self, timezone=None): if timezone == None: timezone = self.GLOBAL_CONF['DEFAULT_TIMEZONE'] tz = pytz.timezone(timezone) to_string = {} for k in self.output: to_string[k] = self._recursionInfo(k, self.output[k], tz) return to_string
class AwsDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def discover(self, param): """ @param: "auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", "region_name":"your prefered region name", } } """ auth = param['auth'] if auth.has_key('access_key_id') == False: raise ERROR_AUTH_FAILED(reason="Access Key ID is needed") else: a_key = auth['access_key_id'] if auth.has_key('secret_access_key') == False: raise ERROR_AUTH_FAILED(reason="Secret Access Key is needed") else: sa_key = auth['secret_access_key'] if auth.has_key('region_name') == False: self.logger.info("Use default region_name:us-east-1") r_name = 'us-east-1' else: r_name = auth['region_name'] client = boto3.client('ec2', region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) # base on endpoint, Create Region cloudMgr = self.locator.getManager('CloudManager') # 1. Create Region regions = self._getRegions(client.describe_regions()) output = [] total_count = 0 for region in regions: param = {'name': region} region_info = cloudMgr.createRegion(param) total_count = total_count + 1 output.append(region_info) # 2. Detect Availability Zones az_list = self.getAvailabilityZones(a_key, sa_key, region) for az in az_list: param = { 'name': az, 'region_id': region_info.output['region_id'], 'zone_type': 'aws' } zone_info = cloudMgr.createZone(param) # return Zones return (output, total_count) def _getRegions(self, region_info): """ @param: value of 'ec2.describe_regions()' {'Regions': [{'Endpoint': 'ec2.eu-west-1.amazonaws.com', 'RegionName': 'eu-west-1'}, {'Endpoint': 'ec2.ap-southeast-1.amazonaws.com', 'RegionName': 'ap-southeast-1'}, {'Endpoint': 'ec2.ap-southeast-2.amazonaws.com', 'RegionName': 'ap-southeast-2'}, {'Endpoint': 'ec2.eu-central-1.amazonaws.com', 'RegionName': 'eu-central-1'}, {'Endpoint': 'ec2.ap-northeast-2.amazonaws.com', 'RegionName': 'ap-northeast-2'}, {'Endpoint': 'ec2.ap-northeast-1.amazonaws.com', 'RegionName': 'ap-northeast-1'}, {'Endpoint': 'ec2.us-east-1.amazonaws.com', 'RegionName': 'us-east-1'}, {'Endpoint': 'ec2.sa-east-1.amazonaws.com', 'RegionName': 'sa-east-1'}, {'Endpoint': 'ec2.us-west-1.amazonaws.com', 'RegionName': 'us-west-1'}, {'Endpoint': 'ec2.us-west-2.amazonaws.com', 'RegionName': 'us-west-2'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '123456789-1234-1234-1234-123456789'}} """ region = set() for item in region_info['Regions']: if item.has_key('RegionName'): region.add(item['RegionName']) return region def getAvailabilityZones(self, a_key, sa_key, r_name): """ @params: - a_key: access key id - sa_key : secret access key - region_name: Region name (ex. us-east-1) """ self.logger.debug("Discover Zone at %s" % r_name) client = boto3.client('ec2', region_name=r_name, aws_access_key_id=a_key, aws_secret_access_key=sa_key) az_infos = client.describe_availability_zones(DryRun=False, Filters=[{ 'Name': 'region-name', 'Values': [r_name] }]) """ {u'AvailabilityZones': [{u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2a'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2b'}, {u'State': 'available', u'RegionName': 'us-west-2', u'Messages': [], u'ZoneName': 'us-west-2c'}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'e4e83d6c-022f-443f-ba58-eb81e49bda27'}} """ output = [] for az_info in az_infos['AvailabilityZones']: if az_info['State'] == 'available': output.append(az_info['ZoneName']) return output ############################################### # Deploy ############################################### def deployServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", } } @param: zone_id @param: req (Dic) """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Create Server # Add placement based on zone_name placement = {'Placement': {'AvailabilityZone': z_name}} req.update(placement) self.logger.debug(req) instances = ec2.create_instances(**req) # We support only one instance instance = instances[0] instance_info = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } server = {} server['server_id'] = instance_info['instance_id'] #server['private_ip_address'] = instance_info['private_ip_address'] self.logger.debug("Create Server => private IP:%s" % instance_info['private_ip_address']) return server def getServerStatus(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Create Server # 3. Get Show server details instances = ec2.instances.filter(Filters=[{ 'Name': 'instance-id', 'Values': [server_id] }]) i_json = {} for instance in instances: i_json = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } self.logger.debug("Get Server Status => private IP:%s" % i_json['private_ip_address']) return { 'status': i_json['state']['Name'], 'private_ip_address': i_json['private_ip_address'] } return {'status': 'unknown'} def addFloatingIP(self, auth, zone_id, server_id): """ @param : - auth : user info for aws {"auth":{ "access_key_id":"choonho.son", "secret_access_key":"choonho.son", } } - server_id: EC2 instance_id """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) auth_data = auth['auth'] a_key = auth_data['access_key_id'] sa_key = auth_data['secret_access_key'] # 2. Create ec2 session session = Session(aws_access_key_id=a_key, aws_secret_access_key=sa_key, region_name=r_name) ec2 = session.resource('ec2') # 3. Get Show server details for i in range(50): instances = ec2.instances.filter(Filters=[{ 'Name': 'instance-id', 'Values': [server_id] }]) self.logger.debug("[count: %d] get server detail" % i) i_json = {} for instance in instances: i_json = { "ami_launch_index": instance.ami_launch_index, "architecture": instance.architecture, "client_token": instance.client_token, "ebs_optimized": instance.ebs_optimized, "hypervisor": instance.hypervisor, "iam_instance_profile": instance.iam_instance_profile, "image_id": instance.image_id, "instance_id": instance.instance_id, "instance_lifecycle": instance.instance_lifecycle, "instance_type": instance.instance_type, "kernel_id": instance.kernel_id, "key_name": instance.key_name, "launch_time": str(instance.launch_time), "monitoring": instance.monitoring, "placement": instance.placement, "platform": instance.platform, "private_dns_name": instance.private_dns_name, "private_ip_address": instance.private_ip_address, "product_codes": instance.product_codes, "public_dns_name": instance.public_dns_name, "public_ip_address": instance.public_ip_address, "ramdisk_id": instance.ramdisk_id, "root_device_name": instance.root_device_name, "root_device_type": instance.root_device_type, "security_groups": instance.security_groups, "source_dest_check": instance.source_dest_check, "spot_instance_request_id": instance.spot_instance_request_id, "sriov_net_support": instance.sriov_net_support, "state": instance.state, "state_reason": instance.state_reason, "state_transition_reason": instance.state_transition_reason, "subnet_id": instance.subnet_id, "tags": instance.tags, "virtualization_type": instance.virtualization_type, "vpc_id": instance.vpc_id, } if i_json['public_ip_address'] != None: return i_json['public_ip_address'] self.logger.info("Instance is not ready") time.sleep(10)
class PortfolioManager(Manager): GLOBAL_CONF = config.getGlobalConfig() def createPortfolio(self, params): dao = self.locator.getDAO('portfolio') dic = {} dic['name'] = params['name'] dic['owner'] = params['owner'] if params.has_key('description'): dic['description'] = params['description'] portfolio = dao.insert(dic) return self.locator.getInfo('PortfolioInfo', portfolio) def listPortfolios(self, search, search_or, sort, page): dao = self.locator.getDAO('portfolio') output = [] (portfolios, total_count) = dao.select(search=search, search_or=search_or, sort=sort, page=page) for item in portfolios: info = self.locator.getInfo('PortfolioInfo', item) output.append(info) return (output, total_count) def updatePortfolio(self, params): dao = self.locator.getDAO('portfolio') if not dao.isExist(portfolio_id=params['portfolio_id']): raise ERROR_INVALID_PARAMETER(key='portfolio_id', value=params['portfolio_id']) dic = {} if params.has_key('name'): dic['name'] = params['name'] if params.has_key('description'): dic['description'] = params['description'] if params.has_key('owner'): dic['owner'] = params['owner'] portfolio = dao.update(params['portfolio_id'], dic, 'portfolio_id') return self.locator.getInfo('PortfolioInfo', portfolio) def getPortfolio(self, params): dao = self.locator.getDAO('portfolio') portfolios = dao.getVOfromKey(portfolio_id=params['portfolio_id']) if portfolios.count() == 0: raise ERROR_NOT_FOUND(key='portfolio_id', value=params['portfolio_id']) return self.locator.getInfo('PortfolioInfo', portfolios[0]) def deletePortfolio(self, params): dao = self.locator.getDAO('portfolio') portfolios = dao.getVOfromKey(portfolio_id=params['portfolio_id']) if portfolios.count() == 0: raise ERROR_NOT_FOUND(key='portfolio_id', value=params['portfolio_id']) portfolios.delete() return {}
class BpmnDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def set_up(self, path, name, workflow_id, stack_id, ctx): self.spec = self.load_spec(path, name) self.workflow = PyengineBpmnWorkflow(self.spec, workflow_id=workflow_id, stack_id=stack_id, ctx=ctx) #self.run_engine() def create_workflow(self): self.workflow_spec = self.load_workflow_spec() def load_spec(self, content_path, workflow_name): return self.load_workflow_spec(content_path, workflow_name) def load_workflow_spec(self, content_path, workflow_name): package = InMemoryPackager.package_in_memory(workflow_name, content_path) return BpmnSerializer().deserialize_workflow_spec(package) def run_engine(self): while 1: tasks = self.workflow.get_tasks(state=Task.READY) print len(tasks) if len(tasks) == 0: break for task in tasks: current_node = Node(task) current_node.show() self.workflow.complete_task_from_id(task.id) self.workflow.do_engine_steps() def run(self, template, env, stack_id, ctx): """ @params: -template: -env: -stack_id: """ # 1. Load content self.env = env job = self._loadURI(template) self.logger.debug("JOB:\n%s" % job) # Save as working directory new_path = self._saveTemp(job) # Get workflow_id w_mgr = self.locator.getManager('WorkflowManager') workflow_id = w_mgr.getWorkflowId(template, template_type='bpmn') self.logger.debug("### Workflow ID:%s" % workflow_id) # TODO: update name from server wf_name = 'Process_1' self.set_up(new_path, wf_name, workflow_id, stack_id, ctx) # 2. Run BPMN self.run_engine() # 3. Update Stack state p_mgr = self.locator.getManager('PackageManager') p_mgr.updateStackState(stack_id, "running") def _loadURI(self, uri): """ @param: - uri @return: - content load content from uri """ r = requests.get(uri) if r.status_code == 200: return r.text raise ERROR_NOT_FOUND(key='template', value=uri) def _saveTemp(self, content): """ @param: - content @return: - saved file path """ SAVE_DIR = '/tmp' new_path = '%s/%s' % (SAVE_DIR, uuid.uuid4()) fp = open(new_path, 'w') fp.write(content) fp.close() return new_path
class DockerDriver(Manager): GLOBAL_CONF = config.getGlobalConfig() def discover(self, param, ctx): """ NOT implemented """ # return Zones return ([], 0) ############################################### # Deploy ############################################### def deployServer(self, auth, zone_id, req): """ @param : auth {"auth":{ "access_key_id":"ACCESS Key ID", "secret_access_key":"Secret Access Key", } } @param: zone_id @param: req (Dic) """ # 1. Get Endpoint of Zone cloudMgr = self.locator.getManager('CloudManager') (r_name, z_name) = cloudMgr._getRegionZone(zone_id) docker_info = cloudMgr._getZoneDetail(zone_id) self.logger.debug(docker_info) base_url = docker_info['DOCKER_HOST'] # 2. Create docker client client = Client(base_url=base_url) # 3. Create Server # Add placement based on zone_name self.logger.debug(req) # Pull Image first pulled = client.pull(req['image'], stream=True) self.logger.debug("Pulled Imaged:%s" % pulled) container = client.create_container(**req) response = client.start(container=container.get('Id')) self.logger.debug(response) inspect = client.inspect_container(container.get('Id')) self.logger.debug(inspect) server = {} server['server_id'] = inspect['Id'] server['private_ip_address'] = inspect['NetworkSettings']['IPAddress'] self.logger.debug("Create Server => private IP:%s" % server['private_ip_address']) server['floating_ip'] = inspect['Node']['IP'] # (TODO) This may be private IP # If it is related with Docker Swarm cluster # Find floating IP address of node server['status'] = inspect['State']['Status'] # CPU, Memory, Disk # based on instance_type, get cpu, memory, disk size manaually # notice: There are no API for get CPU, Memory, Disk return server