def delete(self, dependency_creator, source_deployment, target_deployment=None, is_component_deletion=False, external_source=None, external_target=None): """Deletes an inter-deployment dependency. :param dependency_creator: a string representing the entity that is responsible for this dependency (e.g. an intrinsic function blueprint path, 'node_instances.some_node_instance', etc.). :param source_deployment: source deployment that depends on the target deployment. :param target_deployment: the deployment that the source deployment depends on. :param is_component_deletion: a special flag for allowing the deletion of a Component inter-deployment dependency when the target deployment is already deleted. :param external_source: if the source deployment uses an external resource as target, pass here a JSON containing the source deployment metadata, i.e. deployment name, tenant name, and the manager host(s). :param external_target: if the source deployment uses an external resource as target, pass here a JSON containing the target deployment metadata, i.e. deployment name, tenant name, and the manager host(s). :return: an InterDeploymentDependency object. """ data = create_deployment_dependency(dependency_creator, source_deployment, target_deployment, external_source=external_source, external_target=external_target) data['is_component_deletion'] = is_component_deletion self.api.delete('/{self._uri_prefix}'.format(self=self), data=data)
def delete(self): """Deletes an inter-deployment dependency. :param dependency_creator: a string representing the entity that is responsible for this dependency (e.g. an intrinsic function blueprint path, 'node_instances.some_node_instance', etc.). :param source_deployment: source deployment that depends on the target deployment. :param target_deployment: the deployment that the source deployment depends on. :return: an InterDeploymentDependency object containing the information of the dependency. """ sm = get_storage_manager() params = self._get_delete_dependency_params(sm) filters = create_deployment_dependency(params[DEPENDENCY_CREATOR], params[SOURCE_DEPLOYMENT], params[TARGET_DEPLOYMENT]) dependency = sm.get( models.InterDeploymentDependencies, None, filters=filters, # Locking to make sure to fail here and not during the deletion # (for the purpose of clarifying the error in case one occurs). locking=True) return sm.delete(dependency)
def create(self, dependency_creator, source_deployment, target_deployment=None, external_source=None, external_target=None, target_deployment_func=None): """Creates an inter-deployment dependency. :param dependency_creator: a string representing the entity that is responsible for this dependency (e.g. an intrinsic function blueprint path, 'node_instances.some_node_instance', etc.). :param source_deployment: source deployment that depends on the target deployment. :param target_deployment: the deployment that the source deployment depends on. :param external_source: if the source deployment uses an external resource as target, pass here a JSON containing the source deployment metadata, i.e. deployment name, tenant name, and the manager host(s). :param external_target: if the source deployment uses an external resource as target, pass here a JSON containing the target deployment metadata, i.e. deployment name, tenant name, and the manager host(s). :param target_deployment_func: a function used to determine the target deployment. :return: an InterDeploymentDependency object. """ data = create_deployment_dependency(dependency_creator, source_deployment, target_deployment, target_deployment_func, external_source, external_target) response = self.api.put('/{self._uri_prefix}'.format(self=self), data=data) return self._wrapper_cls(response)
def _build_mock_dependency(self, dependency_creator, target_deployment=None): return self.MockDependency( create_deployment_dependency(dependency_creator, self.mock_dep_update.deployment_id, target_deployment))
def __init__(self, operation_inputs): """ Sets the properties that all operations need. :param operation_inputs: The inputs from the operation. """ full_operation_name = ctx.operation.name self.operation_name = full_operation_name.split('.').pop() # Cloudify client setup self.client_config = self._get_desired_operation_input( 'client', operation_inputs) if self.client_config: self.client = CloudifyClient(**self.client_config) else: self.client = manager.get_rest_client() self.plugins = self._get_desired_operation_input( 'plugins', operation_inputs) self.secrets = self._get_desired_operation_input( 'secrets', operation_inputs) self.config = self._get_desired_operation_input( 'resource_config', operation_inputs) # Blueprint-related properties self.blueprint = self.config.get('blueprint', {}) self.blueprint_id = self.blueprint.get('id') or ctx.instance.id self.blueprint_file_name = self.blueprint.get('main_file_name') self.blueprint_archive = self.blueprint.get('blueprint_archive') # Deployment-related properties runtime_deployment_prop = ctx.instance.runtime_properties.get( 'deployment', {}) runtime_deployment_id = runtime_deployment_prop.get('id') self.deployment = self.config.get('deployment', {}) self.deployment_id = (runtime_deployment_id or self.deployment.get('id') or ctx.instance.id) self.deployment_inputs = self.deployment.get('inputs', {}) self.deployment_capabilities = self.deployment.get('capabilities') self.deployment_logs = self.deployment.get('logs', {}) self.deployment_auto_suffix = self.deployment.get( 'auto_inc_suffix', False) # Execution-related properties self.workflow_id = operation_inputs.get( 'workflow_id', 'create_deployment_environment') self.workflow_state = operation_inputs.get('workflow_state', 'terminated') # Polling-related properties self.interval = operation_inputs.get('interval', POLLING_INTERVAL) self.state = operation_inputs.get('state', 'terminated') self.timeout = operation_inputs.get('timeout', EXECUTIONS_TIMEOUT) # Inter-Deployment Dependency identifier self._inter_deployment_dependency = create_deployment_dependency( dependency_creator_generator(COMPONENT, ctx.instance.id), ctx.deployment.id)
def _create_inter_deployment_dependencies(manager_ips: list, client_config, new_dependencies: dict, local_deployment_id: str, local_tenant_name: str, external: bool, ext_deployment_id: str) -> tuple: local_idds = [] external_idds = [] for func_id, deployment_id_func in new_dependencies.items(): target_deployment_id, target_deployment_func = deployment_id_func if external: local_idds += [ create_deployment_dependency( dependency_creator=func_id, target_deployment=None, external_target={ 'deployment': (ext_deployment_id if ext_deployment_id else None), 'client_config': client_config }) ] external_idds += [ create_deployment_dependency( dependency_creator=func_id, target_deployment=(target_deployment_id if target_deployment_id else ' '), external_source={ 'deployment': local_deployment_id, 'tenant': local_tenant_name, 'host': manager_ips, }) ] else: # It should be safe to assume that if the target_deployment # is known, there's no point passing target_deployment_func. # Also because in this case the target_deployment_func will # be of type string, while REST endpoint expects a dict. local_idds += [ create_deployment_dependency( dependency_creator=func_id, target_deployment=target_deployment_id, target_deployment_func=(target_deployment_func if not target_deployment_id else None)) ] return local_idds, external_idds
def setUp(self): super(InterDeploymentDependenciesTest, self).setUp() self.dependency_creator = 'dependency_creator' self.source_deployment = 'source_deployment' self.target_deployment = 'target_deployment' self.dependency = create_deployment_dependency(self.dependency_creator, self.source_deployment, self.target_deployment) self._put_mock_deployments(self.source_deployment, self.target_deployment)
def _prepare_dependent_deployments(self): self.put_deployment(blueprint_file_name='blueprint_with_inputs.yaml', blueprint_id='i{0}'.format(uuid.uuid4()), deployment_id='infra', inputs={'http_web_server_port': 80}) self.put_deployment(blueprint_file_name='blueprint.yaml', blueprint_id='i{0}'.format(uuid.uuid4()), deployment_id='app') self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.vm', 'app', 'infra'))
def _get_delete_dependency_params(sm): request_dict = InterDeploymentDependencies._verify_dependency_params() source_deployment, target_deployment = InterDeploymentDependencies. \ _verify_and_get_source_and_target_deployments( sm, request_dict.get(SOURCE_DEPLOYMENT), request_dict.get(TARGET_DEPLOYMENT)) dependency_params = create_deployment_dependency( request_dict.get(DEPENDENCY_CREATOR), source_deployment, target_deployment) return dependency_params
def _build_mock_dependency(self, dependency_creator, target_deployment=None, target_deployment_func=None): mock_dependency = self.MockDependency( create_deployment_dependency(dependency_creator, self.mock_dep_update.deployment_id, target_deployment)) if target_deployment_func: mock_dependency.update( {'target_deployment_func': target_deployment_func}) return mock_dependency
def _get_put_dependency_params(sm): request_dict = InterDeploymentDependencies._verify_dependency_params() external_source = request_dict.get(EXTERNAL_SOURCE) external_target = request_dict.get(EXTERNAL_TARGET) source_deployment, target_deployment = InterDeploymentDependencies. \ _verify_and_get_source_and_target_deployments( sm, request_dict.get(SOURCE_DEPLOYMENT), request_dict.get(TARGET_DEPLOYMENT), external_source=external_source, external_target=external_target ) dependency_params = create_deployment_dependency( request_dict.get(DEPENDENCY_CREATOR), source_deployment, target_deployment, external_source, external_target) return dependency_params
def __init__(self, operation_inputs): full_operation_name = ctx.operation.name self.operation_name = full_operation_name.split('.').pop() # Cloudify client setup self.client_config = self._get_desired_operation_input( 'client', operation_inputs) if self.client_config: self.client = CloudifyClient(**self.client_config) # for determining an external client: manager_ips = [ mgr.private_ip for mgr in manager.get_rest_client().manager.get_managers() ] internal_hosts = ({'127.0.0.1', 'localhost'} | set(manager_ips)) host = {self.client.host} if type(self.client.host) == str \ else set(self.client.host) self.is_external_host = not (host & internal_hosts) else: self.client = manager.get_rest_client() self.is_external_host = False self.config = self._get_desired_operation_input( 'resource_config', operation_inputs) self.deployment = self.config.get('deployment', '') self.deployment_id = self.deployment.get('id', '') self._inter_deployment_dependency = create_deployment_dependency( dependency_creator_generator(SHARED_RESOURCE, ctx.instance.id), ctx.deployment.id, self.deployment_id) if self.is_external_host: self._local_dependency_params = \ self._inter_deployment_dependency.copy() self._local_dependency_params['target_deployment'] = ' ' self._local_dependency_params['external_target'] = { 'deployment': self.deployment_id, 'client_config': self.client_config } self._inter_deployment_dependency['external_source'] = { 'deployment': ctx.deployment.id, 'tenant': ctx.tenant_name, 'host': manager_ips }
def delete(self, dependency_creator, source_deployment, target_deployment): """Deletes an inter-deployment dependency. :param dependency_creator: a string representing the entity that is responsible for this dependency (e.g. an intrinsic function blueprint path, 'node_instances.some_node_instance', etc.). :param source_deployment: source deployment that depends on the target deployment. :param target_deployment: the deployment that the source deployment depends on. :return: an InterDeploymentDependency object. """ data = create_deployment_dependency(dependency_creator, source_deployment, target_deployment) response = self.api.delete('/{self._uri_prefix}'.format(self=self), data=data) return self._wrapper_cls(response)
def _populate_dependencies_table(self): self._put_mock_deployments('0', '1') self._put_mock_deployments('2', '3') self._put_mock_deployments('4', '5') self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sample.vm', '1', '0')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('capability.host', '2', '0')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('component.infra', '3', '2')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.infra', '3', '1')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.mynode', '4', '0')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('capability.ip', '5', '4'))
def test_retrieve_dependencies_app_with_components(self): # create an IDD system with the following: # a central app `multi` depending on component `comp-top` and on # shared resource `resource`. # `comp-top` depends on `comp-bottom` which is shared with `sharing-1` # `sharing-2` depends on `resource`, `sharing-3` depends on `sharing-1` # and `capable` depends on `multi`. self.put_mock_deployments('capable', 'multi') self.put_mock_deployments('comp-top', 'comp-bottom') self.put_mock_deployments('sharing-2', 'resource') self.put_mock_deployments('sharing-3', 'sharing-1') self.client.inter_deployment_dependencies.create( **create_deployment_dependency('component.teiredcomponent', 'multi', 'comp-top')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.vm', 'multi', 'resource')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.vm', 'sharing-2', 'resource')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('component.infra', 'comp-top', 'comp-bottom')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.node1', 'sharing-1', 'comp-bottom')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('sharedresource.mynode', 'sharing-3', 'sharing-1')) self.client.inter_deployment_dependencies.create( **create_deployment_dependency('capability.ip', 'capable', 'multi')) # if we try to uninstall/update/stop/delete `multi`, # we should be alerted of both its and its components' dependencies dep_graph = RecursiveDeploymentDependencies(self.sm) dep_graph.create_dependencies_graph() dependencies = dep_graph.retrieve_dependent_deployments('multi') self.assertEqual(len(dependencies), 3) self.assertEqual(set(x['deployment'] for x in dependencies), {'capable', 'sharing-1', 'sharing-3'})
def delete(self): """Deletes an inter-deployment dependency. :param dependency_creator: a string representing the entity that is responsible for this dependency (e.g. an intrinsic function blueprint path, 'node_instances.some_node_instance', etc.). :param source_deployment: source deployment that depends on the target deployment. :param target_deployment: the deployment that the source deployment depends on. :param is_component_deletion: a special flag for allowing the deletion of a Component inter-deployment dependency when the target deployment is already deleted. :param external_source: metadata, in JSON format, of the source deployment (deployment name, tenant name, and the manager host(s)), in case it resides on an external manager. None otherwise :param external_target: metadata, in JSON format, of the target deployment (deployment name, tenant name, and the manager host(s)), in case it resides on an external manager. None otherwise :return: an InterDeploymentDependency object containing the information of the dependency. """ sm = get_storage_manager() params = self._get_delete_dependency_params(sm) filters = create_deployment_dependency(params[DEPENDENCY_CREATOR], params.get(SOURCE_DEPLOYMENT), params.get(TARGET_DEPLOYMENT), params.get(EXTERNAL_SOURCE)) dependency = sm.get( models.InterDeploymentDependencies, None, filters=filters, # Locking to make sure to fail here and not during the deletion # (for the purpose of clarifying the error in case one occurs). locking=True) return sm.delete(dependency)
def __init__(self, operation_inputs): full_operation_name = ctx.operation.name self.operation_name = full_operation_name.split('.').pop() # Cloudify client setup self.client_config = self._get_desired_operation_input( 'client', operation_inputs) if self.client_config: self.client = CloudifyClient(**self.client_config) else: self.client = manager.get_rest_client() self.config = self._get_desired_operation_input( 'resource_config', operation_inputs) self.deployment = self.config.get('deployment', '') self.deployment_id = self.deployment.get('id', '') self._inter_deployment_dependency = create_deployment_dependency( dependency_creator_generator(SHARED_RESOURCE, ctx.instance.id), ctx.deployment.id, self.deployment_id )
def set_inter_deployment_dependency(self, target_deployment, function_identifier): dependency_id = str(uuid.uuid4()) source_deployment_instance = self.sm.get( Deployment, self._deployment_id) target_deployment_instance = self.sm.get(Deployment, target_deployment) filters = create_deployment_dependency(function_identifier, source_deployment_instance) init_kwargs = { TARGET_DEPLOYMENT: target_deployment_instance, 'created_at': utils.get_formatted_timestamp(), 'id': dependency_id } init_kwargs.update(filters) dependencies_list = self.sm.list(InterDeploymentDependencies, filters=filters) if dependencies_list: first_dependency = dependencies_list[0] first_dependency.target_deployment = target_deployment_instance self.sm.update(first_dependency) else: self.sm.put(InterDeploymentDependencies(**init_kwargs))