def provision_node_instance(self, instance_id: str, service_id: str, plan_id: str, parameters: dict=None) -> ProvisionedServiceSpec: url = parameters.get("url") if not url: print("Error: {0}\n".format("url not contained in provision parameters!")) return ProvisionedServiceSpec(state="failed") nodes_to_add = parameters.get("nodesToAdd") if not nodes_to_add: print("Error: {0}\n".format("nodes_to_add not contained in provision parameters!")) return ProvisionedServiceSpec(state="failed") add_nodes_items = [] for node_to_add in nodes_to_add: add_nodes_item = ua.AddNodesItem() if "parentNodeId" in node_to_add: add_nodes_item.ParentNodeId = ua.ExpandedNodeId(node_to_add.get("parentNodeId")) if "referenceTypeId" in node_to_add: add_nodes_item.ReferenceTypeId = ua.NodeId(node_to_add.get("referenceTypeId")) if "requestedNewNodeId" in node_to_add: add_nodes_item.RequestedNewNodeId = ua.ExpandedNodeId(node_to_add.get("requestedNewNodeId")) if "browseName" in node_to_add: add_nodes_item.BrowseName = ua.QualifiedName(node_to_add.get("browseName")) if "nodeClass" in node_to_add: add_nodes_item.NodeClass = ua.NodeClass(node_to_add.get("nodeClass")) add_nodes_items.append(add_nodes_item) print(add_nodes_items) client = Client(url) try: client.connect() nodes = [] for add_nodes_item in add_nodes_items: parent_node = client.get_node(add_nodes_item.ParentNodeId) if add_nodes_item.NodeClass == 1: obj = parent_node.add_object(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(obj) elif add_nodes_item.NodeClass == 2: var = parent_node.add_variable(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(var) elif add_nodes_item.NodeClass == 4: method = parent_node.add_method() nodes.append(method) else: folder = parent_node.add_folder(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(folder) service_instance = OpcuaServiceInstance(instance_id, service_id, plan_id, parameters) service_instance.params["nodes"] = nodes service_instance_map = dict() service_instance_map[instance_id] = service_instance self.service_instance_map = service_instance_map except Exception as e: print("Error: {0}\n".format(e)) return ProvisionedServiceSpec(state="failed") print("Node management service instance {0} is provisioned successfully\n".format(instance_id)) return ProvisionedServiceSpec()
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: self.logger.info("starting provision request") if not async_allowed: raise errors.ErrAsyncRequired() params = details.parameters or {} domain_names = parse_domain_options(params) if not domain_names: raise errors.ErrBadRequest("'domains' parameter required.") self.logger.info("validating CNAMEs") validators.CNAME(domain_names).validate() self.logger.info("validating unique domains") if not config.IGNORE_DUPLICATE_DOMAINS: validators.UniqueDomains(domain_names).validate() if details.plan_id == CDN_PLAN_ID: instance = provision_cdn_instance(instance_id, domain_names, params) queue = queue_all_cdn_provision_tasks_for_operation elif details.plan_id == ALB_PLAN_ID: instance = ALBServiceInstance(id=instance_id, domain_names=domain_names) queue = queue_all_alb_provision_tasks_for_operation elif details.plan_id == MIGRATION_PLAN_ID: instance = MigrationServiceInstance(id=instance_id, domain_names=domain_names) db.session.add(instance) db.session.commit() return ProvisionedServiceSpec( state=ProvisionState.SUCCESSFUL_CREATED) else: raise NotImplementedError() self.logger.info("setting origin hostname") self.logger.info("creating operation") operation = Operation( state=Operation.States.IN_PROGRESS.value, service_instance=instance, action=Operation.Actions.PROVISION.value, step_description="Queuing tasks", ) db.session.add(instance) db.session.add(operation) self.logger.info("committing db session") db.session.commit() self.logger.info("queueing tasks") queue(operation.id, cf_logging.FRAMEWORK.context.get_correlation_id()) self.logger.info("all done. Returning provisioned service spec") return ProvisionedServiceSpec(state=ProvisionState.IS_ASYNC, operation=str(operation.id))
def test_provisining_optional_org_and_space_if_available_in_context(self): self.broker.provision.return_value = ProvisionedServiceSpec(dashboard_url="dash_url", operation="operation_str") self.client.put( "/v2/service_instances/here-instance-id", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", }), headers={ "X-Broker-Api-Version": "2.13", "Content-Type": "application/json", "Authorization": self.auth_header }) actual_instance_id, actual_details, actual_async_allowed = self.broker.provision.call_args[0] self.assertEqual(actual_instance_id, "here-instance-id") self.assertEqual(actual_async_allowed, False) self.assertIsInstance(actual_details, ProvisionDetails) self.assertEqual(actual_details.service_id, "service-guid-here") self.assertEqual(actual_details.plan_id, "plan-guid-here") self.assertEqual(actual_details.organization_guid, "org-guid-here") self.assertEqual(actual_details.space_guid, "space-guid-here") self.assertIsNone(actual_details.parameters)
def test_returns_202_if_missing_org_and_space_guids_data_org_space_check_flag_true(self): openbrokerapi.service_broker.DISABLE_SPACE_ORG_GUID_CHECK = True self.broker.provision.return_value = self.broker.provision.return_value = ProvisionedServiceSpec( ProvisionState.IS_ASYNC, "dash_url", "operation_str" ) response = self.client.put( "/v2/service_instances/abc", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) self.assertEqual(response.status_code, http.HTTPStatus.ACCEPTED) self.assertEqual(response.json, dict( dashboard_url="dash_url", operation="operation_str" )) openbrokerapi.service_broker.DISABLE_SPACE_ORG_GUID_CHECK = False
def test_provisining_called_with_the_right_values(self): self.broker.provision.return_value = ProvisionedServiceSpec( dashboard_url="dash_url", operation="operation_str") self.client.put( "/v2/service_instances/here-instance-id?accepts_incomplete=true", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", "parameters": { "parameter1": 1 } }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) actual_instance_id, actual_details, actual_async_allowed = self.broker.provision.call_args[ 0] self.assertEqual(actual_instance_id, "here-instance-id") self.assertEqual(actual_async_allowed, True) self.assertIsInstance(actual_details, ProvisionDetails) self.assertEqual(actual_details.service_id, "service-guid-here") self.assertEqual(actual_details.plan_id, "plan-guid-here") self.assertEqual(actual_details.parameters, dict(parameter1=1)) self.assertEqual(actual_details.organization_guid, "org-guid-here") self.assertEqual(actual_details.space_guid, "space-guid-here")
def provision(self, instance_id: str, service_details: ProvisionDetails, async_allowed: bool) -> ProvisionedServiceSpec: self.logger.info("kubernetes provider - provision called") self.logger.info("kubernetes provider - instance_id:%s" % instance_id) self.logger.info("kubernetes provider - async_allowed:%s" % async_allowed) self.logger.info("kubernetes provider - service_details: %s" % vars(service_details)) if not self.has_plan(service_details.plan_id): raise HTTPException('invalid plan_id', status_code=400) templates = self.load_templates(service_details.plan_id) # merge parameters from 'context' and 'parameters' to templates parameters = { **service_details.parameters, **service_details.context } if not "name" in parameters.keys(): self.logger.info("No 'name' detected. Injecting name based of instance_id=%s" % instance_id) parameters['name']=instance_id self.logger.info("render parameters: %s" % parameters) outputs = self.render_templates(templates,parameters) self.logger.debug( outputs ) self.my_services[instance_id] = [] if not 'name' in parameters.keys(): self.logger.info("No 'name' parameter override found, default name from instance_id") parameters['name']=instance_id for output in outputs.keys(): self.logger.info("Provisioning: %s" % output) KubeHelper.create_from_yaml( outputs[output]['rendered_template'], True) self.my_services[instance_id].append( outputs[output]['rendered_template'] ) # == 'hello-mongodb-kubernetes-operator': # self.logger.info("provision hello-mongodb-kubernetes-operator start") n = parameters['name'] spec = ProvisionedServiceSpec( dashboard_url="mongodb+srv://%s-svc/test?ssl=false" % n, operation="Provisioned MongoDB: %s" % n ) return spec
def provision(self, instance_id: str, service_details: ProvisionDetails, async_allowed: bool) -> ProvisionedServiceSpec: self.logger.info("devops provider - provision called") self.logger.info("devops provider - instance_id:%s" % instance_id) self.logger.info("devops provider - async_allowed:%s" % async_allowed) self.logger.info("devops provider - service_details: %s" % vars(service_details)) if not self.has_plan(service_details.plan_id): raise HTTPException('invalid plan_id', status_code=400) templates = self.load_templates(service_details.plan_id) # merge parameters from 'context' and 'parameters' to templates parameters = {**service_details.parameters, **service_details.context} self.logger.info("render parameters: %s" % parameters) outputs = self.render_templates(templates, parameters) self.logger.debug(outputs) self.my_services[instance_id] = [] for output in outputs.keys(): self.logger.info("Provisioning: %s" % output) KubeHelper.create_from_yaml(outputs[output]['rendered_template'], True) self.my_services[instance_id].append( outputs[output]['rendered_template']) # == 'hello-mongodb-kubernetes-operator': # self.logger.info("provision hello-mongodb-kubernetes-operator start") spec = ProvisionedServiceSpec(dashboard_url='http://ops-manager/sdfsf', operation='some info here') return spec
def test_returns_202_if_provisioning_in_progress(self): self.broker.provision.return_value = ProvisionedServiceSpec( ProvisionState.IS_ASYNC, "dash_url", "operation_str") response = self.client.put("/v2/service_instances/abc", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) self.assertEqual(response.status_code, http.HTTPStatus.ACCEPTED) self.assertEqual( response.json, dict(dashboard_url="dash_url", operation="service-guid-here operation_str"))
def test_provisining_ignores_unknown_parameters(self): self.broker.provision.return_value = ProvisionedServiceSpec( dashboard_url="dash_url", operation="operation_str") self.client.put("/v2/service_instances/here-instance-id", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", "unknown": "unknown" }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) actual_instance_id, actual_details, actual_async_allowed = self.broker.provision.call_args[ 0] self.assertEqual(actual_instance_id, "here-instance-id") self.assertEqual(actual_async_allowed, False) self.assertIsInstance(actual_details, ProvisionDetails) self.assertEqual(actual_details.service_id, "service-guid-here") self.assertEqual(actual_details.plan_id, "plan-guid-here") self.assertEqual(actual_details.organization_guid, "org-guid-here") self.assertEqual(actual_details.space_guid, "space-guid-here") self.assertIsNone(actual_details.parameters)
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: self.service_instances[instance_id] = { 'provision_details': details, 'state': self.CREATED } return ProvisionedServiceSpec(state=ProvisionState.SUCCESSFUL_CREATED)
def create(self, instance, parameters, existing): """ Create the instance Args: instance (AtlasServiceInstance.Instance): Existing or New instance parameters (dict): Parameters for the instance existing (bool): Create an instance on an existing Atlas cluster Returns: ProvisionedServiceSpec: Status Raises: ErrInstanceAlreadyExists: If instance exists but with different parameters ErrClusterNotFound: Cluster does not exist """ if not instance.isProvisioned(): # Set parameters instance.parameters = parameters # Existing cluster if existing and not self.backend.atlas.Clusters.is_existing_cluster(instance.parameters[self.backend.config.PARAMETER_CLUSTER]): # We need to use an existing cluster that is not available ! raise ErrClusterNotFound(instance.parameters[self.backend.config.PARAMETER_CLUSTER]) elif not existing: # We need to create a new cluster # We should not reach this code because the AtlasBroker.provision should # raise an ErrPlanUnsupported before. raise NotImplementedError() result = self.backend.storage.store(instance) # Provision done return ProvisionedServiceSpec(ProvisionState.SUCCESSFUL_CREATED, "", str(result)) elif instance.parameters == parameters: # Identical so nothing to do return ProvisionedServiceSpec(ProvisionState.IDENTICAL_ALREADY_EXISTS, "", "duplicate") else: # Different parameters ... raise ErrInstanceAlreadyExists()
def test_routes_provision(self): operation_str = str(uuid4()) self.b1.provision.return_value = ProvisionedServiceSpec(state=ProvisionState.IS_ASYNC, dashboard_url="dash_url", operation=operation_str) provision = self.router.provision(str(uuid4()), ProvisionDetails('s1', 'p1', str(uuid4()), str(uuid4())), True) self.assertEqual('s1 ' + operation_str, provision.operation) self.assertTrue(self.b1.provision.called)
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: if not async_allowed: raise errors.ErrAsyncRequired() self.service_instances[instance_id] = { 'provision_details': details, 'state': self.CREATING } return ProvisionedServiceSpec(state=ProvisionState.IS_ASYNC, operation='provision')
def provision_discovery_instance(self, instance_id: str, service_id: str, plan_id: str, parameters: dict=None) -> ProvisionedServiceSpec: url = parameters.get("discovery_url") if not url: return ProvisionedServiceSpec(state="failed") client = Client(url) print("Performing discovery at {0}\n".format(url)) try: endpoints = client.connect_and_get_server_endpoints() service_instance = OpcuaServiceInstance(instance_id, service_id, plan_id, parameters) service_instance.params["endpoints"] = endpoints service_instance_map = dict() service_instance_map[instance_id] = service_instance self.service_instance_map = service_instance_map except Exception as e: print("Error: {0}\n".format(e)) return ProvisionedServiceSpec(state="failed") print("Discovery service instance {0} is provisioned successfully\n".format(instance_id)) return ProvisionedServiceSpec()
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: self.logger.info("starting provision request") if not async_allowed: raise errors.ErrAsyncRequired() params = details.parameters or {} if params.get("domains"): domain_names = [ d.strip().lower() for d in params["domains"].split(",") ] else: raise errors.ErrBadRequest("'domains' parameter required.") self.logger.info("validating CNAMEs") validators.CNAME(domain_names).validate() self.logger.info("validating unique domains") validators.UniqueDomains(domain_names).validate() instance = ServiceInstance(id=instance_id, domain_names=domain_names) self.logger.info("setting origin hostname") instance.cloudfront_origin_hostname = params.get( "origin", config.DEFAULT_CLOUDFRONT_ORIGIN) instance.cloudfront_origin_path = params.get("path", "") self.logger.info("creating operation") operation = Operation( state=Operation.States.IN_PROGRESS.value, service_instance=instance, action=Operation.Actions.PROVISION.value, ) db.session.add(instance) db.session.add(operation) self.logger.info("committing db session") db.session.commit() self.logger.info("queueing tasks") queue_all_provision_tasks_for_operation( operation.id, cf_logging.FRAMEWORK.context.get_correlation_id()) self.logger.info("all done. Returning provisioned service spec") return ProvisionedServiceSpec(state=ProvisionState.IS_ASYNC, operation=str(operation.id))
def test_returns_400_if_missing_org_and_space_guids_data(self): self.broker.provision.return_value = self.broker.provision.return_value = ProvisionedServiceSpec( ProvisionState.IS_ASYNC, "dash_url", "operation_str") response = self.client.put("/v2/service_instances/abc", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) self.assertEqual(http.HTTPStatus.BAD_REQUEST, response.status_code) self.assertEqual( dict(description="Organization and space guid are required."), response.json)
def test_returns_200_if_identical_service_exists(self): self.broker.provision.return_value = ProvisionedServiceSpec(ProvisionState.IDENTICAL_ALREADY_EXISTS) response = self.client.put( "/v2/service_instances/abc", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", }), headers={ 'X-Broker-Api-Version': '2.13', 'Content-Type': 'application/json', 'Authorization': self.auth_header }) self.assertEqual(response.status_code, http.HTTPStatus.OK) self.assertEqual(response.json, dict())
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: if not async_allowed: raise errors.ErrAsyncRequired() if instance_id in self.service_instances.keys(): raise errors.ErrInstanceAlreadyExists() self.service_instances[instance_id] = { 'provision_details': details, 'state': self.CREATING } try: project_name = details.parameters.get('project_name') github_id = details.parameters.get('github_id') github_pass = details.parameters.get('github_pass') email_id = details.parameters.get('email') repo_details = jenkins_utils.provision_job(project_name, github_id, github_pass, email_id) # jenkins_utils.provision_job(githib_url) except Exception as e: print(e) raise errors.ServiceException(e) # repo_details = { # 'html_url' : repo.html_url, # 'clone_url': repo.clone_url, # 'hooks_url': repo.hooks_url, # 'hook_id' : hook.id # } self.service_instances[instance_id] = { 'provision_details': details, 'state': self.CREATED, 'project_name': project_name, 'repo_html_url': repo_details.get('html_url'), 'repo_clone_url': repo_details.get('clone_url'), 'repo_hooks_url': repo_details.get('hooks_url'), 'repo_hook_id': repo_details.get('hook_id') } return ProvisionedServiceSpec(state=ProvisionState.IS_ASYNC, operation='provision')
def test_returns_201_if_created(self): self.broker.provision.return_value = ProvisionedServiceSpec( dashboard_url="dash_url", operation="operation_str") response = self.client.put("/v2/service_instances/abc", data=json.dumps({ "service_id": "service-guid-here", "plan_id": "plan-guid-here", "organization_guid": "org-guid-here", "space_guid": "space-guid-here", }), headers={ 'X-Broker-Api-Version': '2.13', 'Authorization': self.auth_header }) self.assertEqual(response.status_code, http.HTTPStatus.CREATED) self.assertEqual( response.json, dict(dashboard_url="dash_url", operation="operation_str"))
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: self.instances[instance_id] = details return ProvisionedServiceSpec()
def provision(self, instance_id: str, details: ProvisionDetails, async_allowed: bool, **kwargs) -> ProvisionedServiceSpec: # Create service instance # ... return ProvisionedServiceSpec()
def provision_subscription_instance(self, instance_id: str, service_id: str, plan_id: str, parameters: dict=None) -> ProvisionedServiceSpec: return ProvisionedServiceSpec()