From 6e0154f222c645e88e89f5edf6d3297cc10fdac0 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 9 Jun 2015 10:08:25 +0300 Subject: [PATCH 001/228] add support of pyvcloud-13rc11(PyYAML==3.11, requests==2.4.3) --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index ee2188d..c7243b6 100644 --- a/setup.py +++ b/setup.py @@ -29,8 +29,8 @@ install_requires=[ 'cloudify-plugins-common>=3.2', 'pyvcloud==13rc10', - 'requests==2.4', + 'requests==2.4.3', 'IPy==0.81', - 'PyYAML==3.10' + 'PyYAML==3.11' ] ) From 9883a4c7b0a854612e768e7236511d9f97d80d19 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 9 Jun 2015 11:44:49 +0300 Subject: [PATCH 002/228] enable ssh connection between nodes in network --- manager_blueprint/vcloud-manager-blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index 276b7ff..ce0e6e8 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -165,7 +165,7 @@ node_templates: name: nodevcloud_security_group edge_gateway: { get_input: edge_gateway } rules: - - source: external + - source: any destination: internal destination_port: 22 action: allow From ba8734e928f2547a12f5251ebc9d4ec4f76077e9 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 11 Jun 2015 17:34:59 +0300 Subject: [PATCH 003/228] Downgrade to PyYAML>=3.10, Upgrade pyvcloud to pyvcloud>=13rc12 for fix conflict with cfy 3.3m1 --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index c7243b6..5887988 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.2', + version='1.3m1', packages=[ 'vcloud_plugin_common', 'server_plugin', @@ -28,9 +28,9 @@ description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.2', - 'pyvcloud==13rc10', - 'requests==2.4.3', + 'pyvcloud>=13rc12', + 'requests>=2.4.0', 'IPy==0.81', - 'PyYAML==3.11' + 'PyYAML>=3.10' ] ) From 04a2b245c9d3c4b1e016c9af95c2de0ebbc3979c Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 16 Jun 2015 12:02:25 +0300 Subject: [PATCH 004/228] Support custom port for ssh --- .../vcloud-manager-blueprint.yaml | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index ce0e6e8..97ff802 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -105,6 +105,12 @@ inputs: For 'ondemand' service type, the value of floating_ip_public_ip can be empty + manager_server_ssh_port: + type: string + default: 22 + description: > + ssh port that can be used for installed node + agents_user: type: string default: ubuntu @@ -165,12 +171,19 @@ node_templates: name: nodevcloud_security_group edge_gateway: { get_input: edge_gateway } rules: - - source: any + - source: internal destination: internal destination_port: 22 action: allow description: > - ssh to management node + ssh between nodes and management node + protocol: TCP + - source: external + destination: internal + destination_port: { get_input: manager_server_ssh_port } + action: allow + description: > + ssh between external net and managment node protocol: TCP - source: external destination: internal @@ -259,7 +272,7 @@ node_templates: translated_port: 443 - type: DNAT protocol: tcp - original_port: 22 + original_port: { get_input: manager_server_ssh_port } translated_port: 22 vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } @@ -351,6 +364,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } relationships: - type: cloudify.relationships.file_system_depends_on_volume target: volume @@ -365,6 +379,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } - type: cloudify.relationships.file_system_contained_in_compute target: manager_server @@ -378,6 +393,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } unlink: implementation: fabric.fabric_plugin.tasks.run_script inputs: @@ -386,6 +402,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } manager: type: cloudify.nodes.CloudifyManager @@ -433,6 +450,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } configure: implementation: fabric.fabric_plugin.tasks.run_module_task inputs: @@ -445,6 +463,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } start: implementation: fabric.fabric_plugin.tasks.run_task inputs: @@ -456,6 +475,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } stop: implementation: fabric.fabric_plugin.tasks.run_module_task inputs: @@ -464,6 +484,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_property: [manager_keypair, private_key_path] } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } delete: implementation: fabric.fabric_plugin.tasks.run_module_task inputs: @@ -472,6 +493,7 @@ node_templates: user: { get_input: manager_server_user } key_filename: { get_property: [manager_keypair, private_key_path] } host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } cloudify.interfaces.validation: creation: implementation: cli.cloudify_cli.bootstrap.tasks.creation_validation From cd17cdec149b992a7bf4050ecea246a1cb79d31c Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 19 Jun 2015 12:15:30 +0300 Subject: [PATCH 005/228] add inputs descriptions --- .../vcloud-manager-blueprint.yaml | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index 97ff802..fc62e0b 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -8,23 +8,36 @@ imports: inputs: vcloud_username: type: string + description: > + User login for vcloud air vcloud_password: type: string + default: '' + description: > + User password for vcloud air - for login by name + password vcloud_token: type: string default: '' + description: > + User token for vcloud air - for login by name + token vcloud_url: type: string + description: > + Vcloud url vcloud_service: type: string + description: > + Vcloud service vcloud_service_type: type: string default: 'subscription' + description: > + Type of service: subscription, ondemand, vcd, private vcloud_instance: type: string @@ -35,6 +48,8 @@ inputs: vcloud_api_version: type: string default: '5.6' + description: > + Version of api, for now 5.6 vcloud_org_url: type: string @@ -47,49 +62,79 @@ inputs: vcloud_org: type: string + description: > + Organization uuid vcloud_vdc: type: string + description: > + Virtual data center name manager_server_name: type: string + description: > + Name for server manager_server_catalog: type: string + description: > + Name of catalog, can be 'Public Catalog' manager_server_template: type: string + description: > + Name of template from catalog, + can be 'Ubuntu Server 12.04 LTS (amd64 20150127)' manager_server_cpus: type: string default: 2 + description: > + Count cpu on node manager_server_memory: type: string default: 4096 + description: > + Amount memmory on node management_network_use_existing: type: boolean default: false + description: > + Use existed network management_network_name: type: string + description: > + Name common network that can be used for nodes as managment + network management_port_ip_allocation_mode: type: string default: pool + description: > + Ip allocation type for case when you doesn't set public ip + for node and want auto allocate ip management_port_ip_address: type: string default: '' + description: > + Port public ip management_network_public_nat_use_existing: type: boolean default: false + description: > + Use already existed nat rules, only for case when you + doesn't want to change nat rules management_network_public_ip: type: string default: '' + description: > + Manager network public ip (used for SNAT) edge_gateway: type: string @@ -109,52 +154,73 @@ inputs: type: string default: 22 description: > - ssh port that can be used for installed node + SSH port that can be used for installed node agents_user: type: string default: ubuntu + description: > + User name that will be used for agent manager_server_user: default: ubuntu type: string + description: > + User name that will be used for login to manager manager_private_key_path: default: ~/.ssh/cloudify-manager-kp.pem type: string + description: > + Private key for manager agent_private_key_path: default: ~/.ssh/cloudify-agent-kp.pem type: string + description: > + Private key for agent manager_public_key: type: string default: '' + description: > + Public key for manager agent_public_key: type: string default: '' + description: > + Public key for agent resources_prefix: type: string default: '' + description: > + Prefix for node name volume_use_external: type: boolean default: false + description: > + Use alredy exised volume volume_external_name: type: string default: '' + description: > + Volume resource id volume_name: type: string default: 'manager_disk' + description: > + Volume name volume_size_Mb: type: string default: 10240 - + description: > + Volume size in Mb node_types: vcloud_configuration: From 6744bc041663863ad331c293e08ec661343a22aa Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 3 Jul 2015 13:10:06 +0400 Subject: [PATCH 006/228] CFY-3081 Cannot create NAT rules with SNAT and DNAT in the same node. --- network_plugin/public_nat.py | 10 ++++++++++ plugin.yaml | 3 +++ 2 files changed, 13 insertions(+) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 70a92ee..43527f0 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -27,6 +27,16 @@ PORT_REPLACEMENT = 'port_replacement' +@operation +@with_vca_client +def net_connect_to_nat_preconfigure(vca_client, **kwargs): + for rule in ctx.target.node.properties['rules']: + if rule['type'].lower() == 'dnat': + raise cfy_exc.NonRecoverableError( + "In 'cloudify.vcloud.net_connected_to_public_nat' relationship" + " you can use only 'SNAT' rules.") + + @operation @with_vca_client def net_connect_to_nat(vca_client, **kwargs): diff --git a/plugin.yaml b/plugin.yaml index 7c2ef43..173784f 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -183,6 +183,9 @@ relationships: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: + preconfigure: + implementation: vcloud.network_plugin.public_nat.net_connect_to_nat_preconfigure + inputs: {} establish: implementation: vcloud.network_plugin.public_nat.net_connect_to_nat inputs: {} From bcdb9cb5ff5f468b72e9372a6fc2117d21be97a4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 3 Jul 2015 13:39:32 +0400 Subject: [PATCH 007/228] CFY-3081 Add unittests --- .../test_mock_network_plugin_public_nat.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 1df8088..40b7e5f 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -995,5 +995,37 @@ def test_net_connect_to_nat(self): 'any', 'any' ) + def test_net_connect_to_nat_preconfigure(self): + fake_client, fake_ctx = self.generate_client_and_context_network() + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'DNAT' + }] + } + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + + fake_client, fake_ctx = self.generate_client_and_context_network() + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'SNAT' + }] + } + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + if __name__ == '__main__': unittest.main() From c6090628c8138e1915b083b981bdea2b9a135c12 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 3 Jul 2015 14:38:29 +0400 Subject: [PATCH 008/228] CFY-3081 Add more strict checking --- network_plugin/public_nat.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 43527f0..f188280 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -30,11 +30,14 @@ @operation @with_vca_client def net_connect_to_nat_preconfigure(vca_client, **kwargs): - for rule in ctx.target.node.properties['rules']: - if rule['type'].lower() == 'dnat': + rules = ctx.target.node.properties['rules'] + if len(rules) != 1: + raise cfy_exc.NonRecoverableError( + "Rules list must contains only one element") + if rules[0]['type'].lower() == 'dnat': raise cfy_exc.NonRecoverableError( "In 'cloudify.vcloud.net_connected_to_public_nat' relationship" - " you can use only 'SNAT' rules.") + " you can use only 'SNAT' rule.") @operation @@ -138,7 +141,10 @@ def prepare_server_operation(vca_client, operation): vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = get_vm_ip(vca_client, ctx, gateway) + has_snat = False for rule in ctx.target.node.properties['rules']: + if has_snat: + ctx.logger.info("Rules list must contains only one SNAT rule.") rule_type = rule['type'] protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") @@ -147,6 +153,8 @@ def prepare_server_operation(vca_client, operation): vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) + if rule_type == "SNAT": + has_snat = True except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) _save_configuration(gateway, vca_client, operation, public_ip) From 6ea17247214c8ce243a9f7b53ca910c634bf4124 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 3 Jul 2015 14:40:21 +0400 Subject: [PATCH 009/228] CFY-3081 Fix logic --- network_plugin/public_nat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index f188280..d49b8e1 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -145,6 +145,7 @@ def prepare_server_operation(vca_client, operation): for rule in ctx.target.node.properties['rules']: if has_snat: ctx.logger.info("Rules list must contains only one SNAT rule.") + continue rule_type = rule['type'] protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") From d82febfcb6ad00530abf50b010a90091eede55e5 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 6 Jul 2015 12:54:49 +0400 Subject: [PATCH 010/228] CFY-3103 Update gateway by two nodes simultaneously, causes the error --- network_plugin/__init__.py | 38 +++++++++++++++++++------------- network_plugin/floatingip.py | 4 +--- network_plugin/network.py | 4 +--- network_plugin/public_nat.py | 5 ++--- network_plugin/security_group.py | 4 +--- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index e0a1e26..1849caf 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -1,3 +1,4 @@ +import time from IPy import IP from cloudify import exceptions as cfy_exc import collections @@ -10,6 +11,8 @@ NAT_ROUTED = 'natRouted' CREATE = 1 DELETE = 2 +GATEWAY_TRY_COUNT = 10 +GATEWAY_TIMEOUT = 30 AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') @@ -131,24 +134,29 @@ def get_vapp_name(runtime_properties): return vapp_name -def save_gateway_configuration(gateway, vca_client): +def save_gateway_configuration(gateway, ctx, vca_client): """ save gateway configuration, - return - True - everything successfully finished - False - gateway busy - raise NonRecoverableError - can't get task description - """ - task = gateway.save_services_configuration() - if task: - wait_for_task(vca_client, task) - return True - else: - error = taskType.parseString(gateway.response.content, True) - if BUSY_MESSAGE in error.message: - return False + return everything successfully finished + raise NonRecoverableError - can't get task description + """ + for count in range(GATEWAY_TRY_COUNT): + ctx.logger.info("Saving gateway configuration. Retry {} of {}" + .format(count + 1, GATEWAY_TRY_COUNT)) + task = gateway.save_services_configuration() + if task: + wait_for_task(vca_client, task) + return else: - raise cfy_exc.NonRecoverableError(error.message) + error = taskType.parseString(gateway.response.content, True) + if BUSY_MESSAGE in error.message: + ctx.logger.info("Gateway is busy. Waiting for {} seconds.".format(GATEWAY_TIMEOUT)) + time.sleep(GATEWAY_TIMEOUT) + else: + raise cfy_exc.NonRecoverableError(error.message) + ctx.logger.info() + raise cfy_exc.NonRecoverableError("Can't save gateway configuration." + "The maximum number of save attempts has been exceed.") def getFreeIP(gateway): diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 09dc613..01f4aea 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -90,9 +90,7 @@ def _floatingip_operation(operation, vca_client, ctx): nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) - if not save_gateway_configuration(gateway, vca_client): - return ctx.operation.retry(message='Waiting for gateway.', - retry_after=10) + save_gateway_configuration(gateway, ctx, vca_client) if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip diff --git a/network_plugin/network.py b/network_plugin/network.py index 0319284..bafff2e 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -199,9 +199,7 @@ def _dhcp_operation(vca_client, network_name, operation): ctx.logger.info("DHCP rule successful deleted for network {0}" .format(network_name)) - if not save_gateway_configuration(gateway, vca_client): - return ctx.operation.retry(message='Waiting for gateway.', - retry_after=10) + save_gateway_configuration(gateway, ctx, vca_client) def _split_adresses(address_range): diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index d49b8e1..5f0a96a 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -207,9 +207,8 @@ def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ - if not save_gateway_configuration(gateway, vca_client): - return ctx.operation.retry(message='Waiting for gateway.', - retry_after=10) + save_gateway_configuration(gateway, ctx, vca_client) + ctx.logger.info("NAT configuration has been saved") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index dfb6b71..b2deb66 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -121,9 +121,7 @@ def _rule_operation(operation, vca_client): ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) - if not save_gateway_configuration(gateway, vca_client): - return ctx.operation.retry(message='Waiting for gateway.', - retry_after=10) + save_gateway_configuration(gateway, ctx, vca_client) def _get_gateway_name(properties): From 0b9d6eaff5100d7e77cb04608026265843b005ad Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 6 Jul 2015 13:55:27 +0400 Subject: [PATCH 011/228] CFY-3103 Update gateway by two nodes simultaneously, causes the error Update unit tests --- tests/unittests/test_mock_base.py | 3 +++ tests/unittests/test_mock_network_plugin.py | 15 ++++++++------- .../test_mock_network_plugin_floatingip.py | 16 ++++++++-------- ...est_mock_network_plugin_network_subroutes.py | 11 +++++------ .../test_mock_network_plugin_public_nat.py | 11 +++++------ .../test_mock_network_plugin_security_group.py | 17 ++++++++--------- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 6de4569..af8a23a 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -16,6 +16,9 @@ import unittest from cloudify import mocks as cfy_mocks from network_plugin import BUSY_MESSAGE, NAT_ROUTED +import network_plugin +network_plugin.GATEWAY_TRY_COUNT = 2 +network_plugin.GATEWAY_TIMEOUT = 1 class TestBase(unittest.TestCase): diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 0d7b1ad..e0141b3 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -183,13 +183,14 @@ def test_save_gateway_configuration(self): """ gateway = self.generate_gateway() fake_client = self.generate_client() + fake_ctx = self.generate_relation_context() # cant save configuration - error in first call self.set_services_conf_result( gateway, None ) with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_client + gateway, fake_ctx, fake_client ) # error in status self.set_services_conf_result( @@ -197,15 +198,15 @@ def test_save_gateway_configuration(self): ) with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_client + gateway, fake_ctx, fake_client ) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - self.assertTrue( + self.assertIsNone( network_plugin.save_gateway_configuration( - gateway, fake_client + gateway, fake_ctx, fake_client ) ) # server busy @@ -213,11 +214,11 @@ def test_save_gateway_configuration(self): gateway, None ) self.set_gateway_busy(gateway) - self.assertFalse( + with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_client + gateway, fake_ctx, fake_client ) - ) + def test_is_network_routed(self): """ diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 34fcca5..6245275 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -239,10 +239,10 @@ def test_floatingip_operation_delete(self): with mock.patch( 'network_plugin.floatingip.ctx', fake_ctx ): - floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx - ) - self.check_retry_realy_called(fake_ctx) + with self.assertRaises(cfy_exc.NonRecoverableError): + floatingip._floatingip_operation( + network_plugin.DELETE, fake_client, fake_ctx + ) # busy in save with ip in runtime_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() self.set_services_conf_result( @@ -264,10 +264,10 @@ def test_floatingip_operation_delete(self): with mock.patch( 'network_plugin.floatingip.ctx', fake_ctx ): - floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx - ) - self.check_retry_realy_called(fake_ctx) + with self.assertRaises(cfy_exc.NonRecoverableError): + floatingip._floatingip_operation( + network_plugin.DELETE, fake_client, fake_ctx + ) # unknow operation fake_client, fake_ctx = self.generate_client_and_context_floating_ip() fake_ctx._target.node.properties = { diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 2f88d69..9f35e3a 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -113,12 +113,11 @@ def test__dhcp_operation(self): # returned busy, try next time self.set_gateway_busy(fake_client._vdc_gateway) self.prepare_retry(fake_ctx) - - network._dhcp_operation( - fake_client, '_management_network', - network.DELETE_POOL - ), None - self.check_retry_realy_called(fake_ctx) + with self.assertRaises(cfy_exc.NonRecoverableError): + network._dhcp_operation( + fake_client, '_management_network', + network.DELETE_POOL + ) # no such gateway fake_client.get_gateway = mock.MagicMock(return_value=None) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 40b7e5f..3f219bc 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -132,7 +132,7 @@ def test_get_original_port_for_create_with_ctx(self): self.assertEqual( fake_ctx._target.instance.runtime_properties, { - public_nat.PORT_REPLACEMENT: { + public_nat.PORT_REPLACEMENT: { ('external', '10'): 11 } } @@ -392,11 +392,10 @@ def _ip_exist_in_runtime(fake_ctx): with mock.patch( 'network_plugin.public_nat.ctx', fake_ctx ): - self.prepare_retry(fake_ctx) - public_nat._save_configuration( - gateway, fake_client, "any", "any" - ) - self.check_retry_realy_called(fake_ctx) + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat._save_configuration( + gateway, fake_client, "any", "any" + ) # operation create fake_ctx = self.generate_relation_context() self.set_services_conf_result( diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index eb56c05..786f8d2 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -111,7 +111,8 @@ def test_rule_operation_empty_rule(self): ]: gateway = self.check_rule_operation(rule_type, []) gateway.save_services_configuration.assert_called_once_with() - self.check_rule_operation_fail(rule_type, []) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.check_rule_operation_fail(rule_type, []) self.assertFalse(gateway.add_fw_rule.called) self.assertFalse(gateway.delete_fw_rule.called) @@ -126,13 +127,12 @@ def test_rule_operation_default_rule(self): True, 'Rule added by pyvcloud', 'allow', 'Any', 'any', 'external', 'any', 'external', False ) - self.assertFalse(gateway.delete_fw_rule.called) else: gateway.delete_fw_rule.assert_called_once_with( 'Any', 'any', 'external', 'any', 'external' ) - self.assertFalse(gateway.add_fw_rule.called) - self.check_rule_operation_fail(rule_type, [{}]) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.check_rule_operation_fail(rule_type, [{}]) def test_rule_operation_internal_rule(self): for rule_type in [ @@ -163,7 +163,8 @@ def test_rule_operation_internal_rule(self): 'Tcp', '40', 'internal', '22', 'external' ) self.assertFalse(gateway.add_fw_rule.called) - self.check_rule_operation_fail(rule_type, rules) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_icmp_rule(self): for rule_type in [ @@ -194,7 +195,8 @@ def test_rule_operation_icmp_rule(self): 'Icmp', '22', '5.6.7.8', '60', '1.2.3.4' ) self.assertFalse(gateway.add_fw_rule.called) - self.check_rule_operation_fail(rule_type, rules) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_tcp_rule(self): for rule_type in [ @@ -219,13 +221,10 @@ def test_rule_operation_tcp_rule(self): True, 'ip', 'deny', 'Tcp', '22', '5.6.7.8', '60', '1.2.3.4', True ) - self.assertFalse(gateway.delete_fw_rule.called) else: gateway.delete_fw_rule.assert_called_once_with( 'Tcp', '22', '5.6.7.8', '60', '1.2.3.4' ) - self.assertFalse(gateway.add_fw_rule.called) - self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_host_rule(self): for rule_type in [ From a2550b0b41ae821c15b58313cee8d41eb78f8d3b Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 6 Jul 2015 14:05:52 +0400 Subject: [PATCH 012/228] CFY-3103 Style fix --- tests/unittests/test_mock_network_plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index e0141b3..96b00e9 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -219,7 +219,6 @@ def test_save_gateway_configuration(self): gateway, fake_ctx, fake_client ) - def test_is_network_routed(self): """ check network route state @@ -282,7 +281,7 @@ def test_check_port(self): utils.check_port(10) # port int to big with self.assertRaises(cfy_exc.NonRecoverableError): - utils.check_port(utils.MAX_PORT_NUMBER+1) + utils.check_port(utils.MAX_PORT_NUMBER + 1) # port any utils.check_port('any') # port not any and not int From c4b37527c63946fe00e97535099a5f5beedfa82f Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 6 Jul 2015 14:25:35 +0400 Subject: [PATCH 013/228] CFY-3103 Style fixes --- network_plugin/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 1849caf..b50a20b 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -150,13 +150,15 @@ def save_gateway_configuration(gateway, ctx, vca_client): else: error = taskType.parseString(gateway.response.content, True) if BUSY_MESSAGE in error.message: - ctx.logger.info("Gateway is busy. Waiting for {} seconds.".format(GATEWAY_TIMEOUT)) + ctx.logger.info("Gateway is busy. Waiting for {} seconds." + .format(GATEWAY_TIMEOUT)) time.sleep(GATEWAY_TIMEOUT) else: raise cfy_exc.NonRecoverableError(error.message) ctx.logger.info() raise cfy_exc.NonRecoverableError("Can't save gateway configuration." - "The maximum number of save attempts has been exceed.") + "The maximum number of save" + " attempts has been exceed.") def getFreeIP(gateway): From c596acdd496c0eae20f55381b56793cc15bba9ca Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 8 Jul 2015 12:19:50 +0400 Subject: [PATCH 014/228] CFY-3103 Update gateway by two nodes simultaneously, causes the error --- network_plugin/__init__.py | 41 ++++---- network_plugin/floatingip.py | 17 +++- network_plugin/network.py | 95 ++++++++++--------- network_plugin/public_nat.py | 49 ++++++---- network_plugin/security_group.py | 12 ++- server_plugin/server.py | 9 +- tests/unittests/test_mock_base.py | 3 +- tests/unittests/test_mock_network_plugin.py | 16 ++-- .../test_mock_network_plugin_floatingip.py | 14 ++- ...t_mock_network_plugin_network_subroutes.py | 10 +- .../test_mock_network_plugin_public_nat.py | 10 +- ...test_mock_network_plugin_security_group.py | 24 +++-- 12 files changed, 163 insertions(+), 137 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index b50a20b..f05f472 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -1,4 +1,3 @@ -import time from IPy import IP from cloudify import exceptions as cfy_exc import collections @@ -6,18 +5,19 @@ from vcloud_plugin_common import (wait_for_task, get_vcloud_config, is_subscription) + VCLOUD_VAPP_NAME = 'vcloud_vapp_name' PUBLIC_IP = 'public_ip' NAT_ROUTED = 'natRouted' CREATE = 1 DELETE = 2 -GATEWAY_TRY_COUNT = 10 -GATEWAY_TIMEOUT = 30 AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') BUSY_MESSAGE = "The entity gateway is busy completing an operation." +GATEWAY_TIMEOUT = 30 + def check_ip(address): """ @@ -134,31 +134,22 @@ def get_vapp_name(runtime_properties): return vapp_name -def save_gateway_configuration(gateway, ctx, vca_client): +def save_gateway_configuration(gateway, vca_client): """ save gateway configuration, return everything successfully finished raise NonRecoverableError - can't get task description """ - for count in range(GATEWAY_TRY_COUNT): - ctx.logger.info("Saving gateway configuration. Retry {} of {}" - .format(count + 1, GATEWAY_TRY_COUNT)) - task = gateway.save_services_configuration() - if task: - wait_for_task(vca_client, task) - return + task = gateway.save_services_configuration() + if task: + wait_for_task(vca_client, task) + return True + else: + error = taskType.parseString(gateway.response.content, True) + if BUSY_MESSAGE in error.message: + return False else: - error = taskType.parseString(gateway.response.content, True) - if BUSY_MESSAGE in error.message: - ctx.logger.info("Gateway is busy. Waiting for {} seconds." - .format(GATEWAY_TIMEOUT)) - time.sleep(GATEWAY_TIMEOUT) - else: - raise cfy_exc.NonRecoverableError(error.message) - ctx.logger.info() - raise cfy_exc.NonRecoverableError("Can't save gateway configuration." - "The maximum number of save" - " attempts has been exceed.") + raise cfy_exc.NonRecoverableError(error.message) def getFreeIP(gateway): @@ -291,3 +282,9 @@ def get_gateway(vca_client, gateway_name): raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) return gateway + + +def set_retry(ctx): + return ctx.operation.retry( + message='Waiting for gateway.', + retry_after=GATEWAY_TIMEOUT) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 01f4aea..7697a93 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -7,7 +7,8 @@ CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, CREATE, DELETE, PUBLIC_IP, get_gateway, - get_public_ip, del_ondemand_public_ip) + get_public_ip, del_ondemand_public_ip, + set_retry) @operation @@ -16,7 +17,8 @@ def connect_floatingip(vca_client, **kwargs): """ create new floating ip for node """ - _floatingip_operation(CREATE, vca_client, ctx) + if not _floatingip_operation(CREATE, vca_client, ctx): + return set_retry(ctx) @operation @@ -25,7 +27,8 @@ def disconnect_floatingip(vca_client, **kwargs): """ release floating ip """ - _floatingip_operation(DELETE, vca_client, ctx) + if not _floatingip_operation(DELETE, vca_client, ctx): + return set_retry(ctx) @operation @@ -63,6 +66,8 @@ def _floatingip_operation(operation, vca_client, ctx): service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) + if gateway.is_busy(): + return False internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None @@ -90,8 +95,9 @@ def _floatingip_operation(operation, vca_client, ctx): nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) - save_gateway_configuration(gateway, ctx, vca_client) - + success = save_gateway_configuration(gateway, vca_client) + if not success: + return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip else: @@ -103,6 +109,7 @@ def _floatingip_operation(operation, vca_client, ctx): ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP] + return True def _add_nat_rule(gateway, rule_type, original_ip, translated_ip): diff --git a/network_plugin/network.py b/network_plugin/network.py index bafff2e..e51f0f2 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -20,10 +20,12 @@ import collections from network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, is_ips_in_same_subnet, save_gateway_configuration, - get_network_name, is_network_exists) + get_network_name, is_network_exists, + get_gateway, set_retry) VCLOUD_NETWORK_NAME = 'vcloud_network_name' +SKIP_CREATE_NETWORK = 'skip_create_network' ADD_POOL = 1 DELETE_POOL = 2 @@ -59,44 +61,46 @@ def create(vca_client, **kwargs): ctx.logger.info( "External resource {0} has been used".format(network_name)) return - net_prop = ctx.node.properties["network"] network_name = get_network_name(ctx.node.properties) - if network_name in _get_network_list(vca_client, - get_vcloud_config()['vdc']): - raise cfy_exc.NonRecoverableError( - "Network {0} already exists, but parameter " - "'use_external_resource' is 'false' or absent" - .format(network_name)) - - ip = _split_adresses(net_prop['static_range']) - gateway_name = net_prop['edge_gateway'] - if not vca_client.get_gateway(vdc_name, gateway_name): - raise cfy_exc.NonRecoverableError( - "Gateway {0} not found".format(gateway_name)) - start_address = ip.start - end_address = ip.end - gateway_ip = net_prop["gateway_ip"] - netmask = net_prop["netmask"] - dns1 = "" - dns2 = "" - dns_list = net_prop.get("dns") - if dns_list: - dns1 = dns_list[0] - if len(dns_list) > 1: - dns2 = dns_list[1] - dns_suffix = net_prop.get("dns_suffix") - success, result = vca_client.create_vdc_network( - vdc_name, network_name, gateway_name, start_address, - end_address, gateway_ip, netmask, dns1, dns2, dns_suffix) - if success: - ctx.logger.info("Network {0} has been successfully created." - .format(network_name)) - else: - raise cfy_exc.NonRecoverableError( - "Could not create network {0}: {1}".format(network_name, result)) - wait_for_task(vca_client, result) - ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name - _dhcp_operation(vca_client, network_name, ADD_POOL) + if not ctx.instance.runtime_properties.get(SKIP_CREATE_NETWORK): + net_prop = ctx.node.properties["network"] + if network_name in _get_network_list(vca_client, + get_vcloud_config()['vdc']): + raise cfy_exc.NonRecoverableError( + "Network {0} already exists, but parameter " + "'use_external_resource' is 'false' or absent" + .format(network_name)) + + ip = _split_adresses(net_prop['static_range']) + gateway_name = net_prop['edge_gateway'] + get_gateway(vca_client, gateway_name) + start_address = ip.start + end_address = ip.end + gateway_ip = net_prop["gateway_ip"] + netmask = net_prop["netmask"] + dns1 = "" + dns2 = "" + dns_list = net_prop.get("dns") + if dns_list: + dns1 = dns_list[0] + if len(dns_list) > 1: + dns2 = dns_list[1] + dns_suffix = net_prop.get("dns_suffix") + success, result = vca_client.create_vdc_network( + vdc_name, network_name, gateway_name, start_address, + end_address, gateway_ip, netmask, dns1, dns2, dns_suffix) + if success: + ctx.logger.info("Network {0} has been successfully created." + .format(network_name)) + else: + raise cfy_exc.NonRecoverableError( + "Could not create network {0}: {1}". + format(network_name, result)) + wait_for_task(vca_client, result) + ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name + if not _dhcp_operation(vca_client, network_name, ADD_POOL): + ctx.instance.runtime_properties[SKIP_CREATE_NETWORK] = True + return set_retry(ctx) @operation @@ -111,7 +115,8 @@ def delete(vca_client, **kwargs): " been used") return network_name = get_network_name(ctx.node.properties) - _dhcp_operation(vca_client, network_name, DELETE_POOL) + if not _dhcp_operation(vca_client, network_name, DELETE_POOL): + return set_retry(ctx) success, task = vca_client.delete_vdc_network( get_vcloud_config()['vdc'], network_name) if success: @@ -176,13 +181,11 @@ def _dhcp_operation(vca_client, network_name, operation): """ dhcp_settings = ctx.node.properties['network'].get('dhcp') if dhcp_settings is None: - return + return True gateway_name = ctx.node.properties["network"]['edge_gateway'] - gateway = vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name) - if not gateway: - raise cfy_exc.NonRecoverableError( - "Gateway {0} not found!".format(gateway_name)) - + gateway = get_gateway(vca_client, gateway_name) + if gateway.is_busy(): + return False if operation == ADD_POOL: ip = _split_adresses(dhcp_settings['dhcp_range']) low_ip_address = check_ip(ip.start) @@ -199,7 +202,7 @@ def _dhcp_operation(vca_client, network_name, operation): ctx.logger.info("DHCP rule successful deleted for network {0}" .format(network_name)) - save_gateway_configuration(gateway, ctx, vca_client) + return save_gateway_configuration(gateway, vca_client) def _split_adresses(address_range): diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 5f0a96a..0c1f1a8 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -20,7 +20,7 @@ from network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, - del_ondemand_public_ip, utils) + del_ondemand_public_ip, utils, set_retry) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP @@ -34,7 +34,7 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): if len(rules) != 1: raise cfy_exc.NonRecoverableError( "Rules list must contains only one element") - if rules[0]['type'].lower() == 'dnat': + if _is_dnat(rules[0]['type']): raise cfy_exc.NonRecoverableError( "In 'cloudify.vcloud.net_connected_to_public_nat' relationship" " you can use only 'SNAT' rule.") @@ -49,7 +49,8 @@ def net_connect_to_nat(vca_client, **kwargs): if ctx.target.node.properties.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return - prepare_network_operation(vca_client, CREATE) + if not prepare_network_operation(vca_client, CREATE): + return set_retry(ctx) @operation @@ -61,7 +62,8 @@ def net_disconnect_from_nat(vca_client, **kwargs): if ctx.target.node.properties.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return - prepare_network_operation(vca_client, DELETE) + if not prepare_network_operation(vca_client, DELETE): + return set_retry(ctx) @operation @@ -70,7 +72,8 @@ def server_connect_to_nat(vca_client, **kwargs): """ create nat rules for server """ - prepare_server_operation(vca_client, CREATE) + if not prepare_server_operation(vca_client, CREATE): + return set_retry(ctx) @operation @@ -79,7 +82,8 @@ def server_disconnect_from_nat(vca_client, **kwargs): """ drop nat rules for server """ - prepare_server_operation(vca_client, DELETE) + if not prepare_server_operation(vca_client, DELETE): + return set_retry(ctx) @operation @@ -98,7 +102,7 @@ def creation_validation(vca_client, **kwargs): if is_subscription(service_type): getFreeIP(gateway) for rule in get_mandatory(ctx.node.properties, 'rules'): - if rule['type'] == "DNAT": + if _is_dnat(rule['type']): utils.check_protocol(rule.get('protocol')) original_port = rule.get('original_port') if original_port and not isinstance(original_port, int): @@ -129,7 +133,7 @@ def prepare_network_operation(vca_client, operation): raise cfy_exc.NonRecoverableError( "Parameter not found: {0}".format(e) ) - _save_configuration(gateway, vca_client, operation, public_ip) + return _save_configuration(gateway, vca_client, operation, public_ip) def prepare_server_operation(vca_client, operation): @@ -143,10 +147,10 @@ def prepare_server_operation(vca_client, operation): private_ip = get_vm_ip(vca_client, ctx, gateway) has_snat = False for rule in ctx.target.node.properties['rules']: - if has_snat: + rule_type = rule['type'] + if has_snat and _is_snat(rule_type): ctx.logger.info("Rules list must contains only one SNAT rule.") continue - rule_type = rule['type'] protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") @@ -154,11 +158,11 @@ def prepare_server_operation(vca_client, operation): vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) - if rule_type == "SNAT": + if _is_snat(rule_type): has_snat = True except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) - _save_configuration(gateway, vca_client, operation, public_ip) + return _save_configuration(gateway, vca_client, operation, public_ip) def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, @@ -185,7 +189,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, info_message = ("{6} NAT rule: rule type '{2}', original_ip '{0}', " "translated_ip '{1}',protocol '{3}', " "original_port '{4}', translated_port '{5}'") - if rule_type == "SNAT": + if _is_snat(rule_type): # for SNAT type ports and protocol must by "any", # because they are not configurable ctx.logger.info( @@ -194,21 +198,25 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, message)) function( rule_type, private_ip, "any", public_ip, "any", "any") - elif rule_type == "DNAT": + elif _is_dnat(rule_type): ctx.logger.info( info_message.format(public_ip, private_ip, rule_type, protocol, new_original_port, translated_port, message)) function(rule_type, public_ip, str(new_original_port), private_ip, str(translated_port), protocol) + else: + raise cfy_exc.NonRecoverableError( + "Unknown rule type: {0}".format(rule_type)) def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ - save_gateway_configuration(gateway, ctx, vca_client) - + success = save_gateway_configuration(gateway, vca_client) + if not success: + return False ctx.logger.info("NAT configuration has been saved") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip @@ -222,6 +230,7 @@ def _save_configuration(gateway, vca_client, operation, public_ip): ctx ) del ctx.target.instance.runtime_properties[PUBLIC_IP] + return True def _create_ip_range(vca_client, gateway): @@ -385,3 +394,11 @@ def _is_rule_exists(nat_rules, rule_type, else: return False return True + + +def _is_snat(value): + return value.upper() == 'SNAT' + + +def _is_dnat(value): + return value.upper() == 'DNAT' diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index b2deb66..f765442 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -4,7 +4,7 @@ from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) from network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, - get_gateway, utils) + get_gateway, utils, set_retry) CREATE_RULE = 1 @@ -20,7 +20,8 @@ def create(vca_client, **kwargs): """ create firewall rules for node """ - _rule_operation(CREATE_RULE, vca_client) + if not _rule_operation(CREATE_RULE, vca_client): + return set_retry(ctx) @operation @@ -29,7 +30,8 @@ def delete(vca_client, **kwargs): """ drop firewall rules for node """ - _rule_operation(DELETE_RULE, vca_client) + if not _rule_operation(DELETE_RULE, vca_client): + return set_retry(ctx) @operation @@ -91,6 +93,8 @@ def _rule_operation(operation, vca_client): """ gateway = get_gateway( vca_client, _get_gateway_name(ctx.target.node.properties)) + if gateway.is_busy(): + return False for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") @@ -121,7 +125,7 @@ def _rule_operation(operation, vca_client): ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) - save_gateway_configuration(gateway, ctx, vca_client) + return save_gateway_configuration(gateway, vca_client) def _get_gateway_name(properties): diff --git a/server_plugin/server.py b/server_plugin/server.py index 24ba9a0..3650863 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -68,12 +68,13 @@ def get_template(catalog, template_name): catalog = get_catalog(server_dict['catalog']) if catalog is None: raise cfy_exc.NonRecoverableError( - "Catalog {0} could not be found".format(server_dict['catalog'])) + "Catalog '{0}' could not be found".format(server_dict['catalog'])) template = get_template(catalog, server_dict['template']) if template is None: raise cfy_exc.NonRecoverableError( - "Template {0} could not be found".format(server_dict['template'])) + "Template '{0}' could not be found". + format(server_dict['template'])) @operation @@ -173,7 +174,7 @@ def _create(vca_client, config, server): vapp = vca_client.get_vapp(vdc, vapp_name) if vapp is None: raise cfy_exc.NonRecoverableError( - "vApp {0} could not be found".format(vapp_name)) + "vApp '{0}' could not be found".format(vapp_name)) network_name = connection.get('network') network = get_network(vca_client, network_name) @@ -461,7 +462,7 @@ def _create_connections_list(vca_client): if not is_network_exists(vca_client, management_network_name): raise cfy_exc.NonRecoverableError( - "Network {0} could not be found".format(management_network_name)) + "Network '{0}' could not be found".format(management_network_name)) # connection by port for port in ports: diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index af8a23a..01a0540 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -65,7 +65,7 @@ def check_retry_realy_called(self, ctx): """ ctx.operation.retry.assert_called_with( message='Waiting for gateway.', - retry_after=10 + retry_after=30 ) def generate_gateway( @@ -110,6 +110,7 @@ def generate_gateway( gate.deallocate_public_ip = mock.MagicMock(return_value=None) # public ips not exist gate.get_public_ips = mock.MagicMock(return_value=[]) + gate.is_busy = mock.MagicMock(return_value=False) return gate def generate_fake_client_network( diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 96b00e9..0d7b1ad 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -183,14 +183,13 @@ def test_save_gateway_configuration(self): """ gateway = self.generate_gateway() fake_client = self.generate_client() - fake_ctx = self.generate_relation_context() # cant save configuration - error in first call self.set_services_conf_result( gateway, None ) with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_ctx, fake_client + gateway, fake_client ) # error in status self.set_services_conf_result( @@ -198,15 +197,15 @@ def test_save_gateway_configuration(self): ) with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_ctx, fake_client + gateway, fake_client ) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - self.assertIsNone( + self.assertTrue( network_plugin.save_gateway_configuration( - gateway, fake_ctx, fake_client + gateway, fake_client ) ) # server busy @@ -214,10 +213,11 @@ def test_save_gateway_configuration(self): gateway, None ) self.set_gateway_busy(gateway) - with self.assertRaises(cfy_exc.NonRecoverableError): + self.assertFalse( network_plugin.save_gateway_configuration( - gateway, fake_ctx, fake_client + gateway, fake_client ) + ) def test_is_network_routed(self): """ @@ -281,7 +281,7 @@ def test_check_port(self): utils.check_port(10) # port int to big with self.assertRaises(cfy_exc.NonRecoverableError): - utils.check_port(utils.MAX_PORT_NUMBER + 1) + utils.check_port(utils.MAX_PORT_NUMBER+1) # port any utils.check_port('any') # port not any and not int diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 6245275..e8cf162 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -239,10 +239,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'network_plugin.floatingip.ctx', fake_ctx ): - with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx - ) + self.assertFalse(floatingip._floatingip_operation( + network_plugin.DELETE, fake_client, fake_ctx + )) # busy in save with ip in runtime_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() self.set_services_conf_result( @@ -264,10 +263,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'network_plugin.floatingip.ctx', fake_ctx ): - with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx - ) + self.assertFalse(floatingip._floatingip_operation( + network_plugin.DELETE, fake_client, fake_ctx + )) # unknow operation fake_client, fake_ctx = self.generate_client_and_context_floating_ip() fake_ctx._target.node.properties = { diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 9f35e3a..109db43 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -113,11 +113,11 @@ def test__dhcp_operation(self): # returned busy, try next time self.set_gateway_busy(fake_client._vdc_gateway) self.prepare_retry(fake_ctx) - with self.assertRaises(cfy_exc.NonRecoverableError): - network._dhcp_operation( - fake_client, '_management_network', - network.DELETE_POOL - ) + + self.assertFalse(network._dhcp_operation( + fake_client, '_management_network', + network.DELETE_POOL + )) # no such gateway fake_client.get_gateway = mock.MagicMock(return_value=None) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 3f219bc..f6b4bc1 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -132,7 +132,7 @@ def test_get_original_port_for_create_with_ctx(self): self.assertEqual( fake_ctx._target.instance.runtime_properties, { - public_nat.PORT_REPLACEMENT: { + public_nat.PORT_REPLACEMENT: { ('external', '10'): 11 } } @@ -392,10 +392,10 @@ def _ip_exist_in_runtime(fake_ctx): with mock.patch( 'network_plugin.public_nat.ctx', fake_ctx ): - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat._save_configuration( - gateway, fake_client, "any", "any" - ) + self.assertFalse(public_nat._save_configuration( + gateway, fake_client, network_plugin.CREATE, "1.2.3.4" + )) + # operation create fake_ctx = self.generate_relation_context() self.set_services_conf_result( diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 786f8d2..54a4a5a 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -93,17 +93,14 @@ def check_rule_operation_fail(self, rule_type, rules): # check busy gateway = fake_client._vdc_gateway self.set_gateway_busy(gateway) - self.prepare_retry(fake_ctx) self.set_services_conf_result( fake_client._vdc_gateway, None ) with mock.patch('network_plugin.security_group.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - security_group._rule_operation( + self.assertFalse(security_group._rule_operation( rule_type, fake_client - ) - - self.check_retry_realy_called(fake_ctx) + )) def test_rule_operation_empty_rule(self): for rule_type in [ @@ -111,8 +108,7 @@ def test_rule_operation_empty_rule(self): ]: gateway = self.check_rule_operation(rule_type, []) gateway.save_services_configuration.assert_called_once_with() - with self.assertRaises(cfy_exc.NonRecoverableError): - self.check_rule_operation_fail(rule_type, []) + self.check_rule_operation_fail(rule_type, []) self.assertFalse(gateway.add_fw_rule.called) self.assertFalse(gateway.delete_fw_rule.called) @@ -127,12 +123,13 @@ def test_rule_operation_default_rule(self): True, 'Rule added by pyvcloud', 'allow', 'Any', 'any', 'external', 'any', 'external', False ) + self.assertFalse(gateway.delete_fw_rule.called) else: gateway.delete_fw_rule.assert_called_once_with( 'Any', 'any', 'external', 'any', 'external' ) - with self.assertRaises(cfy_exc.NonRecoverableError): - self.check_rule_operation_fail(rule_type, [{}]) + self.assertFalse(gateway.add_fw_rule.called) + self.check_rule_operation_fail(rule_type, [{}]) def test_rule_operation_internal_rule(self): for rule_type in [ @@ -163,8 +160,7 @@ def test_rule_operation_internal_rule(self): 'Tcp', '40', 'internal', '22', 'external' ) self.assertFalse(gateway.add_fw_rule.called) - with self.assertRaises(cfy_exc.NonRecoverableError): - self.check_rule_operation_fail(rule_type, rules) + self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_icmp_rule(self): for rule_type in [ @@ -195,8 +191,7 @@ def test_rule_operation_icmp_rule(self): 'Icmp', '22', '5.6.7.8', '60', '1.2.3.4' ) self.assertFalse(gateway.add_fw_rule.called) - with self.assertRaises(cfy_exc.NonRecoverableError): - self.check_rule_operation_fail(rule_type, rules) + self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_tcp_rule(self): for rule_type in [ @@ -221,10 +216,13 @@ def test_rule_operation_tcp_rule(self): True, 'ip', 'deny', 'Tcp', '22', '5.6.7.8', '60', '1.2.3.4', True ) + self.assertFalse(gateway.delete_fw_rule.called) else: gateway.delete_fw_rule.assert_called_once_with( 'Tcp', '22', '5.6.7.8', '60', '1.2.3.4' ) + self.assertFalse(gateway.add_fw_rule.called) + self.check_rule_operation_fail(rule_type, rules) def test_rule_operation_host_rule(self): for rule_type in [ From 1b24e790bbc7b9d7efb41135ff96825381379e8a Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 10 Jul 2015 13:44:14 +0400 Subject: [PATCH 015/228] Add error message, if network not deleted. --- network_plugin/network.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/network_plugin/network.py b/network_plugin/network.py index e51f0f2..22d1630 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -121,10 +121,10 @@ def delete(vca_client, **kwargs): get_vcloud_config()['vdc'], network_name) if success: ctx.logger.info( - "Network {0} has been successful deleted.".format(network_name)) + "Network '{0}' has been successful deleted.".format(network_name)) else: raise cfy_exc.NonRecoverableError( - "Could not delete network {0}".format(network_name)) + "Could not delete network '{0}': {1}".format(network_name, task)) wait_for_task(vca_client, task) @@ -194,15 +194,18 @@ def _dhcp_operation(vca_client, network_name, operation): max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) - ctx.logger.info("DHCP rule successful created for network {0}" - .format(network_name)) + if save_gateway_configuration(gateway, vca_client): + ctx.logger.info("DHCP rule successful created for network {0}" + .format(network_name)) + return True if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) - ctx.logger.info("DHCP rule successful deleted for network {0}" - .format(network_name)) - - return save_gateway_configuration(gateway, vca_client) + if save_gateway_configuration(gateway, vca_client): + ctx.logger.info("DHCP rule successful deleted for network {0}" + .format(network_name)) + return True + return False def _split_adresses(address_range): From ea3769b95586ba55a94004372d514b8702669ac0 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 10 Jul 2015 13:47:12 +0400 Subject: [PATCH 016/228] Add error message, if network not deleted. --- network_plugin/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/network.py b/network_plugin/network.py index 0319284..c26bec1 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -119,7 +119,7 @@ def delete(vca_client, **kwargs): "Network {0} has been successful deleted.".format(network_name)) else: raise cfy_exc.NonRecoverableError( - "Could not delete network {0}".format(network_name)) + "Could not delete network {0}: {1}".format(network_name, task)) wait_for_task(vca_client, task) From 058f317f1cb1d3d5d2195ca404931d1c340d9cc2 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 13 Jul 2015 09:32:00 +0400 Subject: [PATCH 017/228] CFY-3141 Plugin can't delete network, is it has relationship to two or more server nodes --- network_plugin/network.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/network_plugin/network.py b/network_plugin/network.py index c26bec1..1e26c49 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -22,10 +22,10 @@ is_ips_in_same_subnet, save_gateway_configuration, get_network_name, is_network_exists) - VCLOUD_NETWORK_NAME = 'vcloud_network_name' ADD_POOL = 1 DELETE_POOL = 2 +CANT_DELETE = "cannot be deleted, because it is in use" @operation @@ -89,11 +89,11 @@ def create(vca_client, **kwargs): vdc_name, network_name, gateway_name, start_address, end_address, gateway_ip, netmask, dns1, dns2, dns_suffix) if success: - ctx.logger.info("Network {0} has been successfully created." + ctx.logger.info("Network '{0}' has been successfully created." .format(network_name)) else: raise cfy_exc.NonRecoverableError( - "Could not create network {0}: {1}".format(network_name, result)) + "Could not create network '{0}': {1}".format(network_name, result)) wait_for_task(vca_client, result) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name _dhcp_operation(vca_client, network_name, ADD_POOL) @@ -118,6 +118,10 @@ def delete(vca_client, **kwargs): ctx.logger.info( "Network {0} has been successful deleted.".format(network_name)) else: + if task and CANT_DELETE in task: + ctx.logger.info("Network {} in use. Deleting the network skipped.". + format(network_name)) + return raise cfy_exc.NonRecoverableError( "Could not delete network {0}: {1}".format(network_name, task)) wait_for_task(vca_client, task) From cc7b3d1a05331a574c62b1906d4ee6f990d4bf06 Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 22 Jul 2015 13:35:39 +0400 Subject: [PATCH 018/228] CFY-3206 Provide an option to generate SSH key pair and store it as output of a deployment --- network_plugin/keypair.py | 62 ++++++++++++++++++++++++++++++++++++++- plugin.yaml | 7 +++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 01bd7a5..c7fd5b1 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -2,6 +2,13 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation import os.path +from os import chmod +from Crypto.PublicKey import RSA + +PRIVATE_KEY_PATH = 'private_key_path' +PRIVATE_KEY_VALUE = 'private_key_value' +PUBLIC_KEY_VALUE = 'publci_key_value' +AUTO_GENERATE = 'auto_generate' @operation @@ -10,9 +17,62 @@ def creation_validation(**kwargs): check availability of path used in field private_key_path of node properties """ - key = ctx.node.properties.get('private_key_path') + key = ctx.node.properties.get(PRIVATE_KEY_PATH) if key: key_path = os.path.expanduser(key) if not os.path.isfile(key_path): raise cfy_exc.NonRecoverableError( "Private key file {0} is absent".format(key_path)) + + +@operation +def create(**kwargs): + if ctx.node.properties.get(AUTO_GENERATE): + ctx.logger.info("Generating ssh keypair") + public, private = _generate_pair() + ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() + ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private + ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public + _save_private_key(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], + ctx.instance.runtime_properties[PRIVATE_KEY_VALUE]) + else: + if ctx.node.properties[PRIVATE_KEY_VALUE]: + ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() + _save_private_key(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], + ctx.node.properties[PRIVATE_KEY_VALUE]) + + +@operation +def delete(**kwargs): + if ctx.node.properties[AUTO_GENERATE]: + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH]) + del ctx.instance.runtime_properties[PRIVATE_KEY_PATH] + del ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] + del ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] + else: + if ctx.node.properties[PRIVATE_KEY_VALUE]: + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH]) + del ctx.instance.runtime_properties[PRIVATE_KEY_PATH] + + + +def _generate_pair(): + key = RSA.generate(2048) + priv_value = key.exportKey('PEM') + pubkey = key.publickey() + pub_value = pubkey.exportKey('OpenSSH') + return pub_value, priv_value + + +def _create_path(): + return '~/.ssh/{}_private.key'.format(ctx.instance.id) + + +def _save_private_key(path, value): + with open(path, 'w') as content_file: + chmod(path, 0600) + content_file.write(value) + + +def _delete_key_file(path): + os.unlink(path) diff --git a/plugin.yaml b/plugin.yaml index 173784f..e69e368 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -125,6 +125,13 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.network_plugin.keypair.creation_validation + cloudify.interfaces.lifecycle: + create: + implementation: vcloud.network_plugin.keypair.create + inputs: {} + delete: + implementation: vcloud.network_plugin.keypair.delete + inputs: {} cloudify.vcloud.nodes.Volume: From 36cc9208483db3a5144c84f4b3f4179d39ae0e5c Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 08:02:47 +0400 Subject: [PATCH 019/228] CFY-3206 Update tests --- network_plugin/keypair.py | 7 ++--- .../test_mock_network_plugin_keypair.py | 12 +++++++- .../test_mock_network_plugin_network.py | 9 ++++++ .../test_mock_network_plugin_public_nat.py | 30 +++++++++++++++++++ .../test_mock_server_plugin_volume.py | 14 ++++++++- 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index c7fd5b1..49b85c9 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -58,10 +58,9 @@ def delete(**kwargs): def _generate_pair(): key = RSA.generate(2048) - priv_value = key.exportKey('PEM') - pubkey = key.publickey() - pub_value = pubkey.exportKey('OpenSSH') - return pub_value, priv_value + private_value = key.exportKey('PEM') + public_value = key.publickey().exportKey('OpenSSH') + return public_value, private_value def _create_path(): diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index e95ae26..7e354f7 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -13,7 +13,7 @@ # * limitations under the License. import unittest - +import mock from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base from network_plugin import keypair @@ -38,5 +38,15 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): keypair.creation_validation(ctx=fake_ctx) + def test_create(self): + fake_ctx = self.generate_node_context( + properties={'auto_generate': True}) + with mock.patch( + 'network_plugin.keypair.ctx', fake_ctx): + with mock.patch( + 'network_plugin.keypair._save_private_key', mock.MagicMock()): + keypair.create() + + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index ef380a1..e575b6d 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -97,6 +97,15 @@ def test_delete(self): fake_client.delete_vdc_network.assert_called_with( 'vdc_name', 'secret_network' ) + # Error in deleted vdc network + task_delete_vdc = self.generate_task( + vcloud_plugin_common.TASK_STATUS_ERROR + ) + fake_client.delete_vdc_network = mock.MagicMock( + return_value=(False, "Network cannot be deleted, because it is in use") + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + network.delete(ctx=fake_ctx) # Success in deleted vdc network task_delete_vdc = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 40b7e5f..227ed74 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -629,6 +629,27 @@ def test_prepare_server_operation(self): fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '1.1.1.1', 'any', 'any' ) + # with SNAT rules + fake_client, fake_ctx = self.generate_client_and_context_server() + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{'type': 'SNAT'},{'type': 'SNAT'}] + } + with mock.patch( + 'network_plugin.public_nat.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + public_nat.prepare_server_operation( + fake_client, network_plugin.DELETE + ) + fake_client._vdc_gateway.del_nat_rule.assert_called_with( + 'SNAT', '1.1.1.1', 'any', '192.168.1.1', 'any', 'any' + ) + def generate_client_and_context_network(self): """ @@ -1026,6 +1047,15 @@ def test_net_connect_to_nat_preconfigure(self): mock.MagicMock(return_value=fake_client) ): public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + # empty rules + fake_ctx._target.node.properties.update({'rules':[]}) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_server_plugin_volume.py b/tests/unittests/test_mock_server_plugin_volume.py index 8058af7..d7a9434 100644 --- a/tests/unittests/test_mock_server_plugin_volume.py +++ b/tests/unittests/test_mock_server_plugin_volume.py @@ -292,7 +292,6 @@ def _run_volume_operation(fake_ctx, fake_client, operation): 'server_plugin.volume.ctx', fake_ctx ): volume._volume_operation(fake_client, operation) - # use external resource, no disks _run_volume_operation(fake_ctx, fake_client, 'ATTACH') fake_client.get_diskRefs.assert_called_with( @@ -342,6 +341,19 @@ def _run_volume_operation(fake_ctx, fake_client, operation): fake_client._vapp.detach_disk_from_vm.assert_called_with( 'some_other', disk_ref ) + # disk exist, use external resource + fake_ctx._target.node.properties = { + 'volume': { + 'name': 'some' + }, + 'use_external_resource': False + } + fake_ctx._source.node.properties.update({'use_external_resource':True}) + _run_volume_operation(fake_ctx, fake_client, 'DETACH') + fake_client._vapp.detach_disk_from_vm.assert_called_with( + 'some_other', disk_ref + ) + def _gen_volume_context_and_client(self): fake_client = self.generate_client() From 07cde7193bbf02706e20166e7b7b11293f3b8ee7 Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 08:04:50 +0400 Subject: [PATCH 020/228] CFY-3103 Update requirements --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 5887988..828f154 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3m1', + version='1.3m2', packages=[ 'vcloud_plugin_common', 'server_plugin', @@ -28,7 +28,7 @@ description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.2', - 'pyvcloud>=13rc12', + 'pyvcloud>=14rc6', 'requests>=2.4.0', 'IPy==0.81', 'PyYAML>=3.10' From f830c1ca2c74ba511542729fa7851f1a3dce5a3f Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 09:55:18 +0400 Subject: [PATCH 021/228] CFY-3206 Add more tests --- network_plugin/keypair.py | 8 +-- .../test_mock_network_plugin_keypair.py | 51 ++++++++++++++++++- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 49b85c9..1b4b7db 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -7,7 +7,7 @@ PRIVATE_KEY_PATH = 'private_key_path' PRIVATE_KEY_VALUE = 'private_key_value' -PUBLIC_KEY_VALUE = 'publci_key_value' +PUBLIC_KEY_VALUE = 'public_key_value' AUTO_GENERATE = 'auto_generate' @@ -33,12 +33,12 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public - _save_private_key(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], ctx.instance.runtime_properties[PRIVATE_KEY_VALUE]) else: if ctx.node.properties[PRIVATE_KEY_VALUE]: ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() - _save_private_key(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], ctx.node.properties[PRIVATE_KEY_VALUE]) @@ -67,7 +67,7 @@ def _create_path(): return '~/.ssh/{}_private.key'.format(ctx.instance.id) -def _save_private_key(path, value): +def _save_key_file(path, value): with open(path, 'w') as content_file: chmod(path, 0600) content_file.write(value) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 7e354f7..6df06b9 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -44,8 +44,57 @@ def test_create(self): with mock.patch( 'network_plugin.keypair.ctx', fake_ctx): with mock.patch( - 'network_plugin.keypair._save_private_key', mock.MagicMock()): + 'network_plugin.keypair._save_key_file', mock.MagicMock()): + with mock.patch('network_plugin.keypair._generate_pair', mock.MagicMock(return_value=('public', 'private'))): + keypair.create() + prop = fake_ctx.instance.runtime_properties + self.assertEqual('~/.ssh/test_private.key', prop['private_key_path']) + self.assertEqual('private', prop['private_key_value']) + self.assertEqual('public', prop['public_key_value']) + + fake_ctx = self.generate_node_context( + properties={'auto_generate': False, + 'private_key_value': 'private'}) + with mock.patch( + 'network_plugin.keypair.ctx', fake_ctx): + with mock.patch( + 'network_plugin.keypair._save_key_file', mock.MagicMock()): keypair.create() + prop = fake_ctx.instance.runtime_properties + self.assertEqual('~/.ssh/test_private.key', prop['private_key_path']) + + def test_delete(self): + fake_ctx = self.generate_node_context( + properties={'auto_generate': True}, + runtime_properties={'private_key_path': 'path', + 'private_key_value': 'private', + 'public_key_value': 'public'}) + + with mock.patch( + 'network_plugin.keypair.ctx', fake_ctx): + with mock.patch( + 'network_plugin.keypair._delete_key_file', mock.MagicMock()): + prop = fake_ctx.instance.runtime_properties + self.assertTrue('private_key_path' in prop) + self.assertTrue('private_key_value' in prop) + self.assertTrue('public_key_value' in prop) + keypair.delete() + self.assertFalse('private_key_path' in prop) + self.assertFalse('private_key_value' in prop) + self.assertFalse('public_key_value' in prop) + + fake_ctx = self.generate_node_context( + properties={'auto_generate': False, + 'private_key_value': 'private'}, + runtime_properties={'private_key_path': 'path'}) + with mock.patch( + 'network_plugin.keypair.ctx', fake_ctx): + with mock.patch( + 'network_plugin.keypair._delete_key_file', mock.MagicMock()): + prop = fake_ctx.instance.runtime_properties + self.assertTrue('private_key_path' in prop) + keypair.delete() + self.assertFalse('private_key_path' in prop) if __name__ == '__main__': From 7c4b435df6d0a9ee6d95b46557cab7ea35796d23 Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 10:02:38 +0400 Subject: [PATCH 022/228] CFY-3206 Update tests --- tests/unittests/test_mock_network_plugin_network.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index e575b6d..ef380a1 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -97,15 +97,6 @@ def test_delete(self): fake_client.delete_vdc_network.assert_called_with( 'vdc_name', 'secret_network' ) - # Error in deleted vdc network - task_delete_vdc = self.generate_task( - vcloud_plugin_common.TASK_STATUS_ERROR - ) - fake_client.delete_vdc_network = mock.MagicMock( - return_value=(False, "Network cannot be deleted, because it is in use") - ) - with self.assertRaises(cfy_exc.NonRecoverableError): - network.delete(ctx=fake_ctx) # Success in deleted vdc network task_delete_vdc = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS From 4b2d3e0295406b2a3d03f036ff5577864f708ae4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 10:54:45 +0400 Subject: [PATCH 023/228] CFY-3206 Update cloudify.vcloud.nodes.KeyPair type --- plugin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index e69e368..09866df 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -115,12 +115,12 @@ node_types: cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root properties: + auto_generate: + default: false private_key_path: default: '' public_key: default: {} - vcloud_config: - default: {} interfaces: cloudify.interfaces.validation: creation: From 4d26c08e61c47f41b2dc8cdeb11c5dd09de2187c Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 10:59:46 +0400 Subject: [PATCH 024/228] CFY-3206 Fix path generating: add expanduser --- network_plugin/keypair.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 1b4b7db..d8cecbf 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -34,12 +34,12 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], - ctx.instance.runtime_properties[PRIVATE_KEY_VALUE]) + ctx.instance.runtime_properties[PRIVATE_KEY_VALUE]) else: if ctx.node.properties[PRIVATE_KEY_VALUE]: ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], - ctx.node.properties[PRIVATE_KEY_VALUE]) + ctx.node.properties[PRIVATE_KEY_VALUE]) @operation @@ -55,7 +55,6 @@ def delete(**kwargs): del ctx.instance.runtime_properties[PRIVATE_KEY_PATH] - def _generate_pair(): key = RSA.generate(2048) private_value = key.exportKey('PEM') @@ -68,10 +67,11 @@ def _create_path(): def _save_key_file(path, value): + path = os.path.expanduser(path) with open(path, 'w') as content_file: chmod(path, 0600) content_file.write(value) def _delete_key_file(path): - os.unlink(path) + os.unlink(os.path.expanduser(path)) From c031cf756a666e73f548d2fd3c323ef94978c7e0 Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 13:07:04 +0400 Subject: [PATCH 025/228] CFY-3206 Update plugin archive link --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 09866df..586a064 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3206.zip node_types: cloudify.vcloud.nodes.Server: From 1b19257abd905f9f69bd22dc057f6d95b063425c Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 23 Jul 2015 15:58:58 +0400 Subject: [PATCH 026/228] CFY-3206 Use stub instead keys --- network_plugin/keypair.py | 3 ++- plugin.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index d8cecbf..ddbd6cb 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -29,7 +29,8 @@ def creation_validation(**kwargs): def create(**kwargs): if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") - public, private = _generate_pair() + public, private = 'public', 'private' + #_generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public diff --git a/plugin.yaml b/plugin.yaml index 586a064..a56f18b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3206.zip + source: http://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3206.zip node_types: cloudify.vcloud.nodes.Server: From e7075fffe52014956362620db6a13f97c02c8881 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 08:03:00 +0400 Subject: [PATCH 027/228] CFY-3206 Add atfork --- network_plugin/keypair.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index ddbd6cb..23329cc 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -4,6 +4,7 @@ import os.path from os import chmod from Crypto.PublicKey import RSA +from Crypto import Random PRIVATE_KEY_PATH = 'private_key_path' PRIVATE_KEY_VALUE = 'private_key_value' @@ -30,7 +31,8 @@ def create(**kwargs): if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") public, private = 'public', 'private' - #_generate_pair() + Random.atfork() + _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public From a169436018621d6a10e72f852263c40ed3cdb4a3 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 08:25:30 +0400 Subject: [PATCH 028/228] CFY-3206 Save key values in variables --- network_plugin/keypair.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 23329cc..6a95faf 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -30,9 +30,8 @@ def creation_validation(**kwargs): def create(**kwargs): if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") - public, private = 'public', 'private' Random.atfork() - _generate_pair() + public, private = _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public From ef520b14c467f15947b0b1bee7a6a3ea3a096a9b Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 08:40:53 +0400 Subject: [PATCH 029/228] CFY-3206 Add configure operation --- network_plugin/keypair.py | 2 +- plugin.yaml | 3 +++ server_plugin/server.py | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 6a95faf..9f5c774 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -30,7 +30,7 @@ def creation_validation(**kwargs): def create(**kwargs): if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") - Random.atfork() + Random.atfork() # uses for strong key generation public, private = _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private diff --git a/plugin.yaml b/plugin.yaml index a56f18b..f31e21e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -22,6 +22,9 @@ node_types: create: implementation: vcloud.server_plugin.server.create inputs: {} + configure: + implementation: vcloud.server_plugin.server.configure + inputs: {} start: implementation: vcloud.server_plugin.server.start inputs: {} diff --git a/server_plugin/server.py b/server_plugin/server.py index 3650863..9e5418e 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -307,6 +307,10 @@ def delete(vca_client, **kwargs): del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] +@operation +@with_vca_client +def configure(vca_client, public_key=None, **kwargs): + ctx.logger.info("Configure server") def _get_management_network_from_node(): """ From e53e7367cdef1f00f5fc57587afd24808ff7f9ee Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 10:17:00 +0400 Subject: [PATCH 030/228] CFY-3206 Change keypair properties. Rewrite keypair node --- network_plugin/keypair.py | 48 +++++++++++++++-------------- plugin.yaml | 4 +-- server_plugin/server.py | 63 +++++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 53 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 9f5c774..45a5782 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -6,10 +6,12 @@ from Crypto.PublicKey import RSA from Crypto import Random -PRIVATE_KEY_PATH = 'private_key_path' -PRIVATE_KEY_VALUE = 'private_key_value' -PUBLIC_KEY_VALUE = 'public_key_value' AUTO_GENERATE = 'auto_generate' +PRIVATE_KEY = 'private_key' +PUBLIC_KEY = 'public_key' +PATH = 'path' +KEY = 'key' +USER = 'user' @operation @@ -18,8 +20,8 @@ def creation_validation(**kwargs): check availability of path used in field private_key_path of node properties """ - key = ctx.node.properties.get(PRIVATE_KEY_PATH) - if key: + key = ctx.node.properties.get(PRIVATE_KEY) + if key.get(PATH): key_path = os.path.expanduser(key) if not os.path.isfile(key_path): raise cfy_exc.NonRecoverableError( @@ -28,33 +30,35 @@ def creation_validation(**kwargs): @operation def create(**kwargs): + ctx.instance.runtime_properties[PUBLIC_KEY] = {} + ctx.instance.runtime_properties[PRIVATE_KEY] = {} + ctx.instance.runtime_properties[PUBLIC_KEY][USER] = ctx.node.properties.get(PUBLIC_KEY).get(USER) if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") - Random.atfork() # uses for strong key generation + Random.atfork() # uses for strong key generation public, private = _generate_pair() - ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() - ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] = private - ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] = public - _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], - ctx.instance.runtime_properties[PRIVATE_KEY_VALUE]) + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() + ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private + ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = public + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], + ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: - if ctx.node.properties[PRIVATE_KEY_VALUE]: - ctx.instance.runtime_properties[PRIVATE_KEY_PATH] = _create_path() - _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH], - ctx.node.properties[PRIVATE_KEY_VALUE]) + if ctx.node.properties[PRIVATE_KEY][KEY]: + ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY][KEY] + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], + ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @operation def delete(**kwargs): if ctx.node.properties[AUTO_GENERATE]: - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH]) - del ctx.instance.runtime_properties[PRIVATE_KEY_PATH] - del ctx.instance.runtime_properties[PRIVATE_KEY_VALUE] - del ctx.instance.runtime_properties[PUBLIC_KEY_VALUE] + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) else: - if ctx.node.properties[PRIVATE_KEY_VALUE]: - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY_PATH]) - del ctx.instance.runtime_properties[PRIVATE_KEY_PATH] + if ctx.node.properties[PRIVATE_KEY][KEY]: + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) + del ctx.instance.runtime_properties[PRIVATE_KEY] + del ctx.instance.runtime_properties[PUBLIC_KEY] def _generate_pair(): diff --git a/plugin.yaml b/plugin.yaml index f31e21e..3353f77 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -120,8 +120,8 @@ node_types: properties: auto_generate: default: false - private_key_path: - default: '' + private_key: + default: {} public_key: default: {} interfaces: diff --git a/server_plugin/server.py b/server_plugin/server.py index 9e5418e..58827dd 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -210,32 +210,6 @@ def _create(vca_client, config, server): .format(vapp_name, network_name)) wait_for_task(vca_client, task) - # customize root password and hostname - custom = server.get(GUEST_CUSTOMIZATION) - if custom: - vdc = vca_client.get_vdc(config['vdc']) - vapp = vca_client.get_vapp(vdc, vapp_name) - script = _build_script(custom) - password = custom.get('admin_password') - computer_name = custom.get('computer_name') - - task = vapp.customize_guest_os( - vapp_name, - customization_script=script, - computer_name=computer_name, - admin_password=password - ) - if task is None: - raise cfy_exc.NonRecoverableError( - "Could not set guest customization parameters") - wait_for_task(vca_client, task) - # This function avialable from API version 5.6 - if vapp.customize_on_next_poweron(): - ctx.logger.info("Customizations successful") - else: - raise cfy_exc.NonRecoverableError( - "Can't run customization in next power on") - @operation @with_vca_client @@ -307,10 +281,41 @@ def delete(vca_client, **kwargs): del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] + @operation @with_vca_client -def configure(vca_client, public_key=None, **kwargs): - ctx.logger.info("Configure server") +def configure(vca_client, public_keys=None, **kwargs): + ctx.logger.info("Configure server") + server = {'name': ctx.instance.id} + server.update(ctx.node.properties.get('server', {})) + # customize root password and hostname + custom = server.get(GUEST_CUSTOMIZATION) + vapp_name = server['name'] + config = get_vcloud_config() + if custom: + vdc = vca_client.get_vdc(config['vdc']) + vapp = vca_client.get_vapp(vdc, vapp_name) + script = _build_script(custom, public_keys) + password = custom.get('admin_password') + computer_name = custom.get('computer_name') + + task = vapp.customize_guest_os( + vapp_name, + customization_script=script, + computer_name=computer_name, + admin_password=password + ) + if task is None: + raise cfy_exc.NonRecoverableError( + "Could not set guest customization parameters") + wait_for_task(vca_client, task) + # This function avialable from API version 5.6 + if vapp.customize_on_next_poweron(): + ctx.logger.info("Customizations successful") + else: + raise cfy_exc.NonRecoverableError( + "Can't run customization in next power on") + def _get_management_network_from_node(): """ @@ -387,7 +392,7 @@ def _get_vm_network_connection(vapp, network_name): return connection -def _build_script(custom): +def _build_script(custom, public_keys): """ create customization script """ From f3798b0d457a5aae81b36df26606f724ca8e43fd Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 10:51:45 +0400 Subject: [PATCH 031/228] CFY-3206 Add public key to runtime properties. --- network_plugin/keypair.py | 1 + server_plugin/server.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 45a5782..c42be79 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -43,6 +43,7 @@ def create(**kwargs): _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: + ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = ctx.node.properties.get(PUBLIC_KEY).get(KEY) if ctx.node.properties[PRIVATE_KEY][KEY]: ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY][KEY] ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() diff --git a/server_plugin/server.py b/server_plugin/server.py index 58827dd..3128f8e 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -284,7 +284,7 @@ def delete(vca_client, **kwargs): @operation @with_vca_client -def configure(vca_client, public_keys=None, **kwargs): +def configure(vca_client, public_keys=[], **kwargs): ctx.logger.info("Configure server") server = {'name': ctx.instance.id} server.update(ctx.node.properties.get('server', {})) @@ -392,13 +392,13 @@ def _get_vm_network_connection(vapp, network_name): return connection -def _build_script(custom, public_keys): +def _build_script(custom, autogen_keys): """ create customization script """ pre_script = custom.get('pre_script', "") post_script = custom.get('post_script', "") - public_keys = custom.get('public_keys') + public_keys = autogen_keys + custom.get('public_keys', []) if not pre_script and not post_script and not public_keys: return None script_executor = custom.get('script_executor', DEFAULT_EXECUTOR) From 8abab83e87a324d75d0e42a5b06882a87debd013 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 10:57:49 +0400 Subject: [PATCH 032/228] CFY-3206 use get for dict property --- network_plugin/keypair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index c42be79..2e7e307 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -44,7 +44,7 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = ctx.node.properties.get(PUBLIC_KEY).get(KEY) - if ctx.node.properties[PRIVATE_KEY][KEY]: + if ctx.node.properties[PRIVATE_KEY].get(KEY): ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY][KEY] ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], From 06b799bd0cc03c7b32be520d9f54fc2046e4ed1a Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 11:05:10 +0400 Subject: [PATCH 033/228] CFY-3206 Copy private key path to rintime properties --- network_plugin/keypair.py | 1 + 1 file changed, 1 insertion(+) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 2e7e307..12fe6fc 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -44,6 +44,7 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = ctx.node.properties.get(PUBLIC_KEY).get(KEY) + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = ctx.node.properties[PRIVATE_KEY].get(PATH) if ctx.node.properties[PRIVATE_KEY].get(KEY): ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY][KEY] ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() From ba3dda0eb610167f78ac28bbe5a06d37c68740ac Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 11:10:12 +0400 Subject: [PATCH 034/228] CFY-3206 Refactoring --- network_plugin/keypair.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 12fe6fc..19c6f7c 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -44,9 +44,9 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = ctx.node.properties.get(PUBLIC_KEY).get(KEY) + ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY].get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = ctx.node.properties[PRIVATE_KEY].get(PATH) if ctx.node.properties[PRIVATE_KEY].get(KEY): - ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY][KEY] ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @@ -57,7 +57,7 @@ def delete(**kwargs): if ctx.node.properties[AUTO_GENERATE]: _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) else: - if ctx.node.properties[PRIVATE_KEY][KEY]: + if ctx.node.properties[PRIVATE_KEY].get(KEY): _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) del ctx.instance.runtime_properties[PRIVATE_KEY] del ctx.instance.runtime_properties[PUBLIC_KEY] From 02ec3c4d460cd9a33168779c98e39aa5e5dc78e1 Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 13:14:46 +0400 Subject: [PATCH 035/228] CFY-3206 Read keypairs from dependencies --- server_plugin/server.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 3128f8e..2d02d97 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -284,7 +284,7 @@ def delete(vca_client, **kwargs): @operation @with_vca_client -def configure(vca_client, public_keys=[], **kwargs): +def configure(vca_client, **kwargs): ctx.logger.info("Configure server") server = {'name': ctx.instance.id} server.update(ctx.node.properties.get('server', {})) @@ -295,7 +295,7 @@ def configure(vca_client, public_keys=[], **kwargs): if custom: vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) - script = _build_script(custom, public_keys) + script = _build_script(custom) password = custom.get('admin_password') computer_name = custom.get('computer_name') @@ -392,13 +392,13 @@ def _get_vm_network_connection(vapp, network_name): return connection -def _build_script(custom, autogen_keys): +def _build_script(custom): """ create customization script """ pre_script = custom.get('pre_script', "") post_script = custom.get('post_script', "") - public_keys = autogen_keys + custom.get('public_keys', []) + public_keys = _get_connected_keypairs() if not pre_script and not post_script and not public_keys: return None script_executor = custom.get('script_executor', DEFAULT_EXECUTOR) @@ -425,6 +425,15 @@ def _build_script(custom, autogen_keys): return script +def _get_connected_keypairs(): + relationships = getattr(ctx.instance, 'relationships', None) + if relationships: + return [relationship.target.instance.runtime_properties['public_key'] for relationship in relationships + if 'public_key' in relationship.instance.runtime_properties] + else: + return [] + + def _build_public_keys_script(public_keys): """ create script for update ssh keys From 6283b066ef88f53f9313d29180fe5fe485dd5cfb Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 13:21:13 +0400 Subject: [PATCH 036/228] CFY-3206 Fix error in object get --- server_plugin/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 2d02d97..236ec51 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -429,7 +429,7 @@ def _get_connected_keypairs(): relationships = getattr(ctx.instance, 'relationships', None) if relationships: return [relationship.target.instance.runtime_properties['public_key'] for relationship in relationships - if 'public_key' in relationship.instance.runtime_properties] + if 'public_key' in relationship.target.instance.runtime_properties] else: return [] From e852b701f063187ea9550e894d4ed927114a07bf Mon Sep 17 00:00:00 2001 From: Kostya Date: Fri, 24 Jul 2015 13:46:02 +0400 Subject: [PATCH 037/228] CFY-3206 Style fixes --- network_plugin/keypair.py | 14 +++++++---- server_plugin/server.py | 3 ++- .../test_mock_network_plugin_keypair.py | 24 ++++++++++++------- .../test_mock_network_plugin_public_nat.py | 5 ++-- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 19c6f7c..9c7c135 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -32,10 +32,10 @@ def creation_validation(**kwargs): def create(**kwargs): ctx.instance.runtime_properties[PUBLIC_KEY] = {} ctx.instance.runtime_properties[PRIVATE_KEY] = {} - ctx.instance.runtime_properties[PUBLIC_KEY][USER] = ctx.node.properties.get(PUBLIC_KEY).get(USER) + ctx.instance.runtime_properties[PUBLIC_KEY][USER] = \ + ctx.node.properties.get(PUBLIC_KEY).get(USER) if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") - Random.atfork() # uses for strong key generation public, private = _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private @@ -43,9 +43,12 @@ def create(**kwargs): _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: - ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = ctx.node.properties.get(PUBLIC_KEY).get(KEY) - ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = ctx.node.properties[PRIVATE_KEY].get(KEY) - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = ctx.node.properties[PRIVATE_KEY].get(PATH) + ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = \ + ctx.node.properties.get(PUBLIC_KEY).get(KEY) + ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = \ + ctx.node.properties[PRIVATE_KEY].get(KEY) + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ + ctx.node.properties[PRIVATE_KEY].get(PATH) if ctx.node.properties[PRIVATE_KEY].get(KEY): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], @@ -64,6 +67,7 @@ def delete(**kwargs): def _generate_pair(): + Random.atfork() # uses for strong key generation key = RSA.generate(2048) private_value = key.exportKey('PEM') public_value = key.publickey().exportKey('OpenSSH') diff --git a/server_plugin/server.py b/server_plugin/server.py index 236ec51..3afcaed 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -428,7 +428,8 @@ def _build_script(custom): def _get_connected_keypairs(): relationships = getattr(ctx.instance, 'relationships', None) if relationships: - return [relationship.target.instance.runtime_properties['public_key'] for relationship in relationships + return [relationship.target.instance.runtime_properties['public_key'] + for relationship in relationships if 'public_key' in relationship.target.instance.runtime_properties] else: return [] diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 6df06b9..fc2c443 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -39,20 +39,23 @@ def test_creation_validation(self): keypair.creation_validation(ctx=fake_ctx) def test_create(self): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context( properties={'auto_generate': True}) with mock.patch( 'network_plugin.keypair.ctx', fake_ctx): with mock.patch( 'network_plugin.keypair._save_key_file', mock.MagicMock()): - with mock.patch('network_plugin.keypair._generate_pair', mock.MagicMock(return_value=('public', 'private'))): + with mock.patch('network_plugin.keypair._generate_pair', + mock.MagicMock(return_value=('public', + 'private'))): keypair.create() prop = fake_ctx.instance.runtime_properties - self.assertEqual('~/.ssh/test_private.key', prop['private_key_path']) + self.assertEqual('~/.ssh/test_private.key', + prop['private_key_path']) self.assertEqual('private', prop['private_key_value']) self.assertEqual('public', prop['public_key_value']) - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context( properties={'auto_generate': False, 'private_key_value': 'private'}) with mock.patch( @@ -61,10 +64,11 @@ def test_create(self): 'network_plugin.keypair._save_key_file', mock.MagicMock()): keypair.create() prop = fake_ctx.instance.runtime_properties - self.assertEqual('~/.ssh/test_private.key', prop['private_key_path']) + self.assertEqual('~/.ssh/test_private.key', + prop['private_key_path']) def test_delete(self): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context( properties={'auto_generate': True}, runtime_properties={'private_key_path': 'path', 'private_key_value': 'private', @@ -73,7 +77,8 @@ def test_delete(self): with mock.patch( 'network_plugin.keypair.ctx', fake_ctx): with mock.patch( - 'network_plugin.keypair._delete_key_file', mock.MagicMock()): + 'network_plugin.keypair._delete_key_file', + mock.MagicMock()): prop = fake_ctx.instance.runtime_properties self.assertTrue('private_key_path' in prop) self.assertTrue('private_key_value' in prop) @@ -83,14 +88,15 @@ def test_delete(self): self.assertFalse('private_key_value' in prop) self.assertFalse('public_key_value' in prop) - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context( properties={'auto_generate': False, 'private_key_value': 'private'}, runtime_properties={'private_key_path': 'path'}) with mock.patch( 'network_plugin.keypair.ctx', fake_ctx): with mock.patch( - 'network_plugin.keypair._delete_key_file', mock.MagicMock()): + 'network_plugin.keypair._delete_key_file', + mock.MagicMock()): prop = fake_ctx.instance.runtime_properties self.assertTrue('private_key_path' in prop) keypair.delete() diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index b98966e..a30bf17 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -634,7 +634,7 @@ def test_prepare_server_operation(self): 'nat': { 'edge_gateway': 'gateway' }, - 'rules': [{'type': 'SNAT'},{'type': 'SNAT'}] + 'rules': [{'type': 'SNAT'}, {'type': 'SNAT'}] } with mock.patch( 'network_plugin.public_nat.ctx', fake_ctx @@ -649,7 +649,6 @@ def test_prepare_server_operation(self): 'SNAT', '1.1.1.1', 'any', '192.168.1.1', 'any', 'any' ) - def generate_client_and_context_network(self): """ for test prepare_network_operation based operations @@ -1047,7 +1046,7 @@ def test_net_connect_to_nat_preconfigure(self): ): public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) # empty rules - fake_ctx._target.node.properties.update({'rules':[]}) + fake_ctx._target.node.properties.update({'rules': []}) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) From a29490fdbe96f29b66d57483e8fbdf61835197e7 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 09:56:15 +0400 Subject: [PATCH 038/228] CFY-3206 Use instance dir for keypair --- network_plugin/keypair.py | 1 + 1 file changed, 1 insertion(+) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 9c7c135..faaa06f 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -75,6 +75,7 @@ def _generate_pair(): def _create_path(): + ctx.logger.info("-------- {}".format(ctx._context['storage']._instances_dir)) return '~/.ssh/{}_private.key'.format(ctx.instance.id) From 7a1e9de535b2817c04d9be14d7a24b913609e4dd Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:06:44 +0400 Subject: [PATCH 039/228] CFY-3206 ADd os.environ --- network_plugin/keypair.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index faaa06f..05ba320 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -75,7 +75,9 @@ def _generate_pair(): def _create_path(): - ctx.logger.info("-------- {}".format(ctx._context['storage']._instances_dir)) + ctx.logger.info("-------- {}".format(os.environ)) + if ctx._local: + ctx.logger.info("-------- {}".format(ctx._context['storage']._instances_dir)) return '~/.ssh/{}_private.key'.format(ctx.instance.id) From fffdc726577c4d03ace799b38700fbd356b7a2de Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:24:51 +0400 Subject: [PATCH 040/228] CFY-3206 Set key dir --- network_plugin/keypair.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 05ba320..c394668 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -75,10 +75,11 @@ def _generate_pair(): def _create_path(): - ctx.logger.info("-------- {}".format(os.environ)) if ctx._local: - ctx.logger.info("-------- {}".format(ctx._context['storage']._instances_dir)) - return '~/.ssh/{}_private.key'.format(ctx.instance.id) + key_dir = ctx._context['storage']._instances_dir + else: + key_dir = os.path.dirname(os.environ['VIRTUALENV']) + return '{}/{}_private.key'.format(key_dir/ctx.instance.id) def _save_key_file(path, value): From ffa1e16e41ac6eb6528d27c1dbaf3ede3a73368c Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:31:31 +0400 Subject: [PATCH 041/228] CFY-3206 Fix syntax error --- network_plugin/keypair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index c394668..92a6105 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -79,7 +79,7 @@ def _create_path(): key_dir = ctx._context['storage']._instances_dir else: key_dir = os.path.dirname(os.environ['VIRTUALENV']) - return '{}/{}_private.key'.format(key_dir/ctx.instance.id) + return '{}/{}_private.key'.format(key_dir, ctx.instance.id) def _save_key_file(path, value): From b1a07260f2b90748b56e984dbeaa301ea83331de Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:40:05 +0400 Subject: [PATCH 042/228] CFY-3206 Change file location for local mode --- network_plugin/keypair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 92a6105..4fdcba0 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -76,7 +76,7 @@ def _generate_pair(): def _create_path(): if ctx._local: - key_dir = ctx._context['storage']._instances_dir + key_dir = ctx._context['storage']._storage_dir else: key_dir = os.path.dirname(os.environ['VIRTUALENV']) return '{}/{}_private.key'.format(key_dir, ctx.instance.id) From 2f35ed9e2be109dc610ea593ad0eaf53af1b44e8 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:48:32 +0400 Subject: [PATCH 043/228] CFY-3206 Add new relationship for keypair --- plugin.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 3353f77..8690025 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -212,7 +212,6 @@ relationships: unlink: implementation: vcloud.network_plugin.public_nat.server_disconnect_from_nat inputs: {} - cloudify.vcloud.volume_attached_to_server: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -223,3 +222,5 @@ relationships: unlink: implementation: vcloud.server_plugin.volume.detach_volume inputs: {} + cloudify.vcloud.server_connected_to_keypair: + derived_from: cloudify.relationships.connected_to From 88228a3671be7b146d165ae13ff709555d861c65 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:50:43 +0400 Subject: [PATCH 044/228] CFY-3206 Fix url to plugin archive --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 8690025..90259f9 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: http://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3206.zip + source: http://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: From e535129a9967abc1bb3c0ea828ef7c8c6322aea4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 10:51:19 +0400 Subject: [PATCH 045/228] CFY-3206 Change protocol to https --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 90259f9..5742bc0 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: http://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: From e93c2aaa4e5f7793f6bb15683b936c2d8b555658 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 13:08:26 +0400 Subject: [PATCH 046/228] CFY-3259 When pyvcloud rise Exception plugin didn't catch it. Setup hardware after guest customization --- server_plugin/server.py | 53 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 3650863..9dfd82c 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -137,33 +137,6 @@ def _create(vca_client, config, server): .format(vca_client.response.content)) wait_for_task(vca_client, task) - hardware = server.get('hardware') - if hardware: - cpu = hardware.get('cpu') - memory = hardware.get('memory') - _check_hardware(cpu, memory) - vapp = vca_client.get_vapp( - vca_client.get_vdc(config['vdc']), vapp_name - ) - if memory: - task = vapp.modify_vm_memory(vapp_name, memory) - if task: - wait_for_task(vca_client, task) - ctx.logger.info("Customize VM memory: {0}.".format(memory)) - else: - raise cfy_exc.NonRecoverableError( - "Customize VM memory failed: {0}.".format(task) - ) - if cpu: - task = vapp.modify_vm_cpu(vapp_name, cpu) - if task: - wait_for_task(vca_client, task) - ctx.logger.info("Customize VM cpu: {0}.".format(cpu)) - else: - raise cfy_exc.NonRecoverableError( - "Customize VM cpu failed: {0}.".format(task) - ) - ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = vapp_name connections = _create_connections_list(vca_client) @@ -237,6 +210,32 @@ def _create(vca_client, config, server): "Can't run customization in next power on") + hardware = server.get('hardware') + if hardware: + cpu = hardware.get('cpu') + memory = hardware.get('memory') + _check_hardware(cpu, memory) + vapp = vca_client.get_vapp( + vca_client.get_vdc(config['vdc']), vapp_name + ) + if memory: + try: + task = vapp.modify_vm_memory(vapp_name, memory) + wait_for_task(vca_client, task) + ctx.logger.info("Customize VM memory: {0}.".format(memory)) + except Exception: + raise cfy_exc.NonRecoverableError( + "Customize VM memory failed: {0}. {1}".format(task, vapp.response.text)) + if cpu: + try: + task = vapp.modify_vm_cpu(vapp_name, cpu) + wait_for_task(vca_client, task) + ctx.logger.info("Customize VM cpu: {0}.".format(cpu)) + except Exception: + raise cfy_exc.NonRecoverableError( + "Customize VM cpu failed: {0}. {1}".format(task, vapp.response.text)) + + @operation @with_vca_client def start(vca_client, **kwargs): From ef162063933529a34f13bfc717e7e6ecf27f89d4 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 14:31:04 +0400 Subject: [PATCH 047/228] CFY-3259 Create more verbose error description in server plugin --- server_plugin/server.py | 33 +++++++++++++++++++------------- server_plugin/volume.py | 12 ++++++++---- vcloud_plugin_common/__init__.py | 10 ++++++++++ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 9dfd82c..d31e27e 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -20,6 +20,7 @@ transform_resource_name, wait_for_task, with_vca_client, + error_response, STATUS_POWERED_ON) from network_plugin import (get_network_name, get_network, is_network_exists, @@ -134,7 +135,7 @@ def _create(vca_client, config, server): vm_name=vapp_name) if not task: raise cfy_exc.NonRecoverableError("Could not create vApp: {0}" - .format(vca_client.response.content)) + .format(error_response(vca_client))) wait_for_task(vca_client, task) ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = vapp_name @@ -155,8 +156,8 @@ def _create(vca_client, config, server): task = vapp.connect_to_network(network_name, network.get_href()) if not task: raise cfy_exc.NonRecoverableError( - "Could not add network {0} to VApp {1}" - .format(network_name, vapp_name)) + "Could not add network {0} to VApp {1}. {2}" + .format(network_name, vapp_name, error_response(vapp))) wait_for_task(vca_client, task) connections_primary_index = None @@ -179,8 +180,8 @@ def _create(vca_client, config, server): task = vapp.connect_vms(**connection_args) if task is None: raise cfy_exc.NonRecoverableError( - "Could not connect vApp {0} to network {1}" - .format(vapp_name, network_name)) + "Could not connect vApp {0} to network {1}. {2}" + .format(vapp_name, network_name, error_response(vapp))) wait_for_task(vca_client, task) # customize root password and hostname @@ -200,15 +201,16 @@ def _create(vca_client, config, server): ) if task is None: raise cfy_exc.NonRecoverableError( - "Could not set guest customization parameters") + "Could not set guest customization parameters. {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) # This function avialable from API version 5.6 if vapp.customize_on_next_poweron(): ctx.logger.info("Customizations successful") else: raise cfy_exc.NonRecoverableError( - "Can't run customization in next power on") - + "Can't run customization in next power on. {0}". + format(error_response(vapp))) hardware = server.get('hardware') if hardware: @@ -225,7 +227,8 @@ def _create(vca_client, config, server): ctx.logger.info("Customize VM memory: {0}.".format(memory)) except Exception: raise cfy_exc.NonRecoverableError( - "Customize VM memory failed: {0}. {1}".format(task, vapp.response.text)) + "Customize VM memory failed: {0}. {1}". + format(task, error_response(vapp))) if cpu: try: task = vapp.modify_vm_cpu(vapp_name, cpu) @@ -233,7 +236,8 @@ def _create(vca_client, config, server): ctx.logger.info("Customize VM cpu: {0}.".format(cpu)) except Exception: raise cfy_exc.NonRecoverableError( - "Customize VM cpu failed: {0}. {1}".format(task, vapp.response.text)) + "Customize VM cpu failed: {0}. {1}". + format(task, error_response(vapp))) @operation @@ -254,7 +258,8 @@ def start(vca_client, **kwargs): ctx.logger.info("Power-on VApp {0}".format(vapp_name)) task = vapp.poweron() if not task: - raise cfy_exc.NonRecoverableError("Could not power-on vApp") + raise cfy_exc.NonRecoverableError("Could not power-on vApp. {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) if not _get_state(vca_client): @@ -280,7 +285,8 @@ def stop(vca_client, **kwargs): ctx.logger.info("Power-off and undeploy VApp {0}".format(vapp_name)) task = vapp.undeploy() if not task: - raise cfy_exc.NonRecoverableError("Could not undeploy vApp") + raise cfy_exc.NonRecoverableError("Could not undeploy vApp {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) @@ -301,7 +307,8 @@ def delete(vca_client, **kwargs): ctx.logger.info("Deleting VApp {0}".format(vapp_name)) task = vapp.delete() if not task: - raise cfy_exc.NonRecoverableError("Could not delete vApp") + raise cfy_exc.NonRecoverableError("Could not delete vApp {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] diff --git a/server_plugin/volume.py b/server_plugin/volume.py index 8e1fb1b..70a00df 100644 --- a/server_plugin/volume.py +++ b/server_plugin/volume.py @@ -16,7 +16,8 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (wait_for_task, with_vca_client, - get_vcloud_config, get_mandatory) + get_vcloud_config, get_mandatory, + error_response) from network_plugin import get_vapp_name @@ -133,17 +134,20 @@ def _volume_operation(vca_client, operation): "Volume node {} has been attached".format(volumeName)) else: raise cfy_exc.NonRecoverableError( - "Can't attach disk: {0}".format(volumeName)) + "Can't attach disk: {0} {1}". + format(volumeName, error_response(vapp))) elif operation == 'DETACH': task = vapp.detach_disk_from_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( - "Volume node {} has been detached".format(volumeName)) + "Volume node {0} has been detached.". + format(volumeName)) else: raise cfy_exc.NonRecoverableError( - "Can't detach disk: {0}".format(volumeName)) + "Can't detach disk: {0}. {1}". + format(volumeName, error_response(vapp))) else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}".format(operation)) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index e493ad1..243ee2b 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -456,3 +456,13 @@ def is_ondemand(service_type): check service type is ondemand """ return service_type == ONDEMAND_SERVICE_TYPE + + +def error_response(obj): + """ + return description of response error + """ + try: + return obj.response.content + except AttributeError: + return '' From 84b2d50dd4f061b91124ac1d2f7381069d46bb56 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 14:59:27 +0400 Subject: [PATCH 048/228] CFY-3259 Update dependencies --- setup.py | 3 ++- tox.ini | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 828f154..d25e1b1 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ 'pyvcloud>=14rc6', 'requests>=2.4.0', 'IPy==0.81', - 'PyYAML>=3.10' + 'PyYAML>=3.10', + 'pycrypto' ] ) diff --git a/tox.ini b/tox.ini index 71065a9..f33129c 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,6 @@ commands = nosetests -x -s tests/unittests --cover-html --with-coverage --cover [testenv:pep8] commands= flake8 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts -ignore = +ignore = E501 exclude=.venv,.tox,dist,*egg,etc,build filename=*.py From b90b66584489a1f0927f75dd53e4953d8c83dc99 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 15:08:28 +0400 Subject: [PATCH 049/228] CFY-3259 Fix syntax in tests --- tests/integration/test_network_plugin.py | 2 +- tests/unittests/test_mock_network_plugin.py | 2 +- .../test_mock_network_plugin_network.py | 18 +++++++++--------- .../test_mock_network_plugin_public_nat.py | 2 +- tox.ini | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/integration/test_network_plugin.py b/tests/integration/test_network_plugin.py index d18ecbc..d0fb222 100644 --- a/tests/integration/test_network_plugin.py +++ b/tests/integration/test_network_plugin.py @@ -87,7 +87,7 @@ def setUp(self): self.properties = { 'vcloud_config': self.vcloud_config, 'floatingip': self.test_config['floatingip'] - } + } self.ctx = MockCloudifyContext( node_id=name, node_name=name, diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 0d7b1ad..acaa62f 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -281,7 +281,7 @@ def test_check_port(self): utils.check_port(10) # port int to big with self.assertRaises(cfy_exc.NonRecoverableError): - utils.check_port(utils.MAX_PORT_NUMBER+1) + utils.check_port(utils.MAX_PORT_NUMBER + 1) # port any utils.check_port('any') # port not any and not int diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index ef380a1..64ea473 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -118,7 +118,7 @@ def test_create(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -175,7 +175,7 @@ def test_create(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -200,7 +200,7 @@ def test_create(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -236,7 +236,7 @@ def test_create_exist_same_network(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -286,7 +286,7 @@ def test_creation_validation(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -316,7 +316,7 @@ def test_creation_validation(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', @@ -348,7 +348,7 @@ def test_creation_validation_gateway(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'private_network', @@ -390,7 +390,7 @@ def test_creation_validation_network_mask(self): 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.127", + 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'private_network', @@ -425,7 +425,7 @@ def test_creation_validation_separate_ips(self): 'dhcp': { 'dhcp_range': "10.1.1.10-10.1.1.255" }, - 'static_range': "10.1.1.2-10.1.1.210", + 'static_range': "10.1.1.2-10.1.1.210", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'private_network', diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index f6b4bc1..2ee59e1 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -132,7 +132,7 @@ def test_get_original_port_for_create_with_ctx(self): self.assertEqual( fake_ctx._target.instance.runtime_properties, { - public_nat.PORT_REPLACEMENT: { + public_nat.PORT_REPLACEMENT: { ('external', '10'): 11 } } diff --git a/tox.ini b/tox.ini index f33129c..78fb019 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ commands = nosetests -x -s tests/unittests --cover-html --with-coverage --cover [testenv:pep8] commands= - flake8 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts -ignore = E501 + flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts +ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py From 821600c6007284b5081fb6d87942f52acac580ea Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 15:17:18 +0400 Subject: [PATCH 050/228] CFY-3259 Update dev-requirements.txt --- dev-requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 55fdc57..6f0b776 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,4 +2,6 @@ -e git+https://github.com/cloudify-cosmo/cloudify-rest-client@master#egg=cloudify-rest-client==3.2 -e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@master#egg=cloudify-plugins-common==3.2 IPy -pyvcloud +pyvcloud>=14rc6 +pycrypto + From 5065f23d581a547cce14b688e048bfb3a3e1b603 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 15:28:51 +0400 Subject: [PATCH 051/228] CFY-3259 Fix tests --- tests/unittests/test_mock_vcloud_plugin_common.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 6a7a09b..42f5a40 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -281,10 +281,7 @@ def test_config(self): '__builtin__.open', fake_file ): config = vcloud_plugin_common.Config() - self.assertEqual( - config.get(), - {} - ) + self.assertFalse(config.get()) if __name__ == '__main__': unittest.main() From 7bbaa5f187e2f9d8243b67ea1f1214ef08ed8599 Mon Sep 17 00:00:00 2001 From: Kostya Date: Mon, 27 Jul 2015 16:02:05 +0400 Subject: [PATCH 052/228] CFY-3259 Fix config reader. --- vcloud_plugin_common/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 243ee2b..66f9bf6 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -117,6 +117,8 @@ def get(self): try: with open(config_path) as f: cfg = yaml.load(f.read()) + if not cfg: + cfg = {} except IOError: pass return cfg From f7ae56407b5fe6aef6632e32b88f14a3b92c5c38 Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 28 Jul 2015 11:44:08 +0400 Subject: [PATCH 053/228] Add 'private_key_path' in KeyPair for compatibility --- plugin.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin.yaml b/plugin.yaml index 5742bc0..ddd003e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -118,6 +118,8 @@ node_types: cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root properties: + private_key_path: + default: '' auto_generate: default: false private_key: From 5f61e7c0ef9d43e37974b4b38b9c505787be368a Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 28 Jul 2015 14:11:35 +0400 Subject: [PATCH 054/228] Update manager blueprint --- .../vcloud-manager-blueprint.yaml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index fc62e0b..fdce18c 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -362,7 +362,8 @@ node_templates: manager_keypair: type: cloudify.vcloud.nodes.KeyPair properties: - private_key_path: { get_input: manager_private_key_path } + private_key: + path: { get_input: manager_private_key_path } public_key: key: { get_input: manager_public_key } user: { get_input: manager_server_user } @@ -370,7 +371,8 @@ node_templates: agent_keypair: type: cloudify.vcloud.nodes.KeyPair properties: - private_key_path: { get_input: agent_private_key_path } + private_key: + path: { get_input: agent_private_key_path } public_key: key: { get_input: agent_public_key } user: { get_input: agents_user } @@ -384,9 +386,6 @@ node_templates: catalog: { get_input: manager_server_catalog } template: { get_input: manager_server_template } guest_customization: - public_keys: - - { get_property: [manager_keypair, public_key] } - - { get_property: [agent_keypair, public_key] } computer_name: { get_input: manager_server_name } hardware: cpu: { get_input: manager_server_cpus } @@ -400,6 +399,10 @@ node_templates: type: cloudify.vcloud.server_connected_to_public_nat - target: node_security_group type: cloudify.vcloud.server_connected_to_security_group + - target: agent_keypair + type: cloudify.vcloud.server_connected_to_keypair + - target: manager_keypair + type: cloudify.vcloud.server_connected_to_keypair volume: type: cloudify.vcloud.nodes.Volume @@ -523,7 +526,7 @@ node_templates: task_mapping: cloudify_cli.bootstrap.tasks.bootstrap_docker task_properties: cloudify_packages: { get_property: [manager, cloudify_packages] } - agent_local_key_path: { get_property: [agent_keypair, private_key_path] } + agent_local_key_path: { get_property: [agent_keypair, private_key, path] } provider_context: { get_attribute: [manager, provider_context] } fabric_env: user: { get_input: manager_server_user } @@ -548,7 +551,7 @@ node_templates: task_mapping: cloudify_cli.bootstrap.tasks.stop_manager_container fabric_env: user: { get_input: manager_server_user } - key_filename: { get_property: [manager_keypair, private_key_path] } + key_filename: { get_property: [manager_keypair, private_key, path] } host_string: { get_attribute: [management_server_nat, public_ip] } port: { get_input: manager_server_ssh_port } delete: @@ -557,7 +560,7 @@ node_templates: task_mapping: cloudify_cli.bootstrap.tasks.stop_docker_service fabric_env: user: { get_input: manager_server_user } - key_filename: { get_property: [manager_keypair, private_key_path] } + key_filename: { get_property: [manager_keypair, private_key, path] } host_string: { get_attribute: [management_server_nat, public_ip] } port: { get_input: manager_server_ssh_port } cloudify.interfaces.validation: From cd5794ff88ac05878202d74fa02816642c77c2b1 Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 29 Jul 2015 07:51:04 +0400 Subject: [PATCH 055/228] Remove private_key_path --- plugin.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index ddd003e..5742bc0 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -118,8 +118,6 @@ node_types: cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root properties: - private_key_path: - default: '' auto_generate: default: false private_key: From 87eeac51adf4441ee7bed8b2b6764b1087b95b39 Mon Sep 17 00:00:00 2001 From: Kostya Date: Thu, 30 Jul 2015 12:24:52 +0400 Subject: [PATCH 056/228] Fix setup home dir for root --- server_plugin/server.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index b48fb67..74865d1 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -461,7 +461,12 @@ def _build_public_keys_script(public_keys): if not public_key: continue user = key.get('user', DEFAULT_USER) - home = key.get('home', DEFAULT_HOME) + home = key.get('home') + if not home: + if user == 'root': + home = '' + else: + home = DEFAULT_HOME ssh_dir = ssh_dir_template.format(home, user) authorized_keys = authorized_keys_template.format(ssh_dir) test_ssh_dir = test_ssh_dir_template.format( From 5e067b870ed49c1a4a68fe4af261ada54d10b599 Mon Sep 17 00:00:00 2001 From: Kostya Date: Wed, 29 Jul 2015 15:30:53 +0400 Subject: [PATCH 057/228] Add runtime_properties for user's home dir --- network_plugin/keypair.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index c6bafa3..0496934 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -12,6 +12,7 @@ PATH = 'path' KEY = 'key' USER = 'user' +HOME = 'home' @operation @@ -34,6 +35,8 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY] = {} ctx.instance.runtime_properties[PUBLIC_KEY][USER] = \ ctx.node.properties.get(PUBLIC_KEY, {}).get(USER) + ctx.instance.runtime_properties[PUBLIC_KEY][HOME] = \ + ctx.node.properties.get(PUBLIC_KEY, {}).get(HOME) if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") public, private = _generate_pair() From aa635243ed073acc8b1111a6cfc58a3b1d561324 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 31 Jul 2015 12:35:43 +0400 Subject: [PATCH 058/228] Fix error message if gateway is busy --- network_plugin/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index f05f472..a5e028b 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -14,7 +14,7 @@ AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') -BUSY_MESSAGE = "The entity gateway is busy completing an operation." +BUSY_MESSAGE = "is busy completing an operation" GATEWAY_TIMEOUT = 30 From 409e005c5ed36c0bb5cbdcc873b27b4510e9c45b Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 3 Aug 2015 16:15:34 +0400 Subject: [PATCH 059/228] Fix empty user --- server_plugin/server.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 74865d1..442f2b4 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -460,7 +460,9 @@ def _build_public_keys_script(public_keys): public_key = key.get('key') if not public_key: continue - user = key.get('user', DEFAULT_USER) + user = key.get('user') + if not user: + user = DEFAULT_USER home = key.get('home') if not home: if user == 'root': From 2bc684bd3e2d08785597ded1c8bcb9c6abf116e5 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 09:07:07 +0400 Subject: [PATCH 060/228] Style fixes, refactoring --- server_plugin/server.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 442f2b4..a9d6426 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -93,9 +93,9 @@ def create(vca_client, **kwargs): 'guest_customization': { 'pre_script': 'pre_script', 'post_script': 'post_script', - 'public_keys': [{ - 'key': True - }] + 'admin_password': 'pass', + 'computer_name': 'computer' + } } } @@ -203,8 +203,9 @@ def start(vca_client, **kwargs): ctx.logger.info("Power-on VApp {0}".format(vapp_name)) task = vapp.poweron() if not task: - raise cfy_exc.NonRecoverableError("Could not power-on vApp. {0}". - format(error_response(vapp))) + raise cfy_exc.NonRecoverableError( + "Could not power-on vApp. {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) if not _get_state(vca_client): @@ -433,7 +434,8 @@ def _get_connected_keypairs(): if relationships: return [relationship.target.instance.runtime_properties['public_key'] for relationship in relationships - if 'public_key' in relationship.target.instance.runtime_properties] + if 'public_key' in + relationship.target.instance.runtime_properties] else: return [] @@ -465,10 +467,7 @@ def _build_public_keys_script(public_keys): user = DEFAULT_USER home = key.get('home') if not home: - if user == 'root': - home = '' - else: - home = DEFAULT_HOME + home = '' if user == 'root' else DEFAULT_HOME ssh_dir = ssh_dir_template.format(home, user) authorized_keys = authorized_keys_template.format(ssh_dir) test_ssh_dir = test_ssh_dir_template.format( From 57d6d93743930e82d0eeff00867a0a1245ca0819 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 10:59:34 +0400 Subject: [PATCH 061/228] CFY-3308 Make vcloud server "managment_network" property optional --- server_plugin/server.py | 71 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index a9d6426..bbb31d9 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -305,39 +305,22 @@ def configure(vca_client, **kwargs): try: task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) - ctx.logger.info("Customize VM memory: {0}.".format(memory)) + ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) except Exception: raise cfy_exc.NonRecoverableError( - "Customize VM memory failed: {0}. {1}". + "Customize VM memory failed: '{0}'. {1}". format(task, error_response(vapp))) if cpu: try: task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) - ctx.logger.info("Customize VM cpu: {0}.".format(cpu)) + ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) except Exception: raise cfy_exc.NonRecoverableError( - "Customize VM cpu failed: {0}. {1}". + "Customize VM cpu failed: '{0}'. {1}". format(task, error_response(vapp))) -def _get_management_network_from_node(): - """ - get management network name from: - * node properties or - * provider context (bootstrap context) - """ - management_network_name = ctx.node.properties.get('management_network') - if not management_network_name: - resources = ctx.provider_context.get('resources') - if resources and 'int_network' in resources: - management_network_name = resources['int_network'].get('name') - if not management_network_name: - raise cfy_exc.NonRecoverableError( - "Parameter 'managment_network' for Server node is not defined.") - return management_network_name - - def _get_state(vca_client): """ check network connection availability for host @@ -352,7 +335,6 @@ def _get_state(vca_client): ctx.instance.runtime_properties['ip'] = None ctx.instance.runtime_properties['networks'] = {} return True - management_network_name = _get_management_network_from_node() if not all([connection['ip'] for connection in nw_connections]): ctx.logger.info("Network configuration is not finished yet.") @@ -363,9 +345,11 @@ def _get_state(vca_client): for connection in nw_connections} for connection in nw_connections: - if connection['network_name'] == management_network_name: - ctx.logger.info("Management network ip address {0}" - .format(connection['ip'])) + if connection['is_primary']: + ctx.logger.info("Primary network ip address '{0}' for" + " network '{1}'." + .format(connection['ip'], + connection['network_name'])) ctx.instance.runtime_properties['ip'] = connection['ip'] return True return False @@ -486,13 +470,8 @@ def _create_connections_list(vca_client): ports = _get_connected(ctx.instance, 'port') networks = _get_connected(ctx.instance, 'network') - management_network_name = _get_management_network_from_node() - - if not is_network_exists(vca_client, management_network_name): - raise cfy_exc.NonRecoverableError( - "Network '{0}' could not be found".format(management_network_name)) + management_network_name = ctx.node.properties.get('management_network') - # connection by port for port in ports: port_properties = port.node.properties['port'] connections.append( @@ -504,21 +483,36 @@ def _create_connections_list(vca_client): port_properties.get('primary_interface', False)) ) - # connection by networks for net in networks: connections.append( _create_connection(get_network_name(net.node.properties), None, None, 'POOL')) - # add managmenty network if not exist in list - if not any([conn['network'] == management_network_name - for conn in connections]): + if management_network_name and not any( + [conn['network'] == management_network_name + for conn in connections]): connections.append(_create_connection(management_network_name, None, None, 'POOL')) + for conn in connections: + if not is_network_exists(vca_client, conn['network']): + raise cfy_exc.NonRecoverableError( + "Network '{0}' could not be found".format(conn['network'])) + primary_iface_set = len(filter(lambda conn: conn.get('primary_interface', False), connections)) > 0 + if not primary_iface_set: + if management_network_name: + primary_name = management_network_name + else: + if ports: + primary_name = ports[0]['network'] + elif networks: + primary_name = networks[0]['network'] + else: + raise cfy_exc.NonRecoverableError( + "Can't setup primary interface") # check list of connections and set managment network as primary # in case when we dont have any primary networks @@ -529,10 +523,13 @@ def _create_connections_list(vca_client): raise cfy_exc.NonRecoverableError( "DHCP for network {0} is not available" .format(network_name)) - if primary_iface_set is False: conn['primary_interface'] = \ - (network_name == management_network_name) + (network_name == primary_name) + if conn['primary_interface']: + ctx.logger.info( + "The primary interface has been set to {}".format( + primary_name)) return connections From 5d172bb7750ef51fc52971ec8e282a6ae3c8f923 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 11:02:51 +0400 Subject: [PATCH 062/228] CFY-3308 create network list before create VM --- server_plugin/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index bbb31d9..03db766 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -127,6 +127,7 @@ def _create(vca_client, config, server): vapp_name = server['name'] vapp_template = server['template'] vapp_catalog = server['catalog'] + connections = _create_connections_list(vca_client) ctx.logger.info("Creating VApp with parameters: {0}".format(server)) task = vca_client.create_vapp(config['vdc'], vapp_name, @@ -139,7 +140,6 @@ def _create(vca_client, config, server): wait_for_task(vca_client, task) ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = vapp_name - connections = _create_connections_list(vca_client) # we allways have connection to management_network_name if connections: From 1a5cb868abbdd6b99796c91ada0ec86871261c4c Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 12:32:15 +0400 Subject: [PATCH 063/228] CFY-3308 Fix checks of existing rules --- network_plugin/public_nat.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 0c1f1a8..b4af830 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -386,10 +386,7 @@ def _is_rule_exists(nat_rules, rule_type, if (all(map(cicmp, [ (rule_type, natRule.get_RuleType()), (original_ip, gatewayNatRule.get_OriginalIp()), - (str(original_port), gatewayNatRule.get_OriginalPort()), - (translated_ip, gatewayNatRule.get_TranslatedIp()), - (str(translated_port), gatewayNatRule.get_TranslatedPort()), - (protocol, gatewayNatRule.get_Protocol())]))): + (str(original_port), gatewayNatRule.get_OriginalPort())]))): break else: return False From 0ddd5d341a3a675dc05f97015c22997e2a47f025 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 14:26:03 +0400 Subject: [PATCH 064/228] CFY-3308 Customization with keypairs only --- server_plugin/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 03db766..4553b68 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -269,10 +269,11 @@ def configure(vca_client, **kwargs): vapp_name = server['name'] config = get_vcloud_config() custom = server.get(GUEST_CUSTOMIZATION) - if custom: + public_keys = _get_connected_keypairs() + if custom or public_keys: vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) - script = _build_script(custom) + script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') @@ -380,13 +381,12 @@ def _get_vm_network_connection(vapp, network_name): return connection -def _build_script(custom): +def _build_script(custom, public_keys): """ create customization script """ pre_script = custom.get('pre_script', "") post_script = custom.get('post_script', "") - public_keys = _get_connected_keypairs() if not pre_script and not post_script and not public_keys: return None script_executor = custom.get('script_executor', DEFAULT_EXECUTOR) From f9a45328b2932ca41133aae0e6d9f5baf39f415b Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 14:33:12 +0400 Subject: [PATCH 065/228] CFY-3308 Change key for replacement ports from tuple to string --- network_plugin/public_nat.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index b4af830..6d2ba53 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -177,6 +177,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, translated_port, protocol) function = gateway.add_nat_rule message = "Add" + elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) @@ -230,6 +231,7 @@ def _save_configuration(gateway, vca_client, operation, public_ip): ctx ) del ctx.target.instance.runtime_properties[PUBLIC_IP] + del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] return True @@ -335,6 +337,7 @@ def _get_original_port_for_create( else: return original_port + ctx.target.instance.runtime_properties.setdefault(PORT_REPLACEMENT, {}) # origin port can be string for port in xrange(int(original_port), utils.MAX_PORT_NUMBER + 1): if not _is_rule_exists(nat_rules, rule_type, original_ip, @@ -346,13 +349,9 @@ def _get_original_port_for_create( ctx.logger.info( "For IP {} replace original port {} -> {}" .format(original_ip, original_port, port)) - if (PORT_REPLACEMENT not in - ctx.target.instance.runtime_properties): - ctx.target.instance.runtime_properties[ - PORT_REPLACEMENT] = {} + key = '{}:{}'.format(original_ip, original_port) ctx.target.instance.runtime_properties[ - PORT_REPLACEMENT][ - (original_ip, original_port)] = port + PORT_REPLACEMENT][key] = port return port raise cfy_exc.NonRecoverableError( "Can't create NAT rule because maximum port number was reached") @@ -362,14 +361,10 @@ def _get_original_port_for_delete(original_ip, original_port): """ check may be we already replaced port by some new free port """ - if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: - runtime_properties = ctx.target.instance.runtime_properties - port = runtime_properties[PORT_REPLACEMENT].get( - (original_ip, original_port) - ) - return port if port else original_port - else: - return original_port + runtime_properties = ctx.target.instance.runtime_properties + key = '{}:{}'.format(original_ip, original_port) + port = runtime_properties[PORT_REPLACEMENT].get(key) + return port if port else original_port def _is_rule_exists(nat_rules, rule_type, From 92788e280ad6c2638fea17787446093cb1e02a0d Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 14:42:05 +0400 Subject: [PATCH 066/228] CFY-3308 Add default value for GUEST_CUSTOMIZATION. Add verbose exception description --- server_plugin/server.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 4553b68..414f404 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -268,7 +268,7 @@ def configure(vca_client, **kwargs): server.update(ctx.node.properties.get('server', {})) vapp_name = server['name'] config = get_vcloud_config() - custom = server.get(GUEST_CUSTOMIZATION) + custom = server.get(GUEST_CUSTOMIZATION, {}) public_keys = _get_connected_keypairs() if custom or public_keys: vdc = vca_client.get_vdc(config['vdc']) @@ -285,14 +285,15 @@ def configure(vca_client, **kwargs): ) if task is None: raise cfy_exc.NonRecoverableError( - "Could not set guest customization parameters") + "Could not set guest customization parameters. {0}". + format(error_response(vapp))) wait_for_task(vca_client, task) - # This function avialable from API version 5.6 if vapp.customize_on_next_poweron(): ctx.logger.info("Customizations successful") else: raise cfy_exc.NonRecoverableError( - "Can't run customization in next power on") + "Can't run customization in next power on. {0}". + format(error_response(vapp))) hardware = server.get('hardware') if hardware: From 813512d5092d02eae5fe910da3065a80f71b7789 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 4 Aug 2015 15:14:36 +0400 Subject: [PATCH 067/228] CFY-3308 Fix logic --- network_plugin/keypair.py | 18 +++++ network_plugin/public_nat.py | 14 ++-- plugin.yaml | 8 +++ server_plugin/server.py | 15 ++-- .../test_mock_network_plugin_public_nat.py | 56 ++++++++------- .../test_mock_server_plugin_server.py | 26 ++++--- ...est_mock_server_plugin_server_subroutes.py | 70 ++----------------- 7 files changed, 94 insertions(+), 113 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 0496934..5ff05d8 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -13,6 +13,7 @@ KEY = 'key' USER = 'user' HOME = 'home' +SSH_KEY = 'ssh_key' @operation @@ -69,6 +70,23 @@ def delete(**kwargs): del ctx.instance.runtime_properties[PUBLIC_KEY] +@operation +def server_connect_to_keypair(**kwargs): + host_rt_properties = ctx.source.instance.runtime_properties + if SSH_KEY not in host_rt_properties: + host_rt_properties[SSH_KEY] = {} + host_rt_properties[SSH_KEY][PATH] = ctx.instance.runtime_properties[PRIVATE_KEY][PATH] + host_rt_properties[SSH_KEY][KEY] = ctx.instance.runtime_properties[PRIVATE_KEY][KEY] + host_rt_properties[SSH_KEY][USER] = ctx.instance.runtime_properties[PUBLIC_KEY][USER] + + +@operation +def server_disconnect_from_keypair(**kwargs): + host_rt_properties = ctx.source.instance.runtime_properties + if SSH_KEY in host_rt_properties: + del host_rt_properties[SSH_KEY] + + def _generate_pair(): Random.atfork() # uses for strong key generation key = RSA.generate(2048) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 6d2ba53..211fbb5 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -25,6 +25,7 @@ from IPy import IP PORT_REPLACEMENT = 'port_replacement' +DEFAULT_SSH_PORT = '22' @operation @@ -177,7 +178,8 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, translated_port, protocol) function = gateway.add_nat_rule message = "Add" - + if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: + ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) @@ -230,8 +232,10 @@ def _save_configuration(gateway, vca_client, operation, public_ip): ctx.target.instance.runtime_properties[PUBLIC_IP], ctx ) - del ctx.target.instance.runtime_properties[PUBLIC_IP] - del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] + if PUBLIC_IP in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[PUBLIC_IP] + if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] return True @@ -320,6 +324,7 @@ def _get_original_port_for_create( return port that can be used in rule, if port have already used return new port that is next free port after current """ + ctx.target.instance.runtime_properties.setdefault(PORT_REPLACEMENT, {}) nat_rules = gateway.get_nat_rules() if isinstance( original_port, basestring) and original_port.lower() == 'any': @@ -337,7 +342,6 @@ def _get_original_port_for_create( else: return original_port - ctx.target.instance.runtime_properties.setdefault(PORT_REPLACEMENT, {}) # origin port can be string for port in xrange(int(original_port), utils.MAX_PORT_NUMBER + 1): if not _is_rule_exists(nat_rules, rule_type, original_ip, @@ -362,6 +366,8 @@ def _get_original_port_for_delete(original_ip, original_port): check may be we already replaced port by some new free port """ runtime_properties = ctx.target.instance.runtime_properties + if PORT_REPLACEMENT not in runtime_properties: + return original_port key = '{}:{}'.format(original_ip, original_port) port = runtime_properties[PORT_REPLACEMENT].get(key) return port if port else original_port diff --git a/plugin.yaml b/plugin.yaml index 5742bc0..38eaf17 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -224,3 +224,11 @@ relationships: inputs: {} cloudify.vcloud.server_connected_to_keypair: derived_from: cloudify.relationships.connected_to + target_interfaces: + cloudify.interfaces.relationship_lifecycle: + establish: + implementation: vcloud.network_plugin.keypair.server_connect_to_keypair + inputs: {} + unlink: + implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair + inputs: {} \ No newline at end of file diff --git a/server_plugin/server.py b/server_plugin/server.py index 414f404..cc0ee62 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -506,14 +506,11 @@ def _create_connections_list(vca_client): if not primary_iface_set: if management_network_name: primary_name = management_network_name + elif connections: + primary_name = connections[0]['network'] else: - if ports: - primary_name = ports[0]['network'] - elif networks: - primary_name = networks[0]['network'] - else: - raise cfy_exc.NonRecoverableError( - "Can't setup primary interface") + raise cfy_exc.NonRecoverableError( + "Can't setup primary interface") # check list of connections and set managment network as primary # in case when we dont have any primary networks @@ -524,13 +521,13 @@ def _create_connections_list(vca_client): raise cfy_exc.NonRecoverableError( "DHCP for network {0} is not available" .format(network_name)) - if primary_iface_set is False: + if not primary_iface_set: conn['primary_interface'] = \ (network_name == primary_name) if conn['primary_interface']: ctx.logger.info( "The primary interface has been set to {}".format( - primary_name)) + network_name)) return connections diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 9bc7ac0..fbefea4 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -39,13 +39,16 @@ def test_is_rule_exists(self): # not exist self.assertFalse( public_nat._is_rule_exists( - [rule_inlist], 'SNAT', 'external', '22', 'internal', + [rule_inlist], 'DNAT', 'external', '22', 'internal', '11', 'UDP') ) def test_get_original_port_for_delete(self): # no replacement fake_ctx = self.generate_relation_context() + fake_ctx._target.instance.runtime_properties = { + public_nat.PORT_REPLACEMENT: {}} + with mock.patch( 'network_plugin.public_nat.ctx', fake_ctx ): @@ -57,7 +60,7 @@ def test_get_original_port_for_delete(self): fake_ctx = self.generate_relation_context() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: { - ("10.1.1.2", "11"): '12' + "10.1.1.2:11": '12' } } with mock.patch( @@ -71,7 +74,7 @@ def test_get_original_port_for_delete(self): fake_ctx = self.generate_relation_context() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: { - ("10.1.1.2", "11"): '12' + "10.1.1.2:11": '12' } } with mock.patch( @@ -84,30 +87,27 @@ def test_get_original_port_for_delete(self): def test_get_original_port_for_create(self): gateway = mock.Mock() + fake_ctx = self.generate_relation_context() rule_inlist = self.generate_nat_rule( - 'SNAT', 'external', 'any', 'internal', '11', 'TCP' - ) + 'DNAT', 'external', 'any', 'internal', '11', 'TCP') gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) - # exeption about same port - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', 'any', 'internal', '11', 'TCP' - ) - # everythiong fine with different port - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', 'any', 'internal', '12', 'TCP' - ), - 'any' - ) - # relink some port to other - # port have not used yet - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', 10, 'internal', '12', 'TCP' - ), - 10 - ) + with mock.patch( + 'network_plugin.public_nat.ctx', fake_ctx + ): + # exeption about same port + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat._get_original_port_for_create( + gateway, 'DNAT', 'external', 'any', 'internal', '11', 'TCP' + ) + # everythiong fine with different port + self.assertEqual( + public_nat._get_original_port_for_create( + gateway, 'DNAT', 'external', '12', 'internal', '12', 'TCP'), 12) + # relink some port to other + # port have not used yet + self.assertEqual( + public_nat._get_original_port_for_create( + gateway, 'SNAT', 'external', 13, 'internal', '12', 'TCP'), 13) def test_get_original_port_for_create_with_ctx(self): # with replace, but without replace table - up port +1 @@ -133,7 +133,7 @@ def test_get_original_port_for_create_with_ctx(self): fake_ctx._target.instance.runtime_properties, { public_nat.PORT_REPLACEMENT: { - ('external', '10'): 11 + 'external:10': 11 } } ) @@ -152,7 +152,7 @@ def test_get_original_port_for_create_with_ctx(self): fake_ctx._target.instance.runtime_properties, { public_nat.PORT_REPLACEMENT: { - ('external', '10'): 11 + 'external:10': 11 } } ) @@ -497,6 +497,8 @@ def test_nat_network_operation(self): ) # run correct operation/rule fake_ctx = self.generate_relation_context() + fake_ctx._target.instance.runtime_properties = { + public_nat.PORT_REPLACEMENT: {}} for operation in [network_plugin.DELETE, network_plugin.CREATE]: for rule_type in ["SNAT", "DNAT"]: with mock.patch( diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 98b7750..8757977 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -142,6 +142,7 @@ def test_start(self): fake_ctx = self.generate_node_context() fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': True, 'network_name': 'network_name', 'ip': '1.1.1.1' }]) @@ -174,6 +175,16 @@ def test_start(self): with self.assertRaises(cfy_exc.NonRecoverableError): server.start(ctx=fake_ctx) + fake_client = self.generate_client([{ + 'is_connected': False, + 'is_primary': False, + 'network_name': 'network_name', + 'ip': '1.1.1.1' + }]) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): # poweroff with success in task but not connected fake_client._vapp.me.get_status = mock.MagicMock( return_value=vcloud_plugin_common.STATUS_POWERED_OFF @@ -184,18 +195,17 @@ def test_start(self): fake_client._vapp.poweron = mock.MagicMock( return_value=fake_task ) - with self.assertRaises(cfy_exc.OperationRetry): - server.start(ctx=fake_ctx) + self.assertEquals(server.start(ctx=fake_ctx), None) # poweron with success in task but not connected fake_client._vapp.me.get_status = mock.MagicMock( return_value=vcloud_plugin_common.STATUS_POWERED_OFF ) - with self.assertRaises(cfy_exc.OperationRetry): - server.start(ctx=fake_ctx) + self.assertEquals(server.start(ctx=fake_ctx), None) fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': True, 'network_name': '_management_network', 'ip': '1.1.1.1' }]) @@ -207,8 +217,7 @@ def test_start(self): fake_client._vapp.me.get_status = mock.MagicMock( return_value=vcloud_plugin_common.STATUS_POWERED_ON ) - with self.assertRaises(cfy_exc.OperationRetry): - server.start(ctx=fake_ctx) + self.assertEquals(server.start(ctx=fake_ctx), None) def test_start_external_resource(self): """ @@ -225,6 +234,7 @@ def test_start_external_resource(self): ) fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': True, 'network_name': 'network_name', 'ip': '1.1.1.1' }]) @@ -232,8 +242,7 @@ def test_start_external_resource(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - with self.assertRaises(cfy_exc.OperationRetry): - server.start(ctx=fake_ctx) + self.assertEquals(server.start(ctx=fake_ctx), None) def test_create_default_values(self): """ @@ -257,6 +266,7 @@ def test_create_default_values(self): self.run_with_statuses( fake_client, fake_ctx ) + fake_ctx.instance._relationships = None with self.assertRaises(cfy_exc.NonRecoverableError): server.create(ctx=fake_ctx) fake_client.create_vapp.assert_called_with( diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 397f372..7b42040 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -60,74 +60,11 @@ def test_check_hardware_memory_is_string(self): def test_check_hardware(self): server._check_hardware(1, 512) - def test_get_management_network_name_in_properties(self): - ''' exist some managment network name in properties ''' - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'management_network': '_management_network' - }) - with mock.patch('server_plugin.server.ctx', fake_ctx): - self.assertEqual( - '_management_network', - server._get_management_network_from_node() - ) - - def test_get_management_network_name_without_properties(self): - ''' without name in properties ''' - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={}) - with mock.patch('server_plugin.server.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - server._get_management_network_from_node() - - def test_get_management_network_name_in_provider_context(self): - ''' with name in provider_context ''' - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={}, - provider_context={ - 'resources': { - 'int_network': { - 'name': '_management_network' - } - } - }) - with mock.patch('server_plugin.server.ctx', fake_ctx): - self.assertEqual( - '_management_network', - server._get_management_network_from_node() - ) - - def test_get_management_network_without_name_in_context(self): - ''' without name in provider_context ''' - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={}, - provider_context={ - 'resources': { - 'int_network': { - 'other_name': '_management_network' - } - } - }) - with mock.patch('server_plugin.server.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - self.assertEqual( - '_management_network', - server._get_management_network_from_node() - ) - def test_build_script(self): with mock.patch('server_plugin.server._get_connected_keypairs', mock.MagicMock( return_value=[])): - self.assertEqual(None, server._build_script({})) + self.assertEqual(None, server._build_script({}, [])) custom = { 'pre_script': 'pre_script', @@ -139,7 +76,7 @@ def test_build_script(self): with mock.patch('server_plugin.server._get_connected_keypairs', mock.MagicMock( return_value=[{'key': 'key'}])): - self.assertNotEqual(None, server._build_script(custom)) + self.assertNotEqual(None, server._build_script(custom, [])) def test_build_public_keys_script(self): self.assertEqual('', server._build_public_keys_script([])) @@ -508,6 +445,7 @@ def test_get_state(self): # connected network_name fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': False, 'network_name': 'network_name', 'ip': '1.1.1.1' }]) @@ -522,6 +460,7 @@ def test_get_state(self): # not ip in connected network_name fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': False, 'network_name': 'network_name', 'ip': None }]) @@ -529,6 +468,7 @@ def test_get_state(self): # with managment_network fake_client = self.generate_client([{ 'is_connected': True, + 'is_primary': True, 'network_name': '_management_network', 'ip': '1.1.1.1' }]) From a72a0459ba2f08c242f75220e80fcb43131b00d5 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 6 Aug 2015 08:46:42 +0400 Subject: [PATCH 068/228] Fix relationships --- network_plugin/keypair.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 5ff05d8..a29bf3b 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -75,9 +75,9 @@ def server_connect_to_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY not in host_rt_properties: host_rt_properties[SSH_KEY] = {} - host_rt_properties[SSH_KEY][PATH] = ctx.instance.runtime_properties[PRIVATE_KEY][PATH] - host_rt_properties[SSH_KEY][KEY] = ctx.instance.runtime_properties[PRIVATE_KEY][KEY] - host_rt_properties[SSH_KEY][USER] = ctx.instance.runtime_properties[PUBLIC_KEY][USER] + host_rt_properties[SSH_KEY][PATH] = ctx.target.instance.runtime_properties[PRIVATE_KEY][PATH] + host_rt_properties[SSH_KEY][KEY] = ctx.target.instance.runtime_properties[PRIVATE_KEY][KEY] + host_rt_properties[SSH_KEY][USER] = ctx.target.instance.runtime_properties[PUBLIC_KEY][USER] @operation From d8286b1974b1a41d2e1609d2773ceb18c586b8ad Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 12 Aug 2015 12:20:55 +0400 Subject: [PATCH 069/228] CFY-3290 Create more verbose error messages --- network_plugin/__init__.py | 13 +++++--- network_plugin/network.py | 7 +++-- network_plugin/public_nat.py | 3 +- server_plugin/server.py | 9 +++--- server_plugin/volume.py | 20 +++++++----- tests/integration/test_server_plugin.py | 1 + tests/unittests/test_mock_network_plugin.py | 21 ++++++------- .../test_mock_network_plugin_public_nat.py | 6 ++-- .../test_mock_vcloud_plugin_common.py | 15 +++++---- vcloud_plugin_common/__init__.py | 31 +++++++++++++------ 10 files changed, 77 insertions(+), 49 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index a5e028b..ec3dcca 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -3,7 +3,7 @@ import collections from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType from vcloud_plugin_common import (wait_for_task, get_vcloud_config, - is_subscription) + is_subscription, error_response) VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -229,18 +229,19 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): try to allocate new public ip for ondemand service """ old_public_ips = set(gateway.get_public_ips()) + ctx.logger.info("Try to allocate public IP") task = gateway.allocate_public_ip() if task: wait_for_task(vca_client, task) else: raise cfy_exc.NonRecoverableError( - "Can't get public ip for ondemand service") + "Can't get public ip for ondemand service {0}".format(error_response(gateway))) # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) new_ip = new_public_ips - old_public_ips if new_ip: - ctx.logger.info("Assign public IP {0}".format(new_ip)) + ctx.logger.info("Public IP {0} was asigned.".format(new_ip)) else: raise cfy_exc.NonRecoverableError( "Can't get new public IP address") @@ -251,13 +252,15 @@ def del_ondemand_public_ip(vca_client, gateway, ip, ctx): """ try to deallocate public ip """ + ctx.logger.info("Try to deallocate public IP {0}".format(ip)) task = gateway.deallocate_public_ip(ip) if task: wait_for_task(vca_client, task) - ctx.logger.info("Public IP {0} deallocated".format(ip)) + ctx.logger.info("Public IP {0} was deallocated".format(ip)) else: raise cfy_exc.NonRecoverableError( - "Can't deallocate public ip {0} for ondemand service".format(ip)) + "Can't deallocate public ip {0}. {1} for ondemand service". + format(ip, error_response(gateway))) def get_public_ip(vca_client, gateway, service_type, ctx): diff --git a/network_plugin/network.py b/network_plugin/network.py index dfbd6ac..b463466 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -86,17 +86,19 @@ def create(vca_client, **kwargs): if len(dns_list) > 1: dns2 = dns_list[1] dns_suffix = net_prop.get("dns_suffix") + ctx.logger.info("Create network {0}." + .format(network_name)) success, result = vca_client.create_vdc_network( vdc_name, network_name, gateway_name, start_address, end_address, gateway_ip, netmask, dns1, dns2, dns_suffix) if success: + wait_for_task(vca_client, result) ctx.logger.info("Network {0} has been successfully created." .format(network_name)) else: raise cfy_exc.NonRecoverableError( "Could not create network {0}: {1}". format(network_name, result)) - wait_for_task(vca_client, result) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name if not _dhcp_operation(vca_client, network_name, ADD_POOL): ctx.instance.runtime_properties[SKIP_CREATE_NETWORK] = True @@ -117,9 +119,11 @@ def delete(vca_client, **kwargs): network_name = get_network_name(ctx.node.properties) if not _dhcp_operation(vca_client, network_name, DELETE_POOL): return set_retry(ctx) + ctx.logger.info("Delete network '{0}'".format(network_name)) success, task = vca_client.delete_vdc_network( get_vcloud_config()['vdc'], network_name) if success: + wait_for_task(vca_client, task) ctx.logger.info( "Network '{0}' has been successful deleted.".format(network_name)) else: @@ -129,7 +133,6 @@ def delete(vca_client, **kwargs): return raise cfy_exc.NonRecoverableError( "Could not delete network '{0}': {1}".format(network_name, task)) - wait_for_task(vca_client, task) @operation diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 211fbb5..b4d090d 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -217,10 +217,11 @@ def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ + ctx.logger.info("Save NAT configuration.") success = save_gateway_configuration(gateway, vca_client) if not success: return False - ctx.logger.info("NAT configuration has been saved") + ctx.logger.info("NAT configuration has been saved.") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip else: diff --git a/server_plugin/server.py b/server_plugin/server.py index cc0ee62..13df9be 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -152,7 +152,8 @@ def _create(vca_client, config, server): network_name = connection.get('network') network = get_network(vca_client, network_name) - + ctx.logger.info("Connect network '{0}' to server '{1}'." + .format(network_name, vapp_name)) task = vapp.connect_to_network(network_name, network.get_href()) if not task: raise cfy_exc.NonRecoverableError( @@ -276,7 +277,7 @@ def configure(vca_client, **kwargs): script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') - + ctx.logger.info("Customize guest OS") task = vapp.customize_guest_os( vapp_name, customization_script=script, @@ -305,18 +306,18 @@ def configure(vca_client, **kwargs): ) if memory: try: + ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) - ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM memory failed: '{0}'. {1}". format(task, error_response(vapp))) if cpu: try: + ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) - ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM cpu failed: '{0}'. {1}". diff --git a/server_plugin/volume.py b/server_plugin/volume.py index 70a00df..94b2a1b 100644 --- a/server_plugin/volume.py +++ b/server_plugin/volume.py @@ -41,10 +41,12 @@ def create_volume(vca_client, **kwargs): name = ctx.node.properties['volume']['name'] size = ctx.node.properties['volume']['size'] size_in_Mb = size * 1024 * 1024 + ctx.logger.info("Create volume '{0}' to '{1}' with size {2}Mb." + .format(name, vdc_name, size_in_Mb)) success, disk = vca_client.add_disk(vdc_name, name, size_in_Mb) if success: wait_for_task(vca_client, disk.get_Tasks()[0]) - ctx.logger.info("Volume node {} has been created".format(name)) + ctx.logger.info("Volume node '{0}' has been created".format(name)) else: raise cfy_exc.NonRecoverableError( "Disk creation error: {0}".format(disk)) @@ -61,10 +63,12 @@ def delete_volume(vca_client, **kwargs): return vdc_name = get_vcloud_config()['vdc'] name = ctx.node.properties['volume']['name'] + ctx.logger.info("Delete volume '{0}' from '{1}'." + .format(name, vdc_name)) success, task = vca_client.delete_disk(vdc_name, name) if success: wait_for_task(vca_client, task) - ctx.logger.info("Volume node {} has been deleted".format(name)) + ctx.logger.info("Volume node '{0}' has been deleted".format(name)) else: raise cfy_exc.NonRecoverableError( "Disk deletion error: {0}".format(task)) @@ -127,27 +131,29 @@ def _volume_operation(vca_client, operation): for ref in vca_client.get_diskRefs(vdc): if ref.name == volumeName: if operation == 'ATTACH': + ctx.logger.info("Attach volume node '{0}'.".format(volumeName)) task = vapp.attach_disk_to_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( - "Volume node {} has been attached".format(volumeName)) + "Volume node '{0}' has been attached".format(volumeName)) else: raise cfy_exc.NonRecoverableError( - "Can't attach disk: {0} {1}". + "Can't attach disk: '{0}' with error: {1}". format(volumeName, error_response(vapp))) elif operation == 'DETACH': + ctx.logger.info("Detach volume node '{0}'.".format(volumeName)) task = vapp.detach_disk_from_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( - "Volume node {0} has been detached.". + "Volume node '{0}' has been detached.". format(volumeName)) else: raise cfy_exc.NonRecoverableError( - "Can't detach disk: {0}. {1}". + "Can't detach disk: '{0}'. With error: {1}". format(volumeName, error_response(vapp))) else: raise cfy_exc.NonRecoverableError( - "Unknown operation {0}".format(operation)) + "Unknown operation '{0}'".format(operation)) diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index 2e41d3c..d8d1dff 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -108,6 +108,7 @@ def test_server_creation_validation_parameter_missing(self): def test_server_create_delete(self): server.create() + server.configure() vdc = self.vca_client.get_vdc(self.vcloud_config['org']) vapp = self.vca_client.get_vapp( vdc, diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index acaa62f..1be23b4 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -172,9 +172,9 @@ def test_del_ondemand_public_ip(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) - network_plugin.del_ondemand_public_ip( - fake_client, gateway, '127.0.0.1', fake_ctx - ) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + network_plugin.del_ondemand_public_ip( + fake_client, gateway, '127.0.0.1', fake_ctx) def test_save_gateway_configuration(self): """ @@ -196,18 +196,17 @@ def test_save_gateway_configuration(self): gateway, vcloud_plugin_common.TASK_STATUS_ERROR ) with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.save_gateway_configuration( - gateway, fake_client - ) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + network_plugin.save_gateway_configuration( + gateway, fake_client) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - self.assertTrue( - network_plugin.save_gateway_configuration( - gateway, fake_client - ) - ) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + self.assertTrue( + network_plugin.save_gateway_configuration( + gateway, fake_client)) # server busy self.set_services_conf_result( gateway, None diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index fbefea4..b483fc9 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -405,9 +405,9 @@ def _ip_exist_in_runtime(fake_ctx): 'network_plugin.public_nat.ctx', fake_ctx ): # success save configuration - public_nat._save_configuration( - gateway, fake_client, network_plugin.CREATE, "1.2.3.4" - ) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + public_nat._save_configuration( + gateway, fake_client, network_plugin.CREATE, "1.2.3.4") self.assertEqual( fake_ctx._target.instance.runtime_properties, { diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 42f5a40..320e674 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -182,13 +182,15 @@ def test_wait_for_task(self): fake_task = self.generate_task( vcloud_plugin_common.TASK_STATUS_ERROR ) - with self.assertRaises(cfy_exc.NonRecoverableError): - vcloud_plugin_common.wait_for_task(fake_client, fake_task) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with self.assertRaises(cfy_exc.NonRecoverableError): + vcloud_plugin_common.wait_for_task(fake_client, fake_task) # success in task fake_task = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS ) - vcloud_plugin_common.wait_for_task(fake_client, fake_task) + with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + vcloud_plugin_common.wait_for_task(fake_client, fake_task) # success after wait fake_task = self.generate_task( None @@ -210,9 +212,10 @@ def test_wait_for_task(self): 'time.sleep', sleep ): - vcloud_plugin_common.wait_for_task( - fake_client, fake_task - ) + with mock.patch('vcloud_plugin_common.ctx', + mock.MagicMock()): + vcloud_plugin_common.wait_for_task( + fake_client, fake_task) def test_with_vca_client(self): # context.NODE_INSTANCE diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 66f9bf6..e9436d5 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -26,7 +26,7 @@ from cloudify import context from cloudify import exceptions as cfy_exc -TASK_RECHECK_TIMEOUT = 2 +TASK_RECHECK_TIMEOUT = 3 RELOGIN_TIMEOUT = 3 TASK_STATUS_SUCCESS = 'success' TASK_STATUS_ERROR = 'error' @@ -400,21 +400,32 @@ def wait_for_task(vca_client, task): """ check status of current task and make request for recheck task status in case when we have not well defined state - (not error and not success) + (not error and not success or by timeout) """ + WAIT_TIME_MAX_MINUTES = 30 + MAX_ATTEMPTS = WAIT_TIME_MAX_MINUTES * 60 / TASK_RECHECK_TIMEOUT + ctx.logger.debug('Maximun task wait time {0} minutes.' + .format(WAIT_TIME_MAX_MINUTES)) + ctx.logger.debug('Task recheck after {0} seconds.' + .format(TASK_RECHECK_TIMEOUT)) status = task.get_status() - while status != TASK_STATUS_SUCCESS: + for attempt in range(MAX_ATTEMPTS): + ctx.logger.debug('Attempt: {0}/{1}.'.format(attempt + 1, MAX_ATTEMPTS)) + if status == TASK_STATUS_SUCCESS: + ctx.logger.debug('Task completed in {0} seconds' + .format(attempt * TASK_RECHECK_TIMEOUT)) + return if status == TASK_STATUS_ERROR: error = task.get_Error() raise cfy_exc.NonRecoverableError( "Error during task execution: {0}".format(error.get_message())) - else: - time.sleep(TASK_RECHECK_TIMEOUT) - response = requests.get( - task.get_href(), - headers=vca_client.vcloud_session.get_vcloud_headers()) - task = taskType.parseString(response.content, True) - status = task.get_status() + time.sleep(TASK_RECHECK_TIMEOUT) + response = requests.get( + task.get_href(), + headers=vca_client.vcloud_session.get_vcloud_headers()) + task = taskType.parseString(response.content, True) + status = task.get_status() + raise cfy_exc.NonRecoverableError("Wait for task timeout.") def get_vcloud_config(): From 5f830a0da28ecb6367779aaab1f070e92a1fe2ca Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 11 Aug 2015 14:44:25 +0400 Subject: [PATCH 070/228] CFY-3343 Create new workflow for operation with vcloud token --- plugin.yaml | 9 +- ...st_mock_vcloud_plugin_common_vca_client.py | 6 +- vcloud_plugin_common/__init__.py | 85 ++++++++++++++----- vcloud_plugin_common/workflows.py | 74 ++++++++++++++++ 4 files changed, 146 insertions(+), 28 deletions(-) create mode 100644 vcloud_plugin_common/workflows.py diff --git a/plugin.yaml b/plugin.yaml index 38eaf17..17b97b7 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3343.zip node_types: cloudify.vcloud.nodes.Server: @@ -231,4 +231,9 @@ relationships: inputs: {} unlink: implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair - inputs: {} \ No newline at end of file + inputs: {} + +workflows: + scoreinstall: vcloud.vcloud_plugin_common.workflows.install + + scoreuninstall: vcloud.vcloud_plugin_common.workflows.uninstall diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 85c8cd2..725cc6e 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -55,8 +55,7 @@ def _run( ): return client._subscription_login( url, username, password, token, service, - org_name - ) + org_name) # can't login with token with self.assertRaises(cfy_exc.NonRecoverableError): _run( @@ -125,8 +124,7 @@ def _run( 'vcloud_plugin_common.ctx', fake_ctx ): return client._ondemand_login( - url, username, password, token, instance_id - ) + url, username, password, token, instance_id) # bad case without instance with self.assertRaises(cfy_exc.NonRecoverableError): diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index e9436d5..f714f3e 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -28,6 +28,7 @@ TASK_RECHECK_TIMEOUT = 3 RELOGIN_TIMEOUT = 3 +LOGIN_RETRY_NUM = 5 TASK_STATUS_SUCCESS = 'success' TASK_STATUS_ERROR = 'error' @@ -66,6 +67,9 @@ SUBSCRIPTION_SERVICE_TYPE = 'subscription' ONDEMAND_SERVICE_TYPE = 'ondemand' PRIVATE_SERVICE_TYPE = 'vcd' +SESSION_TOKEN = 'session_token' +ORG_URL = 'org_url' +VCLOUD_CONFIG = 'vcloud_config' def transform_resource_name(res, ctx): @@ -127,7 +131,6 @@ def get(self): class VcloudAirClient(object): config = Config - LOGIN_RETRY_NUM = 5 def get(self, config=None, *args, **kw): """ @@ -152,8 +155,10 @@ def connect(self, cfg): org_name = cfg.get('org') service_type = cfg.get('service_type', SUBSCRIPTION_SERVICE_TYPE) instance = cfg.get('instance') - org_url = cfg.get('org_url', None) + org_url = cfg.get(ORG_URL, None) api_version = cfg.get('api_version', '5.6') + session_token = cfg.get(SESSION_TOKEN) + org_url = cfg.get(ORG_URL) if not (all([url, token]) or all([url, username, password])): raise cfy_exc.NonRecoverableError( "Login credentials must be specified") @@ -165,10 +170,12 @@ def connect(self, cfg): if service_type == SUBSCRIPTION_SERVICE_TYPE: vcloud_air = self._subscription_login( - url, username, password, token, service, org_name) + url, username, password, token, service, org_name, + session_token, org_url) elif service_type == ONDEMAND_SERVICE_TYPE: vcloud_air = self._ondemand_login( - url, username, password, token, instance) + url, username, password, token, instance, + session_token, org_url) # The actual service type for private is 'vcd', but we should accept # 'private' as well, for user friendliness of inputs elif service_type in (PRIVATE_SERVICE_TYPE, 'private'): @@ -180,20 +187,26 @@ def connect(self, cfg): return vcloud_air def _subscription_login(self, url, username, password, token, service, - org_name): + org_name, session_token=None, org_url=None): """ login to subscription service """ + version = '5.6' logined = False vdc_logined = False - vca = vcloudair.VCA( url, username, service_type=SUBSCRIPTION_SERVICE_TYPE, - version='5.6') + version=version) + + if session_token: + if session_login(vca, org_url, session_token, version): + return vca + else: + raise cfy_exc.NonRecoverableError("Invalid session credentials") # login with token if token: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(token=token) if logined is False: ctx.logger.info("Login using token failed.") @@ -205,7 +218,7 @@ def _subscription_login(self, url, username, password, token, service, # outdated token, try login by password if logined is False and password: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(password) if logined is False: ctx.logger.info("Login using password failed. Retrying...") @@ -219,7 +232,7 @@ def _subscription_login(self, url, username, password, token, service, if logined is False: raise cfy_exc.NonRecoverableError("Invalid login credentials") - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): vdc_logined = vca.login_to_org(service, org_name) if vdc_logined is False: ctx.logger.info("Login to VDC failed. Retrying...") @@ -239,7 +252,8 @@ def _subscription_login(self, url, username, password, token, service, atexit.register(vca.logout) return vca - def _ondemand_login(self, url, username, password, token, instance_id): + def _ondemand_login(self, url, username, password, token, instance_id, + session_token=None, org_url=None): """ login to ondemand service """ @@ -249,6 +263,7 @@ def get_instance(vca, instance_id): if instance['id'] == instance_id: return instance + version = '5.7' if instance_id is None: raise cfy_exc.NonRecoverableError( "Instance ID should be specified for OnDemand login") @@ -256,11 +271,17 @@ def get_instance(vca, instance_id): instance_logined = False vca = vcloudair.VCA( - url, username, service_type=ONDEMAND_SERVICE_TYPE, version='5.7') + url, username, service_type=ONDEMAND_SERVICE_TYPE, version=version) + + if session_token: + if session_login(vca, org_url, session_token, version): + return vca + else: + raise cfy_exc.NonRecoverableError("Invalid session credentials") # login with token if token: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(token=token) if logined is False: ctx.logger.info("Login using token failed.") @@ -272,7 +293,7 @@ def get_instance(vca, instance_id): # outdated token, try login by password if logined is False and password: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(password) if logined is False: ctx.logger.info("Login using password failed. Retrying...") @@ -291,7 +312,7 @@ def get_instance(vca, instance_id): raise cfy_exc.NonRecoverableError( "Instance {0} could not be found.".format(instance_id)) - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): instance_logined = vca.login_to_instance( instance_id, password, token, None) if instance_logined is False: @@ -302,7 +323,7 @@ def get_instance(vca, instance_id): ctx.logger.info("Login to instance successful.") break - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): instance_logined = vca.login_to_instance( instance_id, @@ -342,7 +363,7 @@ def _private_login(self, url, username, password, token, org_name, version=api_version) if logined is False and password: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(password, org=org_name) if logined is False: ctx.logger.info("Login using password failed. Retrying...") @@ -360,7 +381,7 @@ def _private_login(self, url, username, password, token, org_name, # Private mode requires being logged in with a token otherwise you # don't seem to be able to retrieve any VDCs if token: - for _ in range(self.LOGIN_RETRY_NUM): + for _ in range(LOGIN_RETRY_NUM): logined = vca.login(token=token, org_url=org_url) if logined is False: ctx.logger.info("Login using token failed.") @@ -384,12 +405,18 @@ def with_vca_client(f): @wraps(f) def wrapper(*args, **kw): config = None + prop = None if ctx.type == context.NODE_INSTANCE: - config = ctx.node.properties.get('vcloud_config') + config = ctx.node.properties.get(VCLOUD_CONFIG) + prop = ctx.instance.runtime_properties elif ctx.type == context.RELATIONSHIP_INSTANCE: - config = ctx.source.node.properties.get('vcloud_config') + config = ctx.source.node.properties.get(VCLOUD_CONFIG) + prop = ctx.source.instance.runtime_properties else: raise cfy_exc.NonRecoverableError("Unsupported context") + if config and prop: + config[SESSION_TOKEN] = prop.get(SESSION_TOKEN) + config[ORG_URL] = prop.get(ORG_URL) client = VcloudAirClient().get(config=config) kw['vca_client'] = client return f(*args, **kw) @@ -434,9 +461,9 @@ def get_vcloud_config(): """ config = None if ctx.type == context.NODE_INSTANCE: - config = ctx.node.properties.get('vcloud_config') + config = ctx.node.properties.get(VCLOUD_CONFIG) elif ctx.type == context.RELATIONSHIP_INSTANCE: - config = ctx.source.node.properties.get('vcloud_config') + config = ctx.source.node.properties.get(VCLOUD_CONFIG) else: raise cfy_exc.NonRecoverableError("Unsupported context") static_config = Config().get() @@ -479,3 +506,17 @@ def error_response(obj): return obj.response.content except AttributeError: return '' + + +def session_login(vca, org_url, session_token, version): + vcs = vcloudair.VCS(org_url, None, None, None, org_url, org_url, version) + for _ in range(LOGIN_RETRY_NUM): + if not vcs.login(token=session_token): + ctx.logger.info("Login using session token failed.") + time.sleep(RELOGIN_TIMEOUT) + continue + else: + vca.vcloud_session = vcs + ctx.logger.info("Login using session token successful.") + return True + return False diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py new file mode 100644 index 0000000..0bcf6d5 --- /dev/null +++ b/vcloud_plugin_common/workflows.py @@ -0,0 +1,74 @@ +######## +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. + +from cloudify.decorators import workflow +import cloudify.plugins.workflows as default_workflow +from cloudify.manager import update_node_instance +from vcloud_plugin_common import (SESSION_TOKEN, ORG_URL, VCLOUD_CONFIG) + + +def update(ctx, instance, token, org_url): + node_instance = instance._node_instance + rt_properties = node_instance['runtime_properties'] + rt_properties.update({SESSION_TOKEN: token, + ORG_URL: org_url}) + version = node_instance['version'] + node_instance['version'] = version if version else 0 + if ctx.local: + version = node_instance['version'] + state = node_instance.get('state') + node_id = instance.id + storage = ctx.internal.handler.storage + storage.update_node_instance(node_id, version, rt_properties, state) + else: + update_node_instance(node_instance) + + +def _get_all_nodes_instances(ctx, token, org_url): + node_instances = set() + for node in ctx.nodes: + for instance in node.instances: + if token and org_url and VCLOUD_CONFIG in node.properties: + update(ctx, instance, token, org_url) + node_instances.add(instance) + return node_instances + + +@workflow +def install(ctx, **kwargs): + """Score install workflow""" + + default_workflow._install_node_instances( + ctx, + _get_all_nodes_instances(ctx, kwargs.get('session_token'), + kwargs.get('org_url')), + set(), + default_workflow.NodeInstallationTasksSequenceCreator(), + default_workflow.InstallationTasksGraphFinisher + ) + + +@workflow +def uninstall(ctx, **kwargs): + """Score uninstall workflow""" + + default_workflow._uninstall_node_instances( + ctx, + _get_all_nodes_instances(ctx, kwargs.get('session_token'), + kwargs.get('org_url')), + set(), + default_workflow.NodeUninstallationTasksSequenceCreator(), + default_workflow.UninstallationTasksGraphFinisher + ) From 8719f84d92bd15f2e632162e65714901f0980d2c Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 13 Aug 2015 15:12:40 +0300 Subject: [PATCH 071/228] CFY-3343: fix password check --- plugin.yaml | 2 +- setup.py | 2 +- vcloud_plugin_common/__init__.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 17b97b7..df5d53e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/CFY-3343.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index d25e1b1..1d30e90 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3m2', + version='1.2.1', packages=[ 'vcloud_plugin_common', 'server_plugin', diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index f714f3e..6aa7bc1 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -159,9 +159,9 @@ def connect(self, cfg): api_version = cfg.get('api_version', '5.6') session_token = cfg.get(SESSION_TOKEN) org_url = cfg.get(ORG_URL) - if not (all([url, token]) or all([url, username, password])): + if not (all([url, token]) or all([url, username, password]) or session_token): raise cfy_exc.NonRecoverableError( - "Login credentials must be specified") + "Login credentials must be specified.") if (service_type == SUBSCRIPTION_SERVICE_TYPE and not ( service and org_name )): From 52c60722f642d0c5dd04ecb2d0132a722a7a6032 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 13 Aug 2015 16:21:28 +0300 Subject: [PATCH 072/228] 1.2.1m2 release --- dev-requirements.txt | 6 +++--- examples/blueprint.yaml | 4 ++-- manager_blueprint/vcloud-manager-blueprint.yaml | 6 +++--- plugin.yaml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 6f0b776..58602ac 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ --e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@master#egg=cloudify-dsl-parser==3.2 --e git+https://github.com/cloudify-cosmo/cloudify-rest-client@master#egg=cloudify-rest-client==3.2 --e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@master#egg=cloudify-plugins-common==3.2 +-e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.2.1#egg=cloudify-dsl-parser==3.2.1 +-e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.2.1#egg=cloudify-rest-client==3.2.1 +-e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.2.1#egg=cloudify-plugins-common==3.2.1 IPy pyvcloud>=14rc6 pycrypto diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index 1e7200e..55fa64e 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,8 +1,8 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - - http://www.getcloudify.org/spec/cloudify/3.2/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m2/plugin.yaml node_types: vcloud_configuration: diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index fdce18c..b7604ba 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -1,9 +1,9 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - - http://www.getcloudify.org/spec/cloudify/3.2/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.2/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m2/plugin.yaml + - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml inputs: vcloud_username: diff --git a/plugin.yaml b/plugin.yaml index df5d53e..4821999 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m2.zip node_types: cloudify.vcloud.nodes.Server: From 0fbb75ab3aa2f4d72019d8dcb75281e9fc6e3c99 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 13 Aug 2015 18:02:27 +0300 Subject: [PATCH 073/228] update docker image --- manager_blueprint/vcloud-manager-blueprint.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index b7604ba..74ebe32 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -77,11 +77,13 @@ inputs: manager_server_catalog: type: string + default: 'Public Catalog' description: > Name of catalog, can be 'Public Catalog' manager_server_template: type: string + default: 'Ubuntu Server 12.04 LTS (amd64 20150127)' description: > Name of template from catalog, can be 'Ubuntu Server 12.04 LTS (amd64 20150127)' @@ -478,11 +480,11 @@ node_templates: properties: cloudify_packages: agents: - ubuntu_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.0/ga-RELEASE/cloudify-ubuntu-agent_3.2.0-ga-b200_amd64.deb - centos_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.0/ga-RELEASE/cloudify-centos-final-agent_3.2.0-ga-b200_amd64.deb - windows_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.0/ga-RELEASE/cloudify-windows-agent_3.2.0-ga-b200_amd64.deb + ubuntu_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-ubuntu-agent_3.2.1-ga-b212_amd64.deb + centos_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-centos-final-agent_3.2.1-ga-b212_amd64.deb + windows_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-windows-agent_3.2.1-ga-b212_amd64.deb docker: - docker_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.0/ga-RELEASE/cloudify-docker_3.2.0-ga-b200.tar + docker_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-docker_3.2.1-ga-b212.tar cloudify: resources_prefix: { get_input: resources_prefix } From eb8889bc639cde99144522ee2d0c563bbcfd2f67 Mon Sep 17 00:00:00 2001 From: Denys Makogon Date: Fri, 14 Aug 2015 12:30:19 +0300 Subject: [PATCH 074/228] CFY-3385: Fix vAPP external resource usage --- server_plugin/server.py | 129 ++++++++++-------- .../test_mock_server_plugin_server.py | 5 +- tox.ini | 2 +- 3 files changed, 78 insertions(+), 58 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 13df9be..dbd02ab 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -110,6 +110,12 @@ def create(vca_client, **kwargs): if ctx.node.properties.get('use_external_resource'): res_id = ctx.node.properties['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id + vdc = vca_client.get_vdc(config['vdc']) + if not vca_client.get_vapp(vdc, res_id): + raise cfy_exc.NonRecoverableError( + "Unable to find external vAPP server resource {0}." + .format(res_id)) + server.update({'name': res_id}) ctx.logger.info( "External resource {0} has been used".format(res_id)) else: @@ -264,64 +270,75 @@ def delete(vca_client, **kwargs): @operation @with_vca_client def configure(vca_client, **kwargs): - ctx.logger.info("Configure server") - server = {'name': ctx.instance.id} - server.update(ctx.node.properties.get('server', {})) - vapp_name = server['name'] - config = get_vcloud_config() - custom = server.get(GUEST_CUSTOMIZATION, {}) - public_keys = _get_connected_keypairs() - if custom or public_keys: - vdc = vca_client.get_vdc(config['vdc']) - vapp = vca_client.get_vapp(vdc, vapp_name) - script = _build_script(custom, public_keys) - password = custom.get('admin_password') - computer_name = custom.get('computer_name') - ctx.logger.info("Customize guest OS") - task = vapp.customize_guest_os( - vapp_name, - customization_script=script, - computer_name=computer_name, - admin_password=password - ) - if task is None: - raise cfy_exc.NonRecoverableError( - "Could not set guest customization parameters. {0}". - format(error_response(vapp))) - wait_for_task(vca_client, task) - if vapp.customize_on_next_poweron(): - ctx.logger.info("Customizations successful") - else: - raise cfy_exc.NonRecoverableError( - "Can't run customization in next power on. {0}". - format(error_response(vapp))) - - hardware = server.get('hardware') - if hardware: - cpu = hardware.get('cpu') - memory = hardware.get('memory') - _check_hardware(cpu, memory) - vapp = vca_client.get_vapp( - vca_client.get_vdc(config['vdc']), vapp_name - ) - if memory: - try: - ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) - task = vapp.modify_vm_memory(vapp_name, memory) - wait_for_task(vca_client, task) - except Exception: + + if ctx.node.properties.get('use_external_resource'): + ctx.logger.info('Avoiding external resource configuration.') + else: + ctx.logger.info("Configure server") + server = {'name': ctx.instance.id} + server.update(ctx.node.properties.get('server', {})) + ctx.logger.info("Server properties: {0}" + .format(str(server))) + vapp_name = server['name'] + config = get_vcloud_config() + custom = server.get(GUEST_CUSTOMIZATION, {}) + public_keys = _get_connected_keypairs() + if custom or public_keys: + vdc = vca_client.get_vdc(config['vdc']) + vapp = vca_client.get_vapp(vdc, vapp_name) + if not vapp: raise cfy_exc.NonRecoverableError( - "Customize VM memory failed: '{0}'. {1}". - format(task, error_response(vapp))) - if cpu: - try: - ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) - task = vapp.modify_vm_cpu(vapp_name, cpu) - wait_for_task(vca_client, task) - except Exception: + "Unable to find vAPP server " + "by its name {0}.".format(vapp_name)) + ctx.logger.info("Using vAPP {0}".format(str(vapp))) + script = _build_script(custom, public_keys) + password = custom.get('admin_password') + computer_name = custom.get('computer_name') + ctx.logger.info("Customizing guest OS.") + task = vapp.customize_guest_os( + vapp_name, + customization_script=script, + computer_name=computer_name, + admin_password=password + ) + if task is None: raise cfy_exc.NonRecoverableError( - "Customize VM cpu failed: '{0}'. {1}". - format(task, error_response(vapp))) + "Could not set guest customization parameters. {0}". + format(error_response(vapp))) + wait_for_task(vca_client, task) + if vapp.customize_on_next_poweron(): + ctx.logger.info("Customizations successful") + else: + raise cfy_exc.NonRecoverableError( + "Can't run customization in next power on. {0}". + format(error_response(vapp))) + + hardware = server.get('hardware') + if hardware: + cpu = hardware.get('cpu') + memory = hardware.get('memory') + _check_hardware(cpu, memory) + vapp = vca_client.get_vapp( + vca_client.get_vdc(config['vdc']), vapp_name + ) + if memory: + try: + ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) + task = vapp.modify_vm_memory(vapp_name, memory) + wait_for_task(vca_client, task) + except Exception: + raise cfy_exc.NonRecoverableError( + "Customize VM memory failed: '{0}'. {1}". + format(task, error_response(vapp))) + if cpu: + try: + ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) + task = vapp.modify_vm_cpu(vapp_name, cpu) + wait_for_task(vca_client, task) + except Exception: + raise cfy_exc.NonRecoverableError( + "Customize VM cpu failed: '{0}'. {1}". + format(task, error_response(vapp))) def _get_state(vca_client): diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 8757977..ecc4fb5 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -422,7 +422,10 @@ def test_create_external_resource(self): fake_ctx = self.generate_node_context( properties={ 'use_external_resource': True, - 'resource_id': 'ServerName' + 'resource_id': 'ServerName', + 'vcloud_config': { + 'vdc': 'vdc_name' + }, } ) diff --git a/tox.ini b/tox.ini index 78fb019..282784b 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,7 @@ commands = nosetests -x -s --tc=ondemand: tests/integration {posargs} commands = nosetests -x -s --tc=subscription: tests/integration {posargs} [testenv:py27-unittests] -commands = nosetests -x -s tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin +commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin [testenv:pep8] commands= From 2eb0c97297e4d0717960484a96600ab89cabd06f Mon Sep 17 00:00:00 2001 From: yoramw Date: Sun, 16 Aug 2015 18:11:05 +0300 Subject: [PATCH 075/228] add public ip for ssh to runtime properties for fabric --- network_plugin/public_nat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index b4d090d..e0277f6 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -180,6 +180,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, message = "Add" if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) + ctx.source.instance.runtime_properties['ssh_public_ip'] = public_ip elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) From 68573b36d046a0085b78e1732c552292fcedef1b Mon Sep 17 00:00:00 2001 From: yoramw Date: Sun, 16 Aug 2015 18:19:55 +0300 Subject: [PATCH 076/228] update plugin zip url --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 4821999..91a8838 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m2.zip + source: https://github.com/yoramw/tosca-vcloud-plugin/archive/cfy3.2.1.zip node_types: cloudify.vcloud.nodes.Server: From e1e3f473027e03959f81d7f26031811b75c18a4b Mon Sep 17 00:00:00 2001 From: yoramw Date: Sun, 16 Aug 2015 18:27:02 +0300 Subject: [PATCH 077/228] update floating_ip with the ssh port and ip --- network_plugin/floatingip.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 7697a93..1c7781c 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -100,6 +100,9 @@ def _floatingip_operation(operation, vca_client, ctx): return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip + ctx.source.instance.runtime_properties['ssh_port'] = str(22) + ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip + else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): @@ -109,6 +112,8 @@ def _floatingip_operation(operation, vca_client, ctx): ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP] + del ctx.source.instance.runtime_properties['ssh_port'] + del ctx.source.instance.runtime_properties['ssh_public_ip'] return True From 9d9e374b0810bbd72c4e152fe6a5863b429adeb8 Mon Sep 17 00:00:00 2001 From: yoramw Date: Mon, 17 Aug 2015 11:38:47 +0300 Subject: [PATCH 078/228] handle versioning issue with update --- network_plugin/public_nat.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index e0277f6..29c073b 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -179,8 +179,21 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, function = gateway.add_nat_rule message = "Add" if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: - ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) - ctx.source.instance.runtime_properties['ssh_public_ip'] = public_ip + retries_update = 3 + update_pending = True + while retries_update > 0 and update_pending + retries_update = retries_update -1 + try: + ctx.source.instance.update() + ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) + ctx.source.instance.runtime_properties['ssh_public_ip'] = public_ip + update_pending = False + except rest_exceptions.CloudifyClientError as e: + if 'conflict' in str(e): + # cannot 'return' in contextmanager + ctx.logger.info("Conflict in updating backend, retrying") + else: + raise elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) From de22ac4fdbdf5d0662bd2f467b09a951bec5d94f Mon Sep 17 00:00:00 2001 From: yoramw Date: Mon, 17 Aug 2015 12:45:39 +0300 Subject: [PATCH 079/228] typo --- network_plugin/public_nat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 29c073b..c1cb23d 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -181,7 +181,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: retries_update = 3 update_pending = True - while retries_update > 0 and update_pending + while retries_update > 0 and update_pending: retries_update = retries_update -1 try: ctx.source.instance.update() From e5cedc137156ff249b68d9b916d19c1e6d88b124 Mon Sep 17 00:00:00 2001 From: yoramw Date: Mon, 17 Aug 2015 15:51:56 +0300 Subject: [PATCH 080/228] flush runtime properties --- network_plugin/public_nat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index c1cb23d..e91c138 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -184,9 +184,9 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, while retries_update > 0 and update_pending: retries_update = retries_update -1 try: - ctx.source.instance.update() ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) ctx.source.instance.runtime_properties['ssh_public_ip'] = public_ip + ctx.source.instance.update() update_pending = False except rest_exceptions.CloudifyClientError as e: if 'conflict' in str(e): From 4f50ce9e2465ed16603c6ac852f11f8d6517a730 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 10:21:21 +0300 Subject: [PATCH 081/228] fix python lines style warnings --- network_plugin/public_nat.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index e91c138..280ac06 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -23,6 +23,7 @@ del_ondemand_public_ip, utils, set_retry) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP +from cloudify_rest_client import exceptions as rest_exceptions PORT_REPLACEMENT = 'port_replacement' DEFAULT_SSH_PORT = '22' @@ -182,16 +183,19 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, retries_update = 3 update_pending = True while retries_update > 0 and update_pending: - retries_update = retries_update -1 + retries_update = retries_update - 1 try: - ctx.source.instance.runtime_properties['ssh_port'] = str(new_original_port) - ctx.source.instance.runtime_properties['ssh_public_ip'] = public_ip - ctx.source.instance.update() + ctx.source.instance.runtime_properties['ssh_port'] = str( + new_original_port) + ctx.source.instance.runtime_properties['ssh_public_ip'] =\ + public_ip + ctx.source.instance.update() update_pending = False except rest_exceptions.CloudifyClientError as e: if 'conflict' in str(e): # cannot 'return' in contextmanager - ctx.logger.info("Conflict in updating backend, retrying") + ctx.logger.info( + "Conflict in updating backend, retrying") else: raise elif operation == DELETE: From f695c8e390aca3e270569cbfa4b688fcdb062d62 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 10:47:59 +0300 Subject: [PATCH 082/228] Update plugin.yaml --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 91a8838..df5d53e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/yoramw/tosca-vcloud-plugin/archive/cfy3.2.1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: From 5dbfd24f253d64aa8de5eb5fa2dcdeaf574495e9 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 10:49:10 +0300 Subject: [PATCH 083/228] Update plugin.yaml prepare for 1.2.1m3 already... --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index df5d53e..4d5f08c 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m3.zip node_types: cloudify.vcloud.nodes.Server: From a12cc5e31be8db536448803afe6e9e66014fa066 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 10:55:20 +0300 Subject: [PATCH 084/228] Update floatingip.py Remove trailing whitespace --- network_plugin/floatingip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 1c7781c..0122589 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -101,7 +101,7 @@ def _floatingip_operation(operation, vca_client, ctx): if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip ctx.source.instance.runtime_properties['ssh_port'] = str(22) - ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip + ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip else: if is_ondemand(service_type): From e15130443c640a28014f9f4d309c6c58e34d86a7 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 16:35:53 +0300 Subject: [PATCH 085/228] Update plugin.yaml --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 4d5f08c..5b76fec 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m3.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/cfy3.2.1.zip node_types: cloudify.vcloud.nodes.Server: From 4832e68cb7947cc6eec16865fb290d2597c6689a Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 23:20:15 +0300 Subject: [PATCH 086/228] spaces and fake test --- network_plugin/floatingip.py | 2 +- .../test_mock_network_plugin_floatingip.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 0122589..e955dee 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -101,7 +101,7 @@ def _floatingip_operation(operation, vca_client, ctx): if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip ctx.source.instance.runtime_properties['ssh_port'] = str(22) - ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip + ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip else: if is_ondemand(service_type): diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index e8cf162..6c8cfdd 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -293,6 +293,11 @@ def test_floatingip_operation_delete(self): } fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '10.10.1.2' + + } + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + 'ssh_port': 22, + 'ssh_public_ip': '1.2.3.1' } fake_client._vdc_gateway.deallocate_public_ip = mock.MagicMock( return_value=self.generate_task( @@ -324,6 +329,10 @@ def test_floatingip_operation_delete(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '10.10.1.2' } + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + 'ssh_port': 22, + 'ssh_public_ip': '1.2.3.1' + } fake_client._vdc_gateway.deallocate_public_ip = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -353,6 +362,10 @@ def test_disconnect_floatingip(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '10.10.1.2' } + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + 'ssh_port': 22, + 'ssh_public_ip': '1.2.3.1' + } fake_client._vdc_gateway.deallocate_public_ip = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -384,6 +397,7 @@ def test_connect_floatingip(self): } } fake_ctx._target.instance.runtime_properties = {} + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1', '10.10.2.3' ]) @@ -420,6 +434,7 @@ def test_floatingip_operation_create(self): } } fake_ctx._target.instance.runtime_properties = {} + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1' ]) @@ -454,6 +469,7 @@ def test_floatingip_operation_create(self): } } fake_ctx._target.instance.runtime_properties = {} + fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1', '10.10.2.3' ]) From 53c31e7eb98fa499ba7b79b818585873632925a6 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 23:32:00 +0300 Subject: [PATCH 087/228] raise e --- network_plugin/public_nat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 280ac06..f919204 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -197,7 +197,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, ctx.logger.info( "Conflict in updating backend, retrying") else: - raise + raise e elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) From bf0076c0e19b1a83a113e90dfe39cc3d5518c062 Mon Sep 17 00:00:00 2001 From: yoramw Date: Tue, 18 Aug 2015 23:39:51 +0300 Subject: [PATCH 088/228] flake8 warnings --- .../test_mock_network_plugin_floatingip.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 6c8cfdd..d1925fd 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -295,7 +295,8 @@ def test_floatingip_operation_delete(self): network_plugin.PUBLIC_IP: '10.10.1.2' } - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp', 'ssh_port': 22, 'ssh_public_ip': '1.2.3.1' } @@ -329,7 +330,8 @@ def test_floatingip_operation_delete(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '10.10.1.2' } - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp', 'ssh_port': 22, 'ssh_public_ip': '1.2.3.1' } @@ -362,7 +364,8 @@ def test_disconnect_floatingip(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '10.10.1.2' } - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp', + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp', 'ssh_port': 22, 'ssh_public_ip': '1.2.3.1' } @@ -397,7 +400,9 @@ def test_connect_floatingip(self): } } fake_ctx._target.instance.runtime_properties = {} - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp' + } fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1', '10.10.2.3' ]) @@ -434,7 +439,9 @@ def test_floatingip_operation_create(self): } } fake_ctx._target.instance.runtime_properties = {} - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp' + } fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1' ]) @@ -469,7 +476,9 @@ def test_floatingip_operation_create(self): } } fake_ctx._target.instance.runtime_properties = {} - fake_ctx._source.instance.runtime_properties = {'vcloud_vapp_name': 'vapp'} + fake_ctx._source.instance.runtime_properties = { + 'vcloud_vapp_name': 'vapp' + } fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1', '10.10.2.3' ]) From d064a979537adbe89786943e7b04bab4e4c8a5c8 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 19 Aug 2015 11:30:51 +0400 Subject: [PATCH 089/228] Delete runtime properties --- network_plugin/public_nat.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index f919204..ec6aadd 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -27,6 +27,8 @@ PORT_REPLACEMENT = 'port_replacement' DEFAULT_SSH_PORT = '22' +SSH_PORT = 'ssh_port' +SSH_PUBLIC_IP = 'ssh_public_ip' @operation @@ -185,9 +187,9 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, while retries_update > 0 and update_pending: retries_update = retries_update - 1 try: - ctx.source.instance.runtime_properties['ssh_port'] = str( + ctx.source.instance.runtime_properties[SSH_PORT] = str( new_original_port) - ctx.source.instance.runtime_properties['ssh_public_ip'] =\ + ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] =\ public_ip ctx.source.instance.update() update_pending = False @@ -255,6 +257,10 @@ def _save_configuration(gateway, vca_client, operation, public_ip): del ctx.target.instance.runtime_properties[PUBLIC_IP] if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] + if SSH_PORT in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[SSH_PORT] + if SSH_PUBLIC_IP in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[SSH_PUBLIC_IP] return True From b5a075fd3e17469a80bc613e8020fb5caea8fe8a Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 19 Aug 2015 11:33:23 +0400 Subject: [PATCH 090/228] Update links --- manager_blueprint/vcloud-manager-blueprint.yaml | 2 +- plugin.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index 74ebe32..f16fd14 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m2/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml inputs: diff --git a/plugin.yaml b/plugin.yaml index 5b76fec..df5d53e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/cfy3.2.1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: From 8200dc15506d8c35ec504f4a5b486d381209d499 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 19 Aug 2015 11:38:44 +0300 Subject: [PATCH 091/228] update version to 1.2.1m3 --- examples/blueprint.yaml | 2 +- manager_blueprint/vcloud-manager-blueprint.yaml | 2 +- plugin.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index 55fa64e..e3e3227 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m2/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m3/plugin.yaml node_types: vcloud_configuration: diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index f16fd14..43a9558 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m3/plugin.yaml - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml inputs: diff --git a/plugin.yaml b/plugin.yaml index df5d53e..4d5f08c 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m3.zip node_types: cloudify.vcloud.nodes.Server: From 2b72ad995a39d678ba577ba03859dce70fd8f21b Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 21 Aug 2015 15:26:15 +0400 Subject: [PATCH 092/228] use vdc name instead org_name --- network_plugin/public_nat.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index ec6aadd..553968e 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -269,8 +269,8 @@ def _create_ip_range(vca_client, gateway): return ip range by avaible ranges from gateway and current network """ network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] - org_name = get_vcloud_config()['org'] - net = _get_network_ip_range(vca_client, org_name, network_name) + vdc_name = get_vcloud_config()['vdc'] + net = _get_network_ip_range(vca_client, vdc_name, network_name) gate = _get_gateway_ip_range(gateway, network_name) if not net: raise cfy_exc.NonRecoverableError( @@ -281,11 +281,11 @@ def _create_ip_range(vca_client, gateway): return "{} - {}".format(min(net), max(net)) -def _get_network_ip_range(vca_client, org_name, network_name): +def _get_network_ip_range(vca_client, vdc_name, network_name): """ return ips for network from network configuration ipscopes """ - networks = vca_client.get_networks(org_name) + networks = vca_client.get_networks(vdc_name) ip_scope = [net.Configuration.IpScopes.IpScope for net in networks if network_name == net.get_name()] addresses = [] From 8af948fba7be13fc8cc06be9573711713572c1af Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 24 Aug 2015 09:48:19 +0400 Subject: [PATCH 093/228] Fix rules check in public_nat.preconfigure --- network_plugin/public_nat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 553968e..a305044 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -35,7 +35,7 @@ @with_vca_client def net_connect_to_nat_preconfigure(vca_client, **kwargs): rules = ctx.target.node.properties['rules'] - if len(rules) != 1: + if not rules or len(rules) != 1: raise cfy_exc.NonRecoverableError( "Rules list must contains only one element") if _is_dnat(rules[0]['type']): From b6b3f9563bf06dcd7ef673812a92a47e7960b01c Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 27 Aug 2015 13:26:43 +0400 Subject: [PATCH 094/228] Delete unnecessary parameters --- network_plugin/floatingip.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index e955dee..f3184d9 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -100,9 +100,6 @@ def _floatingip_operation(operation, vca_client, ctx): return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip - ctx.source.instance.runtime_properties['ssh_port'] = str(22) - ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip - else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): @@ -111,9 +108,8 @@ def _floatingip_operation(operation, vca_client, ctx): gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) - del ctx.target.instance.runtime_properties[PUBLIC_IP] - del ctx.source.instance.runtime_properties['ssh_port'] - del ctx.source.instance.runtime_properties['ssh_public_ip'] + if PUBLIC_IP in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[PUBLIC_IP] return True From fcce32fa4e6332f0d3c274a46a8174b0a57acc0e Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 20 Aug 2015 10:50:31 +0400 Subject: [PATCH 095/228] Update versions for cloudyfy 3.3 use vdc name instead org_name update requirements, Add storage plugin Fix rules check in public_nat.preconfigure Update runtime properties Update link Remove extra runtime parameters Update PyYAML version Merge branch '1.3-build' --- examples/blueprint.yaml | 4 ++-- manager_blueprint/vcloud-manager-blueprint.yaml | 14 +++++++------- network_plugin/floatingip.py | 4 ---- network_plugin/public_nat.py | 10 +++++----- setup.py | 9 +++++---- storage_plugin/__init__.py | 14 ++++++++++++++ storage_plugin/storage.py | 14 ++++++++++++++ 7 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 storage_plugin/__init__.py create mode 100644 storage_plugin/storage.py diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index 55fa64e..ef9c801 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,8 +1,8 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m2/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3m4/plugin.yaml node_types: vcloud_configuration: diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index f16fd14..39ff2d9 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -1,10 +1,9 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml + - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml - + - http://www.getcloudify.org/spec/fabric-plugin/1.3m4/plugin.yaml inputs: vcloud_username: type: string @@ -480,11 +479,12 @@ node_templates: properties: cloudify_packages: agents: - ubuntu_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-ubuntu-agent_3.2.1-ga-b212_amd64.deb - centos_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-centos-final-agent_3.2.1-ga-b212_amd64.deb - windows_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-windows-agent_3.2.1-ga-b212_amd64.deb + ubuntu-trusty-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/Ubuntu-trusty-agent_3.3.0-m4-b274.tar.gz + centos-final-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/centos-Final-agent_3.3.0-m4-b274.tar.gz + ubuntu-precise-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/Ubuntu-precise-agent_3.3.0-m4-b274.tar.gz + windows_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/cloudify-windows-agent_3.3.0-m4-b274.exe docker: - docker_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.2.1/ga-RELEASE/cloudify-docker_3.2.1-ga-b212.tar + docker_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/cloudify-docker_3.3.0-m4-b274.tar cloudify: resources_prefix: { get_input: resources_prefix } diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index e955dee..f6830cd 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -100,8 +100,6 @@ def _floatingip_operation(operation, vca_client, ctx): return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip - ctx.source.instance.runtime_properties['ssh_port'] = str(22) - ctx.source.instance.runtime_properties['ssh_public_ip'] = external_ip else: if is_ondemand(service_type): @@ -112,8 +110,6 @@ def _floatingip_operation(operation, vca_client, ctx): ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP] - del ctx.source.instance.runtime_properties['ssh_port'] - del ctx.source.instance.runtime_properties['ssh_public_ip'] return True diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index ec6aadd..a305044 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -35,7 +35,7 @@ @with_vca_client def net_connect_to_nat_preconfigure(vca_client, **kwargs): rules = ctx.target.node.properties['rules'] - if len(rules) != 1: + if not rules or len(rules) != 1: raise cfy_exc.NonRecoverableError( "Rules list must contains only one element") if _is_dnat(rules[0]['type']): @@ -269,8 +269,8 @@ def _create_ip_range(vca_client, gateway): return ip range by avaible ranges from gateway and current network """ network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] - org_name = get_vcloud_config()['org'] - net = _get_network_ip_range(vca_client, org_name, network_name) + vdc_name = get_vcloud_config()['vdc'] + net = _get_network_ip_range(vca_client, vdc_name, network_name) gate = _get_gateway_ip_range(gateway, network_name) if not net: raise cfy_exc.NonRecoverableError( @@ -281,11 +281,11 @@ def _create_ip_range(vca_client, gateway): return "{} - {}".format(min(net), max(net)) -def _get_network_ip_range(vca_client, org_name, network_name): +def _get_network_ip_range(vca_client, vdc_name, network_name): """ return ips for network from network configuration ipscopes """ - networks = vca_client.get_networks(org_name) + networks = vca_client.get_networks(vdc_name) ip_scope = [net.Configuration.IpScopes.IpScope for net in networks if network_name == net.get_name()] addresses = [] diff --git a/setup.py b/setup.py index 1d30e90..12a5ebd 100644 --- a/setup.py +++ b/setup.py @@ -18,20 +18,21 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.2.1', + version='1.3m5', packages=[ 'vcloud_plugin_common', 'server_plugin', + 'storage_plugin', 'network_plugin' ], license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.2', - 'pyvcloud>=14rc6', + 'cloudify-plugins-common>=3.3a4', + 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', - 'PyYAML>=3.10', + 'PyYAML==3.10', 'pycrypto' ] ) diff --git a/storage_plugin/__init__.py b/storage_plugin/__init__.py new file mode 100644 index 0000000..a9dfcc4 --- /dev/null +++ b/storage_plugin/__init__.py @@ -0,0 +1,14 @@ +######### +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. diff --git a/storage_plugin/storage.py b/storage_plugin/storage.py new file mode 100644 index 0000000..a9dfcc4 --- /dev/null +++ b/storage_plugin/storage.py @@ -0,0 +1,14 @@ +######### +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. From d8c7970f3db3ed8b0cdba1fdacbd478a3f10e6d5 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 27 Aug 2015 13:44:00 +0400 Subject: [PATCH 096/228] Move volume node from server_plugin to storage_plugin --- plugin.yaml | 6 +++--- {server_plugin => storage_plugin}/volume.py | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename {server_plugin => storage_plugin}/volume.py (100%) diff --git a/plugin.yaml b/plugin.yaml index df5d53e..b33fa1b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -153,14 +153,14 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.server_plugin.volume.create_volume + implementation: vcloud.storage_plugin.volume.create_volume inputs: {} delete: - implementation: vcloud.server_plugin.volume.delete_volume + implementation: vcloud.storage_plugin.volume.delete_volume inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.server_plugin.volume.creation_validation + implementation: vcloud.storage_plugin.volume.creation_validation relationships: cloudify.vcloud.server_connected_to_floating_ip: diff --git a/server_plugin/volume.py b/storage_plugin/volume.py similarity index 100% rename from server_plugin/volume.py rename to storage_plugin/volume.py From 94aff95c92eeeac5e554f636c42dd914207af1dd Mon Sep 17 00:00:00 2001 From: Mykhailo Durnosvystov Date: Thu, 27 Aug 2015 16:08:05 +0300 Subject: [PATCH 097/228] update version to 1.2.1m4 --- examples/blueprint.yaml | 2 +- manager_blueprint/vcloud-manager-blueprint.yaml | 2 +- plugin.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index e3e3227..53bb244 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m3/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m4/plugin.yaml node_types: vcloud_configuration: diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index 43a9558..f335629 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m3/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m4/plugin.yaml - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml inputs: diff --git a/plugin.yaml b/plugin.yaml index 4d5f08c..9dd3549 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m3.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m4.zip node_types: cloudify.vcloud.nodes.Server: From 7630d1367f89f8bcc62eb81f99e3b2d4c3a32c96 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 28 Aug 2015 11:26:33 +0400 Subject: [PATCH 098/228] Move executions for network nodes from establish to postconfigure --- plugin.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index b33fa1b..5c3e3c7 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -167,7 +167,7 @@ relationships: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: - establish: + postconfigure: implementation: vcloud.network_plugin.floatingip.connect_floatingip inputs: {} unlink: @@ -183,7 +183,7 @@ relationships: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: - establish: + postconfigure: implementation: vcloud.network_plugin.security_group.create inputs: {} unlink: @@ -196,7 +196,7 @@ relationships: preconfigure: implementation: vcloud.network_plugin.public_nat.net_connect_to_nat_preconfigure inputs: {} - establish: + postconfigure: implementation: vcloud.network_plugin.public_nat.net_connect_to_nat inputs: {} unlink: @@ -206,7 +206,7 @@ relationships: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: - establish: + postconfigure: implementation: vcloud.network_plugin.public_nat.server_connect_to_nat inputs: {} unlink: From 5c311c5576ba6e145b116ab747dd9c3167f08663 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 28 Aug 2015 12:09:10 +0400 Subject: [PATCH 099/228] Install grub to new disk add sudo --- manager_blueprint/scripts/setup_grub.sh | 3 +++ manager_blueprint/vcloud-manager-blueprint.yaml | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 manager_blueprint/scripts/setup_grub.sh diff --git a/manager_blueprint/scripts/setup_grub.sh b/manager_blueprint/scripts/setup_grub.sh new file mode 100644 index 0000000..69fab0c --- /dev/null +++ b/manager_blueprint/scripts/setup_grub.sh @@ -0,0 +1,3 @@ +#!/bin/bash -e + +sudo grub-install ${device_name} diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index 39ff2d9..d478961 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -450,6 +450,17 @@ node_templates: key_filename: { get_input: manager_private_key_path } host_string: { get_attribute: [management_server_nat, public_ip] } port: { get_input: manager_server_ssh_port } + postconfigure: + implementation: fabric.fabric_plugin.tasks.run_script + inputs: + script_path: scripts/setup_grub.sh + device_name: { get_attribute: [TARGET, device_name] } + fabric_env: + user: { get_input: manager_server_user } + key_filename: { get_input: manager_private_key_path } + host_string: { get_attribute: [management_server_nat, public_ip] } + port: { get_input: manager_server_ssh_port } + - type: cloudify.relationships.file_system_contained_in_compute target: manager_server From c26380391d809fe7e2b2fd29be11dd9afa422b22 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 28 Aug 2015 12:26:48 +0400 Subject: [PATCH 100/228] Use vapp_name in message --- server_plugin/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index dbd02ab..b013aba 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -290,7 +290,7 @@ def configure(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Unable to find vAPP server " "by its name {0}.".format(vapp_name)) - ctx.logger.info("Using vAPP {0}".format(str(vapp))) + ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') From 83c88d6bc09c7d83f3936602ce34d57c9671ef68 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 31 Aug 2015 10:46:51 +0400 Subject: [PATCH 101/228] Fir relationship for attaching volume --- plugin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 5c3e3c7..945c044 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -217,10 +217,10 @@ relationships: target_interfaces: cloudify.interfaces.relationship_lifecycle: establish: - implementation: vcloud.server_plugin.volume.attach_volume + implementation: vcloud.storage_plugin.volume.attach_volume inputs: {} unlink: - implementation: vcloud.server_plugin.volume.detach_volume + implementation: vcloud.storage_plugin.volume.detach_volume inputs: {} cloudify.vcloud.server_connected_to_keypair: derived_from: cloudify.relationships.connected_to From 62cab2b3d84aaec038252070c7848d59702f2345 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 31 Aug 2015 13:44:26 +0400 Subject: [PATCH 102/228] Refactoring parameters saving. Add boot wait for attach volume --- network_plugin/__init__.py | 26 ++++++++++++++++++++++++-- network_plugin/floatingip.py | 10 ++++++++-- network_plugin/public_nat.py | 27 ++++----------------------- storage_plugin/volume.py | 20 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index ec3dcca..bd9a34c 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -4,10 +4,12 @@ from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType from vcloud_plugin_common import (wait_for_task, get_vcloud_config, is_subscription, error_response) - +from cloudify_rest_client import exceptions as rest_exceptions VCLOUD_VAPP_NAME = 'vcloud_vapp_name' PUBLIC_IP = 'public_ip' +SSH_PUBLIC_IP = 'ssh_public_ip' +SSH_PORT = 'ssh_port' NAT_ROUTED = 'natRouted' CREATE = 1 DELETE = 2 @@ -235,7 +237,8 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): wait_for_task(vca_client, task) else: raise cfy_exc.NonRecoverableError( - "Can't get public ip for ondemand service {0}".format(error_response(gateway))) + "Can't get public ip for ondemand service {0}". + format(error_response(gateway))) # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) @@ -291,3 +294,22 @@ def set_retry(ctx): return ctx.operation.retry( message='Waiting for gateway.', retry_after=GATEWAY_TIMEOUT) + + +def save_ssh_parameters(ctx, port, ip): + retries_update = 3 + update_pending = True + while retries_update > 0 and update_pending: + retries_update = retries_update - 1 + try: + ctx.source.instance.runtime_properties[SSH_PORT] = port + ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] = ip + ctx.source.instance.update() + update_pending = False + except rest_exceptions.CloudifyClientError as e: + if 'conflict' in str(e): + # cannot 'return' in contextmanager + ctx.logger.info( + "Conflict in updating backend, retrying") + else: + raise e diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index f6830cd..00fa4c9 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -7,6 +7,7 @@ CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, CREATE, DELETE, PUBLIC_IP, get_gateway, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, set_retry) @@ -100,7 +101,7 @@ def _floatingip_operation(operation, vca_client, ctx): return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip - + save_ssh_parameters(ctx, '22', external_ip) else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): @@ -109,7 +110,12 @@ def _floatingip_operation(operation, vca_client, ctx): gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) - del ctx.target.instance.runtime_properties[PUBLIC_IP] + if PUBLIC_IP in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[PUBLIC_IP] + if SSH_PUBLIC_IP in ctx.source.instance.runtime_properties: + del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] + if SSH_PORT in ctx.target.instance.runtime_properties: + del ctx.source.instance.runtime_properties[SSH_PORT] return True diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index a305044..57337b2 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -20,15 +20,13 @@ from network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, del_ondemand_public_ip, utils, set_retry) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP -from cloudify_rest_client import exceptions as rest_exceptions PORT_REPLACEMENT = 'port_replacement' DEFAULT_SSH_PORT = '22' -SSH_PORT = 'ssh_port' -SSH_PUBLIC_IP = 'ssh_public_ip' @operation @@ -182,24 +180,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, function = gateway.add_nat_rule message = "Add" if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: - retries_update = 3 - update_pending = True - while retries_update > 0 and update_pending: - retries_update = retries_update - 1 - try: - ctx.source.instance.runtime_properties[SSH_PORT] = str( - new_original_port) - ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] =\ - public_ip - ctx.source.instance.update() - update_pending = False - except rest_exceptions.CloudifyClientError as e: - if 'conflict' in str(e): - # cannot 'return' in contextmanager - ctx.logger.info( - "Conflict in updating backend, retrying") - else: - raise e + save_ssh_parameters(ctx, str(new_original_port), public_ip) elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) @@ -258,9 +239,9 @@ def _save_configuration(gateway, vca_client, operation, public_ip): if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] if SSH_PORT in ctx.target.instance.runtime_properties: - del ctx.target.instance.runtime_properties[SSH_PORT] + del ctx.source.instance.runtime_properties[SSH_PORT] if SSH_PUBLIC_IP in ctx.target.instance.runtime_properties: - del ctx.target.instance.runtime_properties[SSH_PUBLIC_IP] + del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] return True diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index 94b2a1b..7ffc3da 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -104,6 +104,7 @@ def attach_volume(vca_client, **kwargs): """ attach volume """ + _wait_for_boot() _volume_operation(vca_client, "ATTACH") @@ -157,3 +158,22 @@ def _volume_operation(vca_client, operation): else: raise cfy_exc.NonRecoverableError( "Unknown operation '{0}'".format(operation)) + + +def _wait_for_boot(): + from fabric import api as fabric_api + ip = ctx.target.instance.runtime_properties.get('ssh_public_ip') + if not ip: + ip = ctx.target.instance.runtime_properties['ip'] + ctx.logger.info("Usig ip '{0}'.".format(ip)) + for i in range(30): + ctx.logger.info("Wait for boot '{0}'.".format(i)) + try: + with fabric_api.settings(host_string=ip, warn_only=True, + abort_on_prompts=True): + fabric_api.run('ls') + except SystemExit: + return + except Exception: + pass + raise cfy_exc.NonRecoverableError("Can't wait for boot") From 2e9402ec1cd817c55e06cf85599d3b5bb56e3632 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 31 Aug 2015 15:35:24 +0400 Subject: [PATCH 103/228] Add function documentation Add wait timeout Add busy logger Add logger for sec group Wait gateway before change state Optimization --- network_plugin/__init__.py | 20 +++++++++++++++++++- network_plugin/floatingip.py | 2 +- network_plugin/network.py | 4 ++-- network_plugin/public_nat.py | 2 +- network_plugin/security_group.py | 3 ++- storage_plugin/volume.py | 13 ++++++++++--- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index bd9a34c..6f1874d 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -5,6 +5,8 @@ from vcloud_plugin_common import (wait_for_task, get_vcloud_config, is_subscription, error_response) from cloudify_rest_client import exceptions as rest_exceptions +import time + VCLOUD_VAPP_NAME = 'vcloud_vapp_name' PUBLIC_IP = 'public_ip' @@ -136,12 +138,13 @@ def get_vapp_name(runtime_properties): return vapp_name -def save_gateway_configuration(gateway, vca_client): +def save_gateway_configuration(gateway, vca_client, ctx): """ save gateway configuration, return everything successfully finished raise NonRecoverableError - can't get task description """ + wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.save_services_configuration() if task: wait_for_task(vca_client, task) @@ -232,6 +235,7 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): """ old_public_ips = set(gateway.get_public_ips()) ctx.logger.info("Try to allocate public IP") + wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.allocate_public_ip() if task: wait_for_task(vca_client, task) @@ -256,6 +260,7 @@ def del_ondemand_public_ip(vca_client, gateway, ip, ctx): try to deallocate public ip """ ctx.logger.info("Try to deallocate public IP {0}".format(ip)) + wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.deallocate_public_ip(ip) if task: wait_for_task(vca_client, task) @@ -313,3 +318,16 @@ def save_ssh_parameters(ctx, port, ip): "Conflict in updating backend, retrying") else: raise e + + +def wait_for_gateway(vca_client, gateway_name, ctx): + for i in range(10): + time.sleep(10) + gateway = get_gateway(vca_client, gateway_name) + ctx.logger.info("Gateway busy status '{0}. Try {1}'".format(gateway.is_busy(), i)) + if gateway.is_busy(): + continue + else: + return + raise cfy_exc.NonRecoverableError( + "Can't wait gateway {0}".format(gateway_name)) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 00fa4c9..9bf3916 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -96,7 +96,7 @@ def _floatingip_operation(operation, vca_client, ctx): nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) - success = save_gateway_configuration(gateway, vca_client) + success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False if operation == CREATE: diff --git a/network_plugin/network.py b/network_plugin/network.py index b463466..e2bbb56 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -201,14 +201,14 @@ def _dhcp_operation(vca_client, network_name, operation): max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) - if save_gateway_configuration(gateway, vca_client): + if save_gateway_configuration(gateway, vca_client, ctx): ctx.logger.info("DHCP rule successful created for network {0}" .format(network_name)) return True if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) - if save_gateway_configuration(gateway, vca_client): + if save_gateway_configuration(gateway, vca_client, ctx): ctx.logger.info("DHCP rule successful deleted for network {0}" .format(network_name)) return True diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 57337b2..da6d92b 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -219,7 +219,7 @@ def _save_configuration(gateway, vca_client, operation, public_ip): save/refresh nat rules on gateway """ ctx.logger.info("Save NAT configuration.") - success = save_gateway_configuration(gateway, vca_client) + success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False ctx.logger.info("NAT configuration has been saved.") diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index f765442..66c86b5 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -125,7 +125,8 @@ def _rule_operation(operation, vca_client): ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) - return save_gateway_configuration(gateway, vca_client) + ctx.logger.info("Saving security group configuration") + return save_gateway_configuration(gateway, vca_client, ctx) def _get_gateway_name(properties): diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index 7ffc3da..7930cee 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -19,7 +19,7 @@ get_vcloud_config, get_mandatory, error_response) from network_plugin import get_vapp_name - +import time @operation @with_vca_client @@ -161,17 +161,24 @@ def _volume_operation(vca_client, operation): def _wait_for_boot(): + """ + Whait for loading os. + This function just check if sshd is available. + After attaching disk system may be unbootable, + therefore user can do some manipulation for setup boot sequence. + """ from fabric import api as fabric_api ip = ctx.target.instance.runtime_properties.get('ssh_public_ip') if not ip: ip = ctx.target.instance.runtime_properties['ip'] - ctx.logger.info("Usig ip '{0}'.".format(ip)) + ctx.logger.info("Using ip '{0}'.".format(ip)) for i in range(30): ctx.logger.info("Wait for boot '{0}'.".format(i)) try: with fabric_api.settings(host_string=ip, warn_only=True, abort_on_prompts=True): - fabric_api.run('ls') + fabric_api.run('id') + time.sleep(5) except SystemExit: return except Exception: From d8e7e6288645c971822c3d18c3ac5c0304495cb0 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 1 Sep 2015 13:25:36 +0400 Subject: [PATCH 104/228] Try allocate IP several times --- network_plugin/__init__.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 6f1874d..6c55164 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -235,14 +235,19 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): """ old_public_ips = set(gateway.get_public_ips()) ctx.logger.info("Try to allocate public IP") - wait_for_gateway(vca_client, gateway.get_name(), ctx) - task = gateway.allocate_public_ip() - if task: - wait_for_task(vca_client, task) - else: - raise cfy_exc.NonRecoverableError( - "Can't get public ip for ondemand service {0}". - format(error_response(gateway))) + for i in range(5): + wait_for_gateway(vca_client, gateway.get_name(), ctx) + task = gateway.allocate_public_ip() + if task: + try: + wait_for_task(vca_client, task) + break + except cfy_exc.NonRecoverableError: + continue + else: + raise cfy_exc.NonRecoverableError( + "Can't get public ip for ondemand service {0}". + format(error_response(gateway))) # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) From cd222b638844845b5c267c029b9fe81d1a040771 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 1 Sep 2015 14:46:40 +0400 Subject: [PATCH 105/228] Add more log messages --- network_plugin/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 6c55164..8c5ebc1 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -6,6 +6,7 @@ is_subscription, error_response) from cloudify_rest_client import exceptions as rest_exceptions import time +import random VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -148,10 +149,12 @@ def save_gateway_configuration(gateway, vca_client, ctx): task = gateway.save_services_configuration() if task: wait_for_task(vca_client, task) + ctx.logger.info("Gateway parameters has been saved.") return True else: error = taskType.parseString(gateway.response.content, True) if BUSY_MESSAGE in error.message: + ctx.logger.info("Gateway is busy.") return False else: raise cfy_exc.NonRecoverableError(error.message) @@ -234,8 +237,8 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): try to allocate new public ip for ondemand service """ old_public_ips = set(gateway.get_public_ips()) - ctx.logger.info("Try to allocate public IP") for i in range(5): + ctx.logger.info("Try to allocate public IP") wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.allocate_public_ip() if task: @@ -326,13 +329,12 @@ def save_ssh_parameters(ctx, port, ip): def wait_for_gateway(vca_client, gateway_name, ctx): + time.sleep(random.randint(1, 20)) for i in range(10): - time.sleep(10) gateway = get_gateway(vca_client, gateway_name) - ctx.logger.info("Gateway busy status '{0}. Try {1}'".format(gateway.is_busy(), i)) - if gateway.is_busy(): - continue - else: + if not gateway.is_busy(): return + ctx.logger.info("Check {0}. Gateway is busy.".format(i)) + time.sleep(10) raise cfy_exc.NonRecoverableError( "Can't wait gateway {0}".format(gateway_name)) From 10536a9997c4fed91c8c260994cf3c6ef4da1a91 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 1 Sep 2015 15:09:08 +0400 Subject: [PATCH 106/228] Add comment --- network_plugin/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 8c5ebc1..f009739 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -329,6 +329,8 @@ def save_ssh_parameters(ctx, port, ip): def wait_for_gateway(vca_client, gateway_name, ctx): + # protection against simultaneous reading from several tasks + # status of the gateway time.sleep(random.randint(1, 20)) for i in range(10): gateway = get_gateway(vca_client, gateway_name) From f5c3715d3834ca16aecbee4ec61a63b850d03324 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 3 Sep 2015 17:03:53 +0300 Subject: [PATCH 107/228] SCOR-193: explicit version of plugin in setup, fix tests --- manager_blueprint/vcloud-manager-blueprint.yaml | 2 +- network_plugin/floatingip.py | 4 ++-- plugin.yaml | 2 +- setup.py | 2 +- tests/unittests/test_mock_network_plugin_public_nat.py | 3 ++- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index f335629..d7d6623 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -2,7 +2,7 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - http://www.getcloudify.org/spec/cloudify/3.2.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m4/plugin.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.2.1m5/plugin.yaml - http://www.getcloudify.org/spec/fabric-plugin/1.2.1/plugin.yaml inputs: diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index f3184d9..78ed618 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -108,8 +108,8 @@ def _floatingip_operation(operation, vca_client, ctx): gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) - if PUBLIC_IP in ctx.target.instance.runtime_properties: - del ctx.target.instance.runtime_properties[PUBLIC_IP] + if PUBLIC_IP in ctx.target.instance.runtime_properties: + del ctx.target.instance.runtime_properties[PUBLIC_IP] return True diff --git a/plugin.yaml b/plugin.yaml index 9dd3549..94ade3b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m4.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m5.zip node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index 1d30e90..d77dd67 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.2.1', + version='1.2.1m5', packages=[ 'vcloud_plugin_common', 'server_plugin', diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index b483fc9..1534e8f 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -304,7 +304,8 @@ def test_create_ip_range(self): } fake_ctx._source.node.properties = { 'vcloud_config': { - 'org': 'some_org' + 'org': 'some_org', + 'vdc': 'some_org' } } fake_ctx._target.instance.runtime_properties = {} From 0a33298cc8acb0d4aeaf151bdb602c9e331338a7 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 28 Aug 2015 08:55:42 +0400 Subject: [PATCH 108/228] CFY-3457 Add create-vdc and delete-vdc options to vcloud plugin --- plugin.yaml | 25 +++++ server_plugin/vdc.py | 97 +++++++++++++++++++ tests/integration/test_server_plugin.py | 42 +++++++- .../test_mock_network_plugin_public_nat.py | 2 +- .../test_mock_server_plugin_volume.py | 4 +- 5 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 server_plugin/vdc.py diff --git a/plugin.yaml b/plugin.yaml index b33fa1b..f500680 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -162,6 +162,29 @@ node_types: creation: implementation: vcloud.storage_plugin.volume.creation_validation + cloudify.vcloud.nodes.VDC: + derived_from: cloudify.nodes.Root + properties: + name: + default: '' + use_external_resource: + default: false + resource_id: + default: '' + vcloud_config: + default: {} + interfaces: + cloudify.interfaces.lifecycle: + create: + implementation: vcloud.server_plugin.vdc.create + inputs: {} + delete: + implementation: vcloud.server_plugin.vdc.delete + inputs: {} + cloudify.interfaces.validation: + creation: + implementation: vcloud.server_plugin.vdc.creation_validation + relationships: cloudify.vcloud.server_connected_to_floating_ip: derived_from: cloudify.relationships.connected_to @@ -232,6 +255,8 @@ relationships: unlink: implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair inputs: {} + cloudify.vcloud.server_connected_to_vdc: + derived_from: cloudify.relationships.connected_to workflows: scoreinstall: vcloud.vcloud_plugin_common.workflows.install diff --git a/server_plugin/vdc.py b/server_plugin/vdc.py new file mode 100644 index 0000000..a77853c --- /dev/null +++ b/server_plugin/vdc.py @@ -0,0 +1,97 @@ + +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. + +from cloudify import ctx +from cloudify.decorators import operation +from cloudify import exceptions as cfy_exc + +from vcloud_plugin_common import (get_vcloud_config, + wait_for_task, + with_vca_client, + is_subscription, + error_response) + +VDC_NAME = 'vdc_name' +RESOURCE_ID = 'resource_id' +USE_EXTERNAL_RESOURCE = 'use_external_resource' + + +@operation +@with_vca_client +def creation_validation(vca_client, **kwargs): + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + if not ctx.node.properties.get(RESOURCE_ID): + raise cfy_exc.NonRecoverableError( + "resource_id server properties must be specified") + res_id = ctx.node.properties[RESOURCE_ID] + vdc = vca_client.get_vdc(res_id) + if not vdc: + raise cfy_exc.NonRecoverableError( + "Unable to find external VDC {0}." + .format(res_id)) + else: + vdc_name = ctx.node.properties.get('name') + if not vdc_name: + raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") + vdc = vca_client.get_vdc(vdc_name) + if vdc: + raise cfy_exc.NonRecoverableError( + "VDC '{0}' already exists." + .format(res_id)) + + +@operation +@with_vca_client +def create(vca_client, **kwargs): + config = get_vcloud_config() + if is_subscription(config['service_type']): + raise cfy_exc.NonRecoverableError( + "Unable create VDC on subscription service.") + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + res_id = ctx.node.properties[RESOURCE_ID] + ctx.instance.runtime_properties[VDC_NAME] = res_id + vdc = vca_client.get_vdc(res_id) + if not vdc: + raise cfy_exc.NonRecoverableError( + "Unable to find external VDC {0}." + .format(res_id)) + ctx.logger.info( + "External resource {0} has been used".format(res_id)) + else: + vdc_name = ctx.node.properties.get('name') + if not vdc_name: + raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") + task = vca_client.create_vdc(vdc_name) + if not task: + raise cfy_exc.NonRecoverableError("Could not create VDC: {0}" + .format(error_response(vca_client))) + wait_for_task(vca_client, task) + + +@operation +@with_vca_client +def delete(vca_client, **kwargs): + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + ctx.logger.info('Not deleting VDC since an external VDC is ' + 'being used') + else: + vdc_name = ctx.node.properties.get('name') + status, task = vca_client.delete_vdc(vdc_name) + if not status: + raise cfy_exc.NonRecoverableError("Could not delete VDC: {0}" + .format(error_response(vca_client))) + wait_for_task(vca_client, task) + if VDC_NAME in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[VDC_NAME] diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index d8d1dff..aaa83d6 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -23,10 +23,14 @@ from server_plugin import server from server_plugin import volume +from server_plugin import vdc from tests.integration import TestCase from cloudify.mocks import MockCloudifyContext from server_plugin.server import VCLOUD_VAPP_NAME +from vcloud_plugin_common import VcloudAirClient + + RANDOM_PREFIX_LENGTH = 5 @@ -364,4 +368,40 @@ def links_count(): volume.attach_volume() self.assertEqual(links_before + 1, links_count()) volume.detach_volume() - self.assertEqual(links_before, links_count()) + + +class VdcTestCase(TestCase): + def setUp(self): + super(VdcTestCase, self).setUp() + self.vdc_test_dict = self.test_config['vdc'] + name = 'vdc' + self.properties = { + 'name': self.vdc_test_dict['name'], + 'use_external_resource': False, + 'resource_id': self.vdc_test_dict['name_exists'], + 'vcloud_config': self.vcloud_config + } + self.nodectx = cfy_mocks.MockCloudifyContext( + node_id=name, + node_name=name, + properties=self.properties + ) + self.ctx = self.nodectx + ctx_patch1 = mock.patch('server_plugin.vdc.ctx', self.nodectx) + ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.nodectx) + ctx_patch1.start() + ctx_patch2.start() + self.addCleanup(ctx_patch1.stop) + self.addCleanup(ctx_patch2.stop) + + def test_vdc_create_delete(self): + name = self.properties['name'] + self.assertFalse(name in self._get_vdc_names()) + vdc.create() + self.assertTrue(name in self._get_vdc_names()) + vdc.delete() + self.assertFalse(name in self._get_vdc_names()) + + def _get_vdc_names(self): + vca_client = VcloudAirClient().get(config=self.vcloud_config) + return vca_client.get_vdc_names() diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index b483fc9..856e5a9 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -304,7 +304,7 @@ def test_create_ip_range(self): } fake_ctx._source.node.properties = { 'vcloud_config': { - 'org': 'some_org' + 'vdc': 'some_org' } } fake_ctx._target.instance.runtime_properties = {} diff --git a/tests/unittests/test_mock_server_plugin_volume.py b/tests/unittests/test_mock_server_plugin_volume.py index 930c76d..8ea356f 100644 --- a/tests/unittests/test_mock_server_plugin_volume.py +++ b/tests/unittests/test_mock_server_plugin_volume.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc from cloudify import mocks as cfy_mocks -from server_plugin import volume +from storage_plugin import volume import vcloud_plugin_common from tests.unittests import test_mock_base import network_plugin @@ -289,7 +289,7 @@ def _run_volume_operation(fake_ctx, fake_client, operation): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'server_plugin.volume.ctx', fake_ctx + 'storage_plugin.volume.ctx', fake_ctx ): volume._volume_operation(fake_client, operation) # use external resource, no disks From 7cfc5de3838d0435d3d1ba52bbdc8b0a4264f4db Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 8 Sep 2015 16:04:22 +0400 Subject: [PATCH 109/228] CFY-3539 Protection against simultaneous access to the gateway --- network_plugin/__init__.py | 42 ++++++++++-- network_plugin/floatingip.py | 6 +- network_plugin/public_nat.py | 6 +- network_plugin/security_group.py | 10 +-- tests/unittests/test_mock_network_plugin.py | 25 ++++---- .../test_mock_network_plugin_floatingip.py | 14 ++++ .../test_mock_network_plugin_public_nat.py | 64 ++++++++++++++++++- ...test_mock_network_plugin_security_group.py | 22 +++++++ .../test_mock_server_plugin_volume.py | 13 ++-- vcloud_plugin_common/__init__.py | 7 +- 10 files changed, 172 insertions(+), 37 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index f009739..d939a9f 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -6,7 +6,7 @@ is_subscription, error_response) from cloudify_rest_client import exceptions as rest_exceptions import time -import random +from functools import wraps VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -14,6 +14,7 @@ SSH_PUBLIC_IP = 'ssh_public_ip' SSH_PORT = 'ssh_port' NAT_ROUTED = 'natRouted' +GATEWAY_LOCK = 'gateway_lock' CREATE = 1 DELETE = 2 @@ -145,7 +146,6 @@ def save_gateway_configuration(gateway, vca_client, ctx): return everything successfully finished raise NonRecoverableError - can't get task description """ - wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.save_services_configuration() if task: wait_for_task(vca_client, task) @@ -237,6 +237,13 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): try to allocate new public ip for ondemand service """ old_public_ips = set(gateway.get_public_ips()) + allocated_ips = set([address.external + for address in collectAssignedIps(gateway)]) + available_ips = old_public_ips - allocated_ips + if available_ips: + new_ip = list(available_ips)[0] + ctx.logger.info("Public IP {0} was reused.".format(new_ip)) + return new_ip for i in range(5): ctx.logger.info("Try to allocate public IP") wait_for_gateway(vca_client, gateway.get_name(), ctx) @@ -329,9 +336,6 @@ def save_ssh_parameters(ctx, port, ip): def wait_for_gateway(vca_client, gateway_name, ctx): - # protection against simultaneous reading from several tasks - # status of the gateway - time.sleep(random.randint(1, 20)) for i in range(10): gateway = get_gateway(vca_client, gateway_name) if not gateway.is_busy(): @@ -340,3 +344,31 @@ def wait_for_gateway(vca_client, gateway_name, ctx): time.sleep(10) raise cfy_exc.NonRecoverableError( "Can't wait gateway {0}".format(gateway_name)) + + +def lock_gateway(f): + def update_parameters(ctx, value): + ctx.source.instance.runtime_properties[GATEWAY_LOCK] = value + ctx.source.instance.update() + + @wraps(f) + def wrapper(*args, **kw): + ctx = kw['ctx'] + # Reset for getting last version of runtime_properties + ctx.source.instance._node_instance = None + if ctx.source.instance.runtime_properties.get(GATEWAY_LOCK): + ctx.logger.info("Gateway locked.") + return set_retry(ctx) + ctx.logger.info("Lock gateway.") + update_parameters(ctx, True) + vca_client = kw['vca_client'] + gateway_name = get_vcloud_config()['edge_gateway'] + wait_for_gateway(vca_client, gateway_name, ctx) + try: + result = f(*args, **kw) + finally: + ctx.logger.info("Unlock gateway.") + ctx.source.instance._node_instance = None + update_parameters(ctx, False) + return result + return wrapper diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 9bf3916..3a6e29e 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -9,11 +9,12 @@ CREATE, DELETE, PUBLIC_IP, get_gateway, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, - set_retry) + set_retry, lock_gateway) @operation @with_vca_client +@lock_gateway def connect_floatingip(vca_client, **kwargs): """ create new floating ip for node @@ -24,6 +25,7 @@ def connect_floatingip(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def disconnect_floatingip(vca_client, **kwargs): """ release floating ip @@ -67,8 +69,6 @@ def _floatingip_operation(operation, vca_client, ctx): service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) - if gateway.is_busy(): - return False internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index da6d92b..6a40adf 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -21,7 +21,7 @@ get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry) + del_ondemand_public_ip, utils, set_retry, lock_gateway) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP @@ -44,6 +44,7 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def net_connect_to_nat(vca_client, **kwargs): """ create nat rule for current node @@ -57,6 +58,7 @@ def net_connect_to_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def net_disconnect_from_nat(vca_client, **kwargs): """ drop nat rule for current node @@ -70,6 +72,7 @@ def net_disconnect_from_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def server_connect_to_nat(vca_client, **kwargs): """ create nat rules for server @@ -80,6 +83,7 @@ def server_connect_to_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def server_disconnect_from_nat(vca_client, **kwargs): """ drop nat rules for server diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index 66c86b5..8010cca 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -4,7 +4,7 @@ from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) from network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, - get_gateway, utils, set_retry) + get_gateway, utils, set_retry, lock_gateway) CREATE_RULE = 1 @@ -16,6 +16,7 @@ @operation @with_vca_client +@lock_gateway def create(vca_client, **kwargs): """ create firewall rules for node @@ -26,6 +27,7 @@ def create(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def delete(vca_client, **kwargs): """ drop firewall rules for node @@ -91,10 +93,8 @@ def _rule_operation(operation, vca_client): """ create/delete firewall rules in gateway for current node """ - gateway = get_gateway( - vca_client, _get_gateway_name(ctx.target.node.properties)) - if gateway.is_busy(): - return False + gateway_name = _get_gateway_name(ctx.target.node.properties) + gateway = get_gateway(vca_client, gateway_name) for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 1be23b4..e0894d3 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -161,10 +161,10 @@ def test_del_ondemand_public_ip(self): fake_ctx = self.generate_node_context() # can't deallocate ip gateway.deallocate_public_ip = mock.MagicMock(return_value=None) - with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.del_ondemand_public_ip( - fake_client, gateway, '127.0.0.1', fake_ctx - ) + with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): + with self.assertRaises(cfy_exc.NonRecoverableError): + network_plugin.del_ondemand_public_ip( + fake_client, gateway, '127.0.0.1', fake_ctx) gateway.deallocate_public_ip.assert_called_with('127.0.0.1') # successfully dropped public ip gateway.deallocate_public_ip = mock.MagicMock( @@ -173,8 +173,9 @@ def test_del_ondemand_public_ip(self): ) ) with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): - network_plugin.del_ondemand_public_ip( - fake_client, gateway, '127.0.0.1', fake_ctx) + with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): + network_plugin.del_ondemand_public_ip( + fake_client, gateway, '127.0.0.1', fake_ctx) def test_save_gateway_configuration(self): """ @@ -187,10 +188,10 @@ def test_save_gateway_configuration(self): self.set_services_conf_result( gateway, None ) + fake_ctx = self.generate_node_context() with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_client - ) + gateway, fake_client, fake_ctx) # error in status self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_ERROR @@ -198,7 +199,7 @@ def test_save_gateway_configuration(self): with self.assertRaises(cfy_exc.NonRecoverableError): with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): network_plugin.save_gateway_configuration( - gateway, fake_client) + gateway, fake_client, fake_ctx) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -206,7 +207,7 @@ def test_save_gateway_configuration(self): with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): self.assertTrue( network_plugin.save_gateway_configuration( - gateway, fake_client)) + gateway, fake_client, fake_ctx)) # server busy self.set_services_conf_result( gateway, None @@ -214,9 +215,7 @@ def test_save_gateway_configuration(self): self.set_gateway_busy(gateway) self.assertFalse( network_plugin.save_gateway_configuration( - gateway, fake_client - ) - ) + gateway, fake_client, fake_ctx)) def test_is_network_routed(self): """ diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index d1925fd..538c9c6 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -369,6 +369,14 @@ def test_disconnect_floatingip(self): 'ssh_port': 22, 'ssh_public_ip': '1.2.3.1' } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_client._vdc_gateway.deallocate_public_ip = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -397,6 +405,12 @@ def test_connect_floatingip(self): 'floatingip': { 'edge_gateway': 'gateway', network_plugin.PUBLIC_IP: '10.10.2.3' + }} + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' } } fake_ctx._target.instance.runtime_properties = {} diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 856e5a9..307dd6e 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -366,7 +366,9 @@ def _context_for_delete(service_type): } properties = { 'vcloud_config': { - 'org': 'some_org', + 'edge_gateway': 'gateway', + 'vdc': 'vdc', + 'org': 'some_org' } } if service_type: @@ -480,6 +482,7 @@ def _ip_exist_in_runtime(fake_ctx): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): + # import pdb;pdb.set_trace() public_nat._save_configuration( gateway, fake_client, network_plugin.DELETE, "1.2.3.4" ) @@ -917,6 +920,17 @@ def test_server_disconnect_from_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -931,6 +945,17 @@ def test_server_connect_to_nat(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '192.168.1.1' } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } fake_ctx._target.node.properties = { 'nat': { 'edge_gateway': 'gateway' @@ -939,6 +964,7 @@ def test_server_connect_to_nat(self): 'type': 'DNAT' }] } + fake_client._vdc_gateway.get_public_ips = mock.MagicMock( return_value=['10.18.1.1'] ) @@ -957,6 +983,18 @@ def test_net_disconnect_from_nat(self): fake_ctx._target.node.properties = { 'use_external_resource': True } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -972,6 +1010,14 @@ def test_net_disconnect_from_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -988,6 +1034,14 @@ def test_net_connect_to_nat(self): fake_ctx._target.node.properties = { 'use_external_resource': True } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -1003,6 +1057,14 @@ def test_net_connect_to_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1' ]) diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 54a4a5a..ad55e63 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -337,6 +337,17 @@ def test_create(self): fake_ctx._target.node.properties = { 'rules': [] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) @@ -353,6 +364,17 @@ def test_delete(self): fake_ctx._target.node.properties = { 'rules': [] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) diff --git a/tests/unittests/test_mock_server_plugin_volume.py b/tests/unittests/test_mock_server_plugin_volume.py index 8ea356f..5bf11e4 100644 --- a/tests/unittests/test_mock_server_plugin_volume.py +++ b/tests/unittests/test_mock_server_plugin_volume.py @@ -371,7 +371,8 @@ def _gen_volume_context_and_client(self): 'resource_id': 'some' } fake_ctx._target.instance.runtime_properties = { - network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME + network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME, + 'ip': "1.2.3.4" } return fake_ctx, fake_client @@ -380,11 +381,11 @@ def test_attach_volume(self): use external resource, try to attach but no disks """ fake_ctx, fake_client = self._gen_volume_context_and_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.attach_volume(ctx=fake_ctx) + with mock.patch('vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client)): + with mock.patch( + 'storage_plugin.volume._wait_for_boot', mock.MagicMock()): + volume.attach_volume(ctx=fake_ctx) def test_detach_volume(self): """ diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 6aa7bc1..9121bbd 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -26,9 +26,10 @@ from cloudify import context from cloudify import exceptions as cfy_exc -TASK_RECHECK_TIMEOUT = 3 -RELOGIN_TIMEOUT = 3 -LOGIN_RETRY_NUM = 5 + +TASK_RECHECK_TIMEOUT = 5 +RELOGIN_TIMEOUT = 5 +LOGIN_RETRY_NUM = 15 TASK_STATUS_SUCCESS = 'success' TASK_STATUS_ERROR = 'error' From c0feb2017cbd60d1f929d309575fccc2a68b8e06 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 10 Sep 2015 15:34:52 +0300 Subject: [PATCH 110/228] CFY-2841: Backport move volume class to storage plugin from master branch --- plugin.yaml | 10 +- setup.py | 13 +- storage_plugin/__init__.py | 1 + {server_plugin => storage_plugin}/volume.py | 12 +- .../test_mock_storage_plugin_volume.py | 401 ++++++++++++++++++ tox.ini | 6 +- 6 files changed, 421 insertions(+), 22 deletions(-) create mode 100644 storage_plugin/__init__.py rename {server_plugin => storage_plugin}/volume.py (96%) create mode 100644 tests/unittests/test_mock_storage_plugin_volume.py diff --git a/plugin.yaml b/plugin.yaml index 94ade3b..9299d12 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -153,14 +153,14 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.server_plugin.volume.create_volume + implementation: vcloud.storage_plugin.volume.create_volume inputs: {} delete: - implementation: vcloud.server_plugin.volume.delete_volume + implementation: vcloud.storage_plugin.volume.delete_volume inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.server_plugin.volume.creation_validation + implementation: vcloud.storage_plugin.volume.creation_validation relationships: cloudify.vcloud.server_connected_to_floating_ip: @@ -217,10 +217,10 @@ relationships: target_interfaces: cloudify.interfaces.relationship_lifecycle: establish: - implementation: vcloud.server_plugin.volume.attach_volume + implementation: vcloud.storage_plugin.volume.attach_volume inputs: {} unlink: - implementation: vcloud.server_plugin.volume.detach_volume + implementation: vcloud.storage_plugin.volume.detach_volume inputs: {} cloudify.vcloud.server_connected_to_keypair: derived_from: cloudify.relationships.connected_to diff --git a/setup.py b/setup.py index d77dd67..e8947be 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ -######### -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -9,10 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. - +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from setuptools import setup setup( @@ -22,13 +20,14 @@ packages=[ 'vcloud_plugin_common', 'server_plugin', + 'storage_plugin', 'network_plugin' ], license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.2', - 'pyvcloud>=14rc6', + 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', 'PyYAML>=3.10', diff --git a/storage_plugin/__init__.py b/storage_plugin/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/storage_plugin/__init__.py @@ -0,0 +1 @@ + diff --git a/server_plugin/volume.py b/storage_plugin/volume.py similarity index 96% rename from server_plugin/volume.py rename to storage_plugin/volume.py index 94b2a1b..b9a6a50 100644 --- a/server_plugin/volume.py +++ b/storage_plugin/volume.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify import exceptions as cfy_exc @@ -19,7 +19,7 @@ get_vcloud_config, get_mandatory, error_response) from network_plugin import get_vapp_name - +import time @operation @with_vca_client @@ -101,9 +101,7 @@ def creation_validation(vca_client, **kwargs): @operation @with_vca_client def attach_volume(vca_client, **kwargs): - """ - attach volume - """ + """attach volume""" _volume_operation(vca_client, "ATTACH") diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py new file mode 100644 index 0000000..e15824c --- /dev/null +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -0,0 +1,401 @@ +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock +import unittest + +from cloudify import exceptions as cfy_exc +from cloudify import mocks as cfy_mocks +from storage_plugin import volume +import vcloud_plugin_common +from tests.unittests import test_mock_base +import network_plugin + + +class StoaragePluginVolumeMockTestCase(test_mock_base.TestBase): + + # vapp name used for tests + VAPPNAME = "some_other" + + def test_creation_validation_external_resource(self): + fake_client = self.generate_client() + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': True, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + # use external without resorse_id + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.creation_validation(ctx=fake_ctx) + fake_client.get_disks.assert_called_with('vdc_name') + # with resource id, but without disks(no disks for this client) + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': True, + 'resource_id': 'some', + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.creation_validation(ctx=fake_ctx) + # good case for external resource + fake_client.get_disks = mock.MagicMock(return_value=[ + [ + self.generate_fake_client_disk('some'), + self.generate_fake_vms_disk('some') + ] + ]) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.creation_validation(ctx=fake_ctx) + + def test_creation_validation_internal(self): + fake_client = self.generate_client() + # internal resource without volume + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.creation_validation(ctx=fake_ctx) + fake_client.get_disks.assert_called_with('vdc_name') + # internal resourse wit volume and name, + # but already exist such volume + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'volume': { + 'name': 'some' + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + fake_client.get_disks = mock.MagicMock(return_value=[ + [ + self.generate_fake_client_disk('some'), + self.generate_fake_vms_disk('some') + ] + ]) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.creation_validation(ctx=fake_ctx) + # correct name but without size + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'volume': { + 'name': 'some-other' + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.creation_validation(ctx=fake_ctx) + # good case + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'volume': { + 'name': 'some-other', + 'size': 11 + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.creation_validation(ctx=fake_ctx) + + def test_delete_volume(self): + fake_client = self.generate_client() + # external resource + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': True, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.delete_volume(ctx=fake_ctx) + # cant't add disk + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'volume': { + 'name': 'some-other', + 'size': 11 + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.delete_volume(ctx=fake_ctx) + fake_client.delete_disk.assert_called_with( + 'vdc_name', 'some-other' + ) + # positive case + fake_client.delete_disk = mock.MagicMock( + return_value=( + True, self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.delete_volume(ctx=fake_ctx) + + def test_create_volume(self): + fake_client = self.generate_client() + # external resource + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': True, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.create_volume(ctx=fake_ctx) + # fail on create volume + fake_ctx = cfy_mocks.MockCloudifyContext( + node_id='test', + node_name='test', + properties={ + 'use_external_resource': False, + 'volume': { + 'name': 'some-other', + 'size': 11 + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + volume.create_volume(ctx=fake_ctx) + fake_client.add_disk.assert_called_with( + 'vdc_name', 'some-other', 11534336 + ) + # positive case + disk = mock.Mock() + disk.get_Tasks = mock.MagicMock( + return_value=[self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + )] + ) + fake_client.add_disk = mock.MagicMock( + return_value=(True, disk) + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.create_volume(ctx=fake_ctx) + + def test_volume_operation(self): + fake_ctx, fake_client = self._gen_volume_context_and_client() + + def _run_volume_operation(fake_ctx, fake_client, operation): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + with mock.patch( + 'storage_plugin.volume.ctx', fake_ctx + ): + volume._volume_operation(fake_client, operation) + # use external resource, no disks + _run_volume_operation(fake_ctx, fake_client, 'ATTACH') + fake_client.get_diskRefs.assert_called_with( + fake_client._app_vdc + ) + # disk exist, can't attach + disk_ref = self.generate_fake_client_disk_ref('some') + fake_client.get_diskRefs = mock.MagicMock(return_value=[ + disk_ref + ]) + with self.assertRaises(cfy_exc.NonRecoverableError): + _run_volume_operation(fake_ctx, fake_client, 'ATTACH') + fake_client._vapp.attach_disk_to_vm.assert_called_with( + self.VAPPNAME, disk_ref + ) + # disk exist, can't detach + with self.assertRaises(cfy_exc.NonRecoverableError): + _run_volume_operation(fake_ctx, fake_client, 'DETACH') + fake_client._vapp.detach_disk_from_vm.assert_called_with( + self.VAPPNAME, disk_ref + ) + # wrong operation + with self.assertRaises(cfy_exc.NonRecoverableError): + _run_volume_operation(fake_ctx, fake_client, 'Wrong') + # disk exist, can attach + fake_client._vapp.attach_disk_to_vm = mock.MagicMock( + return_value=self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) + _run_volume_operation(fake_ctx, fake_client, 'ATTACH') + # disk exist, can detach + fake_client._vapp.detach_disk_from_vm = mock.MagicMock( + return_value=self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) + _run_volume_operation(fake_ctx, fake_client, 'DETACH') + # disk exist, use internal resource + fake_ctx._target.node.properties = { + 'volume': { + 'name': 'some' + }, + 'use_external_resource': False + } + _run_volume_operation(fake_ctx, fake_client, 'DETACH') + fake_client._vapp.detach_disk_from_vm.assert_called_with( + 'some_other', disk_ref + ) + # disk exist, use external resource + fake_ctx._target.node.properties = { + 'volume': { + 'name': 'some' + }, + 'use_external_resource': False + } + fake_ctx._source.node.properties.update( + {'use_external_resource': True}) + _run_volume_operation(fake_ctx, fake_client, 'DETACH') + fake_client._vapp.detach_disk_from_vm.assert_called_with( + 'some_other', disk_ref + ) + + def _gen_volume_context_and_client(self): + fake_client = self.generate_client() + fake_ctx = self.generate_relation_context() + fake_ctx._target.node.properties = { + 'use_external_resource': True + } + fake_ctx._source.node.properties = { + 'volume': { + 'name': 'some' + }, + 'vcloud_config': { + 'vdc': 'vdc_name', + }, + 'resource_id': 'some' + } + fake_ctx._target.instance.runtime_properties = { + network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME + } + return fake_ctx, fake_client + + def test_attach_volume(self): + """ + use external resource, try to attach but no disks + """ + fake_ctx, fake_client = self._gen_volume_context_and_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.attach_volume(ctx=fake_ctx) + + def test_detach_volume(self): + """ + use external resource, try to detach but no disks + """ + fake_ctx, fake_client = self._gen_volume_context_and_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + volume.detach_volume(ctx=fake_ctx) + +if __name__ == '__main__': + unittest.main() diff --git a/tox.ini b/tox.ini index 282784b..20c84e6 100644 --- a/tox.ini +++ b/tox.ini @@ -16,11 +16,11 @@ commands = nosetests -x -s --tc=ondemand: tests/integration {posargs} commands = nosetests -x -s --tc=subscription: tests/integration {posargs} [testenv:py27-unittests] -commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin +commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin --cover-package=storage_plugin [testenv:pep8] commands= - flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts -ignore = + flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts storage_plugin +ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py From ab1c80222beaaae07e775fb8c4712cedf53eda94 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 10 Sep 2015 15:35:26 +0300 Subject: [PATCH 111/228] CFY-2841: fix license text --- manager_blueprint/scripts/configure.py | 14 + manager_blueprint/scripts/configure_docker.py | 14 + network_plugin/__init__.py | 14 + network_plugin/floatingip.py | 14 + network_plugin/keypair.py | 14 + network_plugin/network.py | 6 +- network_plugin/port.py | 14 + network_plugin/public_nat.py | 6 +- network_plugin/security_group.py | 14 + network_plugin/utils.py | 6 +- server_plugin/server.py | 6 +- system_tests/__init__.py | 6 +- system_tests/vcloud_handler.py | 6 +- tests/integration/__init__.py | 6 +- tests/integration/run_all_tests.py | 6 +- tests/integration/test_combined.py | 6 +- tests/integration/test_network_plugin.py | 6 +- tests/integration/test_server_plugin.py | 6 +- tests/syntax_check.py | 14 + tests/unittests/test_mock_base.py | 6 +- tests/unittests/test_mock_network_plugin.py | 6 +- .../test_mock_network_plugin_floatingip.py | 6 +- .../test_mock_network_plugin_keypair.py | 6 +- .../test_mock_network_plugin_network.py | 6 +- ...t_mock_network_plugin_network_subroutes.py | 6 +- .../test_mock_network_plugin_port.py | 6 +- .../test_mock_network_plugin_public_nat.py | 6 +- ...test_mock_network_plugin_security_group.py | 6 +- .../test_mock_server_plugin_server.py | 6 +- ...est_mock_server_plugin_server_subroutes.py | 6 +- .../test_mock_server_plugin_volume.py | 401 ------------------ .../test_mock_vcloud_plugin_common.py | 6 +- ...st_mock_vcloud_plugin_common_vca_client.py | 6 +- vcloud_plugin_common/__init__.py | 6 +- vcloud_plugin_common/workflows.py | 9 +- 35 files changed, 191 insertions(+), 481 deletions(-) delete mode 100644 tests/unittests/test_mock_server_plugin_volume.py diff --git a/manager_blueprint/scripts/configure.py b/manager_blueprint/scripts/configure.py index f83b668..e96bb14 100644 --- a/manager_blueprint/scripts/configure.py +++ b/manager_blueprint/scripts/configure.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import tempfile import json diff --git a/manager_blueprint/scripts/configure_docker.py b/manager_blueprint/scripts/configure_docker.py index 22aa3bc..7fb147e 100644 --- a/manager_blueprint/scripts/configure_docker.py +++ b/manager_blueprint/scripts/configure_docker.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import fabric diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index ec3dcca..ad6424e 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from IPy import IP from cloudify import exceptions as cfy_exc import collections diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 78ed618..d97598e 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index a29bf3b..9f74fb4 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/network.py b/network_plugin/network.py index b463466..6a6f316 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify import exceptions as cfy_exc diff --git a/network_plugin/port.py b/network_plugin/port.py index d6a5b67..bd85235 100644 --- a/network_plugin/port.py +++ b/network_plugin/port.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index a305044..0349f90 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify import exceptions as cfy_exc diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index f765442..4b013e6 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/utils.py b/network_plugin/utils.py index 747f5cc..6729344 100644 --- a/network_plugin/utils.py +++ b/network_plugin/utils.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import exceptions as cfy_exc diff --git a/server_plugin/server.py b/server_plugin/server.py index dbd02ab..83394b5 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify.decorators import operation diff --git a/system_tests/__init__.py b/system_tests/__init__.py index 1da0114..bd93320 100644 --- a/system_tests/__init__.py +++ b/system_tests/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from pkgutil import extend_path diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 22882c5..90b4867 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cosmo_tester.framework.handlers import ( BaseHandler, diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index c3fcb00..5afab65 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from testconfig import config import mock diff --git a/tests/integration/run_all_tests.py b/tests/integration/run_all_tests.py index 158932e..0364a52 100644 --- a/tests/integration/run_all_tests.py +++ b/tests/integration/run_all_tests.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import nose import os diff --git a/tests/integration/test_combined.py b/tests/integration/test_combined.py index 4e2548e..6965669 100644 --- a/tests/integration/test_combined.py +++ b/tests/integration/test_combined.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import contextlib import ipaddress diff --git a/tests/integration/test_network_plugin.py b/tests/integration/test_network_plugin.py index d0fb222..3529577 100644 --- a/tests/integration/test_network_plugin.py +++ b/tests/integration/test_network_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import os import mock diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index d8d1dff..e0bec19 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import random diff --git a/tests/syntax_check.py b/tests/syntax_check.py index 56db7b9..918ef2b 100644 --- a/tests/syntax_check.py +++ b/tests/syntax_check.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # Simple syntax check for blueprints and json examples import yaml diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 01a0540..8fabe53 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 1be23b4..2051c11 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index d1925fd..d2865f1 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 706bc2d..491418c 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import unittest import mock diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 64ea473..69852a5 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 109db43..67e3515 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 379a582..685ed32 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 1534e8f..f200461 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 54a4a5a..37c053c 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index ecc4fb5..85e6acd 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 7b42040..f8b0602 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_volume.py b/tests/unittests/test_mock_server_plugin_volume.py deleted file mode 100644 index 930c76d..0000000 --- a/tests/unittests/test_mock_server_plugin_volume.py +++ /dev/null @@ -1,401 +0,0 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. - -import mock -import unittest - -from cloudify import exceptions as cfy_exc -from cloudify import mocks as cfy_mocks -from server_plugin import volume -import vcloud_plugin_common -from tests.unittests import test_mock_base -import network_plugin - - -class ServerPluginServerMockTestCase(test_mock_base.TestBase): - - # vapp name used for tests - VAPPNAME = "some_other" - - def test_creation_validation_external_resource(self): - fake_client = self.generate_client() - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': True, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - # use external without resorse_id - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) - fake_client.get_disks.assert_called_with('vdc_name') - # with resource id, but without disks(no disks for this client) - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': True, - 'resource_id': 'some', - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) - # good case for external resource - fake_client.get_disks = mock.MagicMock(return_value=[ - [ - self.generate_fake_client_disk('some'), - self.generate_fake_vms_disk('some') - ] - ]) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.creation_validation(ctx=fake_ctx) - - def test_creation_validation_internal(self): - fake_client = self.generate_client() - # internal resource without volume - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) - fake_client.get_disks.assert_called_with('vdc_name') - # internal resourse wit volume and name, - # but already exist such volume - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'volume': { - 'name': 'some' - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - fake_client.get_disks = mock.MagicMock(return_value=[ - [ - self.generate_fake_client_disk('some'), - self.generate_fake_vms_disk('some') - ] - ]) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) - # correct name but without size - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'volume': { - 'name': 'some-other' - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) - # good case - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'volume': { - 'name': 'some-other', - 'size': 11 - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.creation_validation(ctx=fake_ctx) - - def test_delete_volume(self): - fake_client = self.generate_client() - # external resource - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': True, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.delete_volume(ctx=fake_ctx) - # cant't add disk - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'volume': { - 'name': 'some-other', - 'size': 11 - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.delete_volume(ctx=fake_ctx) - fake_client.delete_disk.assert_called_with( - 'vdc_name', 'some-other' - ) - # positive case - fake_client.delete_disk = mock.MagicMock( - return_value=( - True, self.generate_task( - vcloud_plugin_common.TASK_STATUS_SUCCESS - ) - ) - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.delete_volume(ctx=fake_ctx) - - def test_create_volume(self): - fake_client = self.generate_client() - # external resource - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': True, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.create_volume(ctx=fake_ctx) - # fail on create volume - fake_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={ - 'use_external_resource': False, - 'volume': { - 'name': 'some-other', - 'size': 11 - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - volume.create_volume(ctx=fake_ctx) - fake_client.add_disk.assert_called_with( - 'vdc_name', 'some-other', 11534336 - ) - # positive case - disk = mock.Mock() - disk.get_Tasks = mock.MagicMock( - return_value=[self.generate_task( - vcloud_plugin_common.TASK_STATUS_SUCCESS - )] - ) - fake_client.add_disk = mock.MagicMock( - return_value=(True, disk) - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.create_volume(ctx=fake_ctx) - - def test_volume_operation(self): - fake_ctx, fake_client = self._gen_volume_context_and_client() - - def _run_volume_operation(fake_ctx, fake_client, operation): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - with mock.patch( - 'server_plugin.volume.ctx', fake_ctx - ): - volume._volume_operation(fake_client, operation) - # use external resource, no disks - _run_volume_operation(fake_ctx, fake_client, 'ATTACH') - fake_client.get_diskRefs.assert_called_with( - fake_client._app_vdc - ) - # disk exist, can't attach - disk_ref = self.generate_fake_client_disk_ref('some') - fake_client.get_diskRefs = mock.MagicMock(return_value=[ - disk_ref - ]) - with self.assertRaises(cfy_exc.NonRecoverableError): - _run_volume_operation(fake_ctx, fake_client, 'ATTACH') - fake_client._vapp.attach_disk_to_vm.assert_called_with( - self.VAPPNAME, disk_ref - ) - # disk exist, can't detach - with self.assertRaises(cfy_exc.NonRecoverableError): - _run_volume_operation(fake_ctx, fake_client, 'DETACH') - fake_client._vapp.detach_disk_from_vm.assert_called_with( - self.VAPPNAME, disk_ref - ) - # wrong operation - with self.assertRaises(cfy_exc.NonRecoverableError): - _run_volume_operation(fake_ctx, fake_client, 'Wrong') - # disk exist, can attach - fake_client._vapp.attach_disk_to_vm = mock.MagicMock( - return_value=self.generate_task( - vcloud_plugin_common.TASK_STATUS_SUCCESS - ) - ) - _run_volume_operation(fake_ctx, fake_client, 'ATTACH') - # disk exist, can detach - fake_client._vapp.detach_disk_from_vm = mock.MagicMock( - return_value=self.generate_task( - vcloud_plugin_common.TASK_STATUS_SUCCESS - ) - ) - _run_volume_operation(fake_ctx, fake_client, 'DETACH') - # disk exist, use internal resource - fake_ctx._target.node.properties = { - 'volume': { - 'name': 'some' - }, - 'use_external_resource': False - } - _run_volume_operation(fake_ctx, fake_client, 'DETACH') - fake_client._vapp.detach_disk_from_vm.assert_called_with( - 'some_other', disk_ref - ) - # disk exist, use external resource - fake_ctx._target.node.properties = { - 'volume': { - 'name': 'some' - }, - 'use_external_resource': False - } - fake_ctx._source.node.properties.update( - {'use_external_resource': True}) - _run_volume_operation(fake_ctx, fake_client, 'DETACH') - fake_client._vapp.detach_disk_from_vm.assert_called_with( - 'some_other', disk_ref - ) - - def _gen_volume_context_and_client(self): - fake_client = self.generate_client() - fake_ctx = self.generate_relation_context() - fake_ctx._target.node.properties = { - 'use_external_resource': True - } - fake_ctx._source.node.properties = { - 'volume': { - 'name': 'some' - }, - 'vcloud_config': { - 'vdc': 'vdc_name', - }, - 'resource_id': 'some' - } - fake_ctx._target.instance.runtime_properties = { - network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME - } - return fake_ctx, fake_client - - def test_attach_volume(self): - """ - use external resource, try to attach but no disks - """ - fake_ctx, fake_client = self._gen_volume_context_and_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.attach_volume(ctx=fake_ctx) - - def test_detach_volume(self): - """ - use external resource, try to detach but no disks - """ - fake_ctx, fake_client = self._gen_volume_context_and_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.detach_volume(ctx=fake_ctx) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 320e674..3439227 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 725cc6e..a63f253 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 6aa7bc1..ba2d30c 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import atexit from functools import wraps diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index 0bcf6d5..9c442bc 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -1,17 +1,16 @@ -######## # Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify.decorators import workflow import cloudify.plugins.workflows as default_workflow From 620d23c4b8cb5c9640c989127a1cb951c1ccaa2d Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 10 Sep 2015 15:52:43 +0300 Subject: [PATCH 112/228] CFY-2841: pep8 fix --- storage_plugin/__init__.py | 1 - storage_plugin/volume.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/storage_plugin/__init__.py b/storage_plugin/__init__.py index 8b13789..e69de29 100644 --- a/storage_plugin/__init__.py +++ b/storage_plugin/__init__.py @@ -1 +0,0 @@ - diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index b9a6a50..720899a 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -19,7 +19,7 @@ get_vcloud_config, get_mandatory, error_response) from network_plugin import get_vapp_name -import time + @operation @with_vca_client From f2af5a75a80e396f7955a7e4552129be1190147e Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 11 Sep 2015 14:53:09 +0300 Subject: [PATCH 113/228] CFY-2841: add workflow update coverage test --- tests/unittests/test_mock_base.py | 53 +++++++--- .../test_mock_storage_plugin_volume.py | 2 +- ...est_mock_vcloud_plugin_common_workflows.py | 98 +++++++++++++++++++ vcloud_plugin_common/workflows.py | 21 ++-- 4 files changed, 151 insertions(+), 23 deletions(-) create mode 100644 tests/unittests/test_mock_vcloud_plugin_common_workflows.py diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 8fabe53..d3bac29 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -15,12 +15,43 @@ import mock import unittest from cloudify import mocks as cfy_mocks -from network_plugin import BUSY_MESSAGE, NAT_ROUTED import network_plugin network_plugin.GATEWAY_TRY_COUNT = 2 network_plugin.GATEWAY_TIMEOUT = 1 +class MockToscaCloudifyContext(cfy_mocks.MockCloudifyContext): + """updated mock for use with tosca""" + + _local = False + + @property + def local(self): + return self._local + + _internal = None + + @property + def internal(self): + return self._internal + + _nodes = None + + @property + def nodes(self): + return self._nodes + + +class MockToscaNodeInstanceContext(cfy_mocks.MockNodeInstanceContext): + """node instance mock for use with tosca""" + + _relationships = None + + @property + def relationships(self): + return self._relationships + + class TestBase(unittest.TestCase): ERROR_PLACE = "ERROR_MESSAGE_PLACE_HOLDER" @@ -47,7 +78,7 @@ def set_services_conf_result(self, gateway, result): def set_gateway_busy(self, gateway): message = gateway.response.content message = message.replace( - self.ERROR_PLACE, BUSY_MESSAGE + self.ERROR_PLACE, network_plugin.BUSY_MESSAGE ) gateway.response.content = message @@ -175,7 +206,9 @@ def set_network_routed_in_client(self, fake_client): """ set any network as routed """ - network = self.generate_fake_client_network(NAT_ROUTED) + network = self.generate_fake_client_network( + network_plugin.NAT_ROUTED + ) fake_client.get_network = mock.MagicMock(return_value=network) def generate_fake_client_disk(self, name="some_disk"): @@ -328,7 +361,7 @@ def generate_relation_context(self): target = mock.Mock() target.node = mock.Mock() target.instance.runtime_properties = {} - fake_ctx = cfy_mocks.MockCloudifyContext( + fake_ctx = MockToscaCloudifyContext( source=source, target=target ) return fake_ctx @@ -338,14 +371,6 @@ def generate_node_context( runtime_properties=None ): - class MockInstanceContext(cfy_mocks.MockNodeInstanceContext): - - self._relationships = None - - @property - def relationships(self): - return self._relationships - if not properties: properties = { 'management_network': '_management_network', @@ -357,7 +382,7 @@ def relationships(self): runtime_properties = { 'vcloud_vapp_name': 'vapp_name' } - fake_ctx = cfy_mocks.MockCloudifyContext( + fake_ctx = MockToscaCloudifyContext( node_id='test', node_name='test', properties=properties, @@ -365,7 +390,7 @@ def relationships(self): runtime_properties=runtime_properties ) - fake_ctx._instance = MockInstanceContext( + fake_ctx._instance = MockToscaNodeInstanceContext( fake_ctx.instance._id, fake_ctx.instance._runtime_properties ) diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index e15824c..32873e0 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -40,7 +40,7 @@ def test_creation_validation_external_resource(self): } } ) - # use external without resorse_id + # use external without resource_id with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) diff --git a/tests/unittests/test_mock_vcloud_plugin_common_workflows.py b/tests/unittests/test_mock_vcloud_plugin_common_workflows.py new file mode 100644 index 0000000..b340ffe --- /dev/null +++ b/tests/unittests/test_mock_vcloud_plugin_common_workflows.py @@ -0,0 +1,98 @@ +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from tests.unittests import test_mock_base +import vcloud_plugin_common +import vcloud_plugin_common.workflows + + +class VcloudPluginCommonWorkflowsMockTestCase(test_mock_base.TestBase): + + def _generate_instance(self): + fake_instance = mock.Mock() + fake_instance._node_instance = { + 'runtime_properties': { + }, + 'version': None + } + fake_instance.id = "fake_instance" + return fake_instance + + def check_instance(self, call_function, fake_instance): + call_function.assert_called_with( + fake_instance._node_instance + ) + # check for installed token and url + self.assertEqual( + fake_instance._node_instance, { + 'runtime_properties': { + vcloud_plugin_common.ORG_URL: 'org_url', + vcloud_plugin_common.SESSION_TOKEN: 'token' + }, + 'version': 0 + } + ) + + def test_update(self): + """check update logic""" + fake_ctx = self.generate_node_context() + fake_instance = self._generate_instance() + call_function = mock.MagicMock() + with mock.patch( + 'vcloud_plugin_common.workflows.update_node_instance', + call_function + ): + vcloud_plugin_common.workflows.update( + fake_ctx, fake_instance, "token", "org_url" + ) + self.check_instance(call_function, fake_instance) + # use local version + fake_ctx._local = True + internal = mock.MagicMock() + update_call = mock.MagicMock() + internal.handler.storage.update_node_instance = update_call + fake_ctx._internal = internal + vcloud_plugin_common.workflows.update( + fake_ctx, fake_instance, "token", "org_url" + ) + update_call.assert_called_with( + 'fake_instance', 0, { + 'org_url': 'org_url', + 'session_token': 'token' + }, None + ) + + def test_get_all_nodes_instances(self): + """update all instances in context""" + fake_ctx = self.generate_node_context() + fake_instance = self._generate_instance() + call_function = mock.MagicMock() + # create fake node with all prpoerties + fake_node = mock.MagicMock() + fake_node.properties = { + vcloud_plugin_common.VCLOUD_CONFIG: 'some_magic_here' + } + fake_node.instances = [fake_instance] + fake_ctx._nodes = [fake_node] + # try to run + with mock.patch( + 'vcloud_plugin_common.workflows.update_node_instance', + call_function + ): + vcloud_plugin_common.workflows._get_all_nodes_instances( + fake_ctx, "token", "org_url" + ) + self.check_instance(call_function, fake_instance) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index 9c442bc..0202ffc 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,16 +13,19 @@ # limitations under the License. from cloudify.decorators import workflow -import cloudify.plugins.workflows as default_workflow from cloudify.manager import update_node_instance -from vcloud_plugin_common import (SESSION_TOKEN, ORG_URL, VCLOUD_CONFIG) +import cloudify.plugins.workflows as default_workflow +import vcloud_plugin_common def update(ctx, instance, token, org_url): + """updete token and url in instance""" node_instance = instance._node_instance rt_properties = node_instance['runtime_properties'] - rt_properties.update({SESSION_TOKEN: token, - ORG_URL: org_url}) + rt_properties.update({ + vcloud_plugin_common.SESSION_TOKEN: token, + vcloud_plugin_common.ORG_URL: org_url + }) version = node_instance['version'] node_instance['version'] = version if version else 0 if ctx.local: @@ -36,11 +39,13 @@ def update(ctx, instance, token, org_url): def _get_all_nodes_instances(ctx, token, org_url): + """return all instances from context nodes""" node_instances = set() for node in ctx.nodes: - for instance in node.instances: - if token and org_url and VCLOUD_CONFIG in node.properties: - update(ctx, instance, token, org_url) + if vcloud_plugin_common.VCLOUD_CONFIG in node.properties: + for instance in node.instances: + if token and org_url: + update(ctx, instance, token, org_url) node_instances.add(instance) return node_instances From a639ddcf35fa00506d4e11ce9b2bbaeb2464976a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 11 Sep 2015 16:18:09 +0300 Subject: [PATCH 114/228] CFY-2841: Backport wait boot logic for volume --- network_plugin/__init__.py | 27 ++++++++++++++- network_plugin/floatingip.py | 8 ++++- network_plugin/network.py | 4 +-- network_plugin/public_nat.py | 25 ++------------ network_plugin/security_group.py | 2 +- storage_plugin/volume.py | 34 ++++++++++++++++++- tests/unittests/test_mock_network_plugin.py | 12 +++---- .../test_mock_storage_plugin_volume.py | 13 +++---- 8 files changed, 84 insertions(+), 41 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index ad6424e..fd50925 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -18,10 +18,14 @@ from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType from vcloud_plugin_common import (wait_for_task, get_vcloud_config, is_subscription, error_response) +from cloudify_rest_client import exceptions as rest_exceptions +import time VCLOUD_VAPP_NAME = 'vcloud_vapp_name' PUBLIC_IP = 'public_ip' +SSH_PUBLIC_IP = 'ssh_public_ip' +SSH_PORT = 'ssh_port' NAT_ROUTED = 'natRouted' CREATE = 1 DELETE = 2 @@ -148,7 +152,7 @@ def get_vapp_name(runtime_properties): return vapp_name -def save_gateway_configuration(gateway, vca_client): +def save_gateway_configuration(gateway, vca_client, ctx): """ save gateway configuration, return everything successfully finished @@ -157,10 +161,12 @@ def save_gateway_configuration(gateway, vca_client): task = gateway.save_services_configuration() if task: wait_for_task(vca_client, task) + ctx.logger.info("Gateway parameters has been saved.") return True else: error = taskType.parseString(gateway.response.content, True) if BUSY_MESSAGE in error.message: + ctx.logger.info("Gateway is busy.") return False else: raise cfy_exc.NonRecoverableError(error.message) @@ -305,3 +311,22 @@ def set_retry(ctx): return ctx.operation.retry( message='Waiting for gateway.', retry_after=GATEWAY_TIMEOUT) + + +def save_ssh_parameters(ctx, port, ip): + retries_update = 3 + update_pending = True + while retries_update > 0 and update_pending: + retries_update = retries_update - 1 + try: + ctx.source.instance.runtime_properties[SSH_PORT] = port + ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] = ip + ctx.source.instance.update() + update_pending = False + except rest_exceptions.CloudifyClientError as e: + if 'conflict' in str(e): + # cannot 'return' in contextmanager + ctx.logger.info( + "Conflict in updating backend, retrying") + else: + raise e diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index d97598e..54bde0e 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -21,6 +21,7 @@ CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, CREATE, DELETE, PUBLIC_IP, get_gateway, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, set_retry) @@ -109,11 +110,12 @@ def _floatingip_operation(operation, vca_client, ctx): nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) - success = save_gateway_configuration(gateway, vca_client) + success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip + save_ssh_parameters(ctx, '22', external_ip) else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): @@ -124,6 +126,10 @@ def _floatingip_operation(operation, vca_client, ctx): ctx) if PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PUBLIC_IP] + if SSH_PUBLIC_IP in ctx.source.instance.runtime_properties: + del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] + if SSH_PORT in ctx.target.instance.runtime_properties: + del ctx.source.instance.runtime_properties[SSH_PORT] return True diff --git a/network_plugin/network.py b/network_plugin/network.py index 6a6f316..e3815a8 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -201,14 +201,14 @@ def _dhcp_operation(vca_client, network_name, operation): max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) - if save_gateway_configuration(gateway, vca_client): + if save_gateway_configuration(gateway, vca_client, ctx): ctx.logger.info("DHCP rule successful created for network {0}" .format(network_name)) return True if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) - if save_gateway_configuration(gateway, vca_client): + if save_gateway_configuration(gateway, vca_client, ctx): ctx.logger.info("DHCP rule successful deleted for network {0}" .format(network_name)) return True diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 0349f90..b830d12 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -20,15 +20,13 @@ from network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, del_ondemand_public_ip, utils, set_retry) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP -from cloudify_rest_client import exceptions as rest_exceptions PORT_REPLACEMENT = 'port_replacement' DEFAULT_SSH_PORT = '22' -SSH_PORT = 'ssh_port' -SSH_PUBLIC_IP = 'ssh_public_ip' @operation @@ -182,24 +180,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, function = gateway.add_nat_rule message = "Add" if _is_dnat(rule_type) and str(translated_port) == DEFAULT_SSH_PORT: - retries_update = 3 - update_pending = True - while retries_update > 0 and update_pending: - retries_update = retries_update - 1 - try: - ctx.source.instance.runtime_properties[SSH_PORT] = str( - new_original_port) - ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] =\ - public_ip - ctx.source.instance.update() - update_pending = False - except rest_exceptions.CloudifyClientError as e: - if 'conflict' in str(e): - # cannot 'return' in contextmanager - ctx.logger.info( - "Conflict in updating backend, retrying") - else: - raise e + save_ssh_parameters(ctx, str(new_original_port), public_ip) elif operation == DELETE: new_original_port = _get_original_port_for_delete( public_ip, original_port) @@ -238,7 +219,7 @@ def _save_configuration(gateway, vca_client, operation, public_ip): save/refresh nat rules on gateway """ ctx.logger.info("Save NAT configuration.") - success = save_gateway_configuration(gateway, vca_client) + success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False ctx.logger.info("NAT configuration has been saved.") diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index 4b013e6..2d9ab69 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -139,7 +139,7 @@ def _rule_operation(operation, vca_client): ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) - return save_gateway_configuration(gateway, vca_client) + return save_gateway_configuration(gateway, vca_client, ctx) def _get_gateway_name(properties): diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index 720899a..b922572 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -18,7 +18,7 @@ from vcloud_plugin_common import (wait_for_task, with_vca_client, get_vcloud_config, get_mandatory, error_response) -from network_plugin import get_vapp_name +from network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT @operation @@ -102,6 +102,7 @@ def creation_validation(vca_client, **kwargs): @with_vca_client def attach_volume(vca_client, **kwargs): """attach volume""" + _wait_for_boot() _volume_operation(vca_client, "ATTACH") @@ -155,3 +156,34 @@ def _volume_operation(vca_client, operation): else: raise cfy_exc.NonRecoverableError( "Unknown operation '{0}'".format(operation)) + + +def _wait_for_boot(): + """ + Whait for loading os. + This function just check if sshd is available. + After attaching disk system may be unbootable, + therefore user can do some manipulation for setup boot sequence. + """ + from fabric import api as fabric_api + ip = ctx.target.instance.runtime_properties.get(SSH_PUBLIC_IP) + if not ip: + # private ip will be used in case + # when we does not have public ip + ip = ctx.target.instance.runtime_properties['ip'] + port = ctx.target.instance.runtime_properties.get(SSH_PORT, 22) + ctx.logger.info("Using ip '{0}'.".format(ip)) + for i in range(30): + ctx.logger.info("Wait for boot '{0}'.".format(i)) + try: + with fabric_api.settings( + host_string=ip, port=port, warn_only=True, + abort_on_prompts=True + ): + fabric_api.run('id') + time.sleep(5) + except SystemExit: + return + except Exception: + pass + raise cfy_exc.NonRecoverableError("Can't wait for boot") diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 2051c11..130042c 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -187,10 +187,10 @@ def test_save_gateway_configuration(self): self.set_services_conf_result( gateway, None ) + fake_ctx = self.generate_node_context() with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.save_gateway_configuration( - gateway, fake_client - ) + gateway, fake_client, fake_ctx) # error in status self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_ERROR @@ -198,7 +198,7 @@ def test_save_gateway_configuration(self): with self.assertRaises(cfy_exc.NonRecoverableError): with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): network_plugin.save_gateway_configuration( - gateway, fake_client) + gateway, fake_client, fake_ctx) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -206,7 +206,7 @@ def test_save_gateway_configuration(self): with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): self.assertTrue( network_plugin.save_gateway_configuration( - gateway, fake_client)) + gateway, fake_client, fake_ctx)) # server busy self.set_services_conf_result( gateway, None @@ -214,9 +214,7 @@ def test_save_gateway_configuration(self): self.set_gateway_busy(gateway) self.assertFalse( network_plugin.save_gateway_configuration( - gateway, fake_client - ) - ) + gateway, fake_client, fake_ctx)) def test_is_network_routed(self): """ diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 32873e0..442b877 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -371,7 +371,8 @@ def _gen_volume_context_and_client(self): 'resource_id': 'some' } fake_ctx._target.instance.runtime_properties = { - network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME + network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME, + 'ip': "1.2.3.4" } return fake_ctx, fake_client @@ -380,11 +381,11 @@ def test_attach_volume(self): use external resource, try to attach but no disks """ fake_ctx, fake_client = self._gen_volume_context_and_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - volume.attach_volume(ctx=fake_ctx) + with mock.patch('vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client)): + with mock.patch( + 'storage_plugin.volume._wait_for_boot', mock.MagicMock()): + volume.attach_volume(ctx=fake_ctx) def test_detach_volume(self): """ From 60690dbe89ff97ae7299b0301b49e5a7e5e07bc9 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 8 Sep 2015 16:04:22 +0400 Subject: [PATCH 115/228] CFY-3539 Protection against simultaneous access to the gateway --- network_plugin/__init__.py | 69 +++++++++++++++++-- network_plugin/floatingip.py | 6 +- network_plugin/public_nat.py | 6 +- network_plugin/security_group.py | 10 +-- tests/unittests/test_mock_network_plugin.py | 13 ++-- .../test_mock_network_plugin_floatingip.py | 14 ++++ .../test_mock_network_plugin_public_nat.py | 64 ++++++++++++++++- ...test_mock_network_plugin_security_group.py | 22 ++++++ vcloud_plugin_common/__init__.py | 7 +- 9 files changed, 185 insertions(+), 26 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index fd50925..95ed62d 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -20,6 +20,7 @@ is_subscription, error_response) from cloudify_rest_client import exceptions as rest_exceptions import time +from functools import wraps VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -27,6 +28,7 @@ SSH_PUBLIC_IP = 'ssh_public_ip' SSH_PORT = 'ssh_port' NAT_ROUTED = 'natRouted' +GATEWAY_LOCK = 'gateway_lock' CREATE = 1 DELETE = 2 @@ -249,13 +251,27 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): try to allocate new public ip for ondemand service """ old_public_ips = set(gateway.get_public_ips()) - ctx.logger.info("Try to allocate public IP") - task = gateway.allocate_public_ip() - if task: - wait_for_task(vca_client, task) - else: - raise cfy_exc.NonRecoverableError( - "Can't get public ip for ondemand service {0}".format(error_response(gateway))) + allocated_ips = set([address.external + for address in collectAssignedIps(gateway)]) + available_ips = old_public_ips - allocated_ips + if available_ips: + new_ip = list(available_ips)[0] + ctx.logger.info("Public IP {0} was reused.".format(new_ip)) + return new_ip + for i in range(5): + ctx.logger.info("Try to allocate public IP") + wait_for_gateway(vca_client, gateway.get_name(), ctx) + task = gateway.allocate_public_ip() + if task: + try: + wait_for_task(vca_client, task) + break + except cfy_exc.NonRecoverableError: + continue + else: + raise cfy_exc.NonRecoverableError( + "Can't get public ip for ondemand service {0}". + format(error_response(gateway))) # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) @@ -330,3 +346,42 @@ def save_ssh_parameters(ctx, port, ip): "Conflict in updating backend, retrying") else: raise e + + +def wait_for_gateway(vca_client, gateway_name, ctx): + for i in range(10): + gateway = get_gateway(vca_client, gateway_name) + if not gateway.is_busy(): + return + ctx.logger.info("Check {0}. Gateway is busy.".format(i)) + time.sleep(10) + raise cfy_exc.NonRecoverableError( + "Can't wait gateway {0}".format(gateway_name)) + + +def lock_gateway(f): + def update_parameters(ctx, value): + ctx.source.instance.runtime_properties[GATEWAY_LOCK] = value + ctx.source.instance.update() + + @wraps(f) + def wrapper(*args, **kw): + ctx = kw['ctx'] + # Reset for getting last version of runtime_properties + ctx.source.instance._node_instance = None + if ctx.source.instance.runtime_properties.get(GATEWAY_LOCK): + ctx.logger.info("Gateway locked.") + return set_retry(ctx) + ctx.logger.info("Lock gateway.") + update_parameters(ctx, True) + vca_client = kw['vca_client'] + gateway_name = get_vcloud_config()['edge_gateway'] + wait_for_gateway(vca_client, gateway_name, ctx) + try: + result = f(*args, **kw) + finally: + ctx.logger.info("Unlock gateway.") + ctx.source.instance._node_instance = None + update_parameters(ctx, False) + return result + return wrapper diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 54bde0e..e3bac1b 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -23,11 +23,12 @@ CREATE, DELETE, PUBLIC_IP, get_gateway, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, - set_retry) + set_retry, lock_gateway) @operation @with_vca_client +@lock_gateway def connect_floatingip(vca_client, **kwargs): """ create new floating ip for node @@ -38,6 +39,7 @@ def connect_floatingip(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def disconnect_floatingip(vca_client, **kwargs): """ release floating ip @@ -81,8 +83,6 @@ def _floatingip_operation(operation, vca_client, ctx): service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) - if gateway.is_busy(): - return False internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index b830d12..d58947e 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -21,7 +21,7 @@ get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry) + del_ondemand_public_ip, utils, set_retry, lock_gateway) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP @@ -44,6 +44,7 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def net_connect_to_nat(vca_client, **kwargs): """ create nat rule for current node @@ -57,6 +58,7 @@ def net_connect_to_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def net_disconnect_from_nat(vca_client, **kwargs): """ drop nat rule for current node @@ -70,6 +72,7 @@ def net_disconnect_from_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def server_connect_to_nat(vca_client, **kwargs): """ create nat rules for server @@ -80,6 +83,7 @@ def server_connect_to_nat(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def server_disconnect_from_nat(vca_client, **kwargs): """ drop nat rules for server diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index 2d9ab69..bec924b 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -18,7 +18,7 @@ from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) from network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, - get_gateway, utils, set_retry) + get_gateway, utils, set_retry, lock_gateway) CREATE_RULE = 1 @@ -30,6 +30,7 @@ @operation @with_vca_client +@lock_gateway def create(vca_client, **kwargs): """ create firewall rules for node @@ -40,6 +41,7 @@ def create(vca_client, **kwargs): @operation @with_vca_client +@lock_gateway def delete(vca_client, **kwargs): """ drop firewall rules for node @@ -105,10 +107,8 @@ def _rule_operation(operation, vca_client): """ create/delete firewall rules in gateway for current node """ - gateway = get_gateway( - vca_client, _get_gateway_name(ctx.target.node.properties)) - if gateway.is_busy(): - return False + gateway_name = _get_gateway_name(ctx.target.node.properties) + gateway = get_gateway(vca_client, gateway_name) for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 130042c..dabc3d0 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -161,10 +161,10 @@ def test_del_ondemand_public_ip(self): fake_ctx = self.generate_node_context() # can't deallocate ip gateway.deallocate_public_ip = mock.MagicMock(return_value=None) - with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.del_ondemand_public_ip( - fake_client, gateway, '127.0.0.1', fake_ctx - ) + with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): + with self.assertRaises(cfy_exc.NonRecoverableError): + network_plugin.del_ondemand_public_ip( + fake_client, gateway, '127.0.0.1', fake_ctx) gateway.deallocate_public_ip.assert_called_with('127.0.0.1') # successfully dropped public ip gateway.deallocate_public_ip = mock.MagicMock( @@ -173,8 +173,9 @@ def test_del_ondemand_public_ip(self): ) ) with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): - network_plugin.del_ondemand_public_ip( - fake_client, gateway, '127.0.0.1', fake_ctx) + with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): + network_plugin.del_ondemand_public_ip( + fake_client, gateway, '127.0.0.1', fake_ctx) def test_save_gateway_configuration(self): """ diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index d2865f1..c2fd9db 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -369,6 +369,14 @@ def test_disconnect_floatingip(self): 'ssh_port': 22, 'ssh_public_ip': '1.2.3.1' } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_client._vdc_gateway.deallocate_public_ip = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -397,6 +405,12 @@ def test_connect_floatingip(self): 'floatingip': { 'edge_gateway': 'gateway', network_plugin.PUBLIC_IP: '10.10.2.3' + }} + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' } } fake_ctx._target.instance.runtime_properties = {} diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index f200461..0bbd307 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -367,7 +367,9 @@ def _context_for_delete(service_type): } properties = { 'vcloud_config': { - 'org': 'some_org', + 'edge_gateway': 'gateway', + 'vdc': 'vdc', + 'org': 'some_org' } } if service_type: @@ -481,6 +483,7 @@ def _ip_exist_in_runtime(fake_ctx): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): + # import pdb;pdb.set_trace() public_nat._save_configuration( gateway, fake_client, network_plugin.DELETE, "1.2.3.4" ) @@ -918,6 +921,17 @@ def test_server_disconnect_from_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -932,6 +946,17 @@ def test_server_connect_to_nat(self): fake_ctx._target.instance.runtime_properties = { network_plugin.PUBLIC_IP: '192.168.1.1' } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } fake_ctx._target.node.properties = { 'nat': { 'edge_gateway': 'gateway' @@ -940,6 +965,7 @@ def test_server_connect_to_nat(self): 'type': 'DNAT' }] } + fake_client._vdc_gateway.get_public_ips = mock.MagicMock( return_value=['10.18.1.1'] ) @@ -958,6 +984,18 @@ def test_net_disconnect_from_nat(self): fake_ctx._target.node.properties = { 'use_external_resource': True } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -973,6 +1011,14 @@ def test_net_disconnect_from_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -989,6 +1035,14 @@ def test_net_connect_to_nat(self): fake_ctx._target.node.properties = { 'use_external_resource': True } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -1004,6 +1058,14 @@ def test_net_connect_to_nat(self): 'type': 'DNAT' }] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1' ]) diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 37c053c..a4b67d9 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -337,6 +337,17 @@ def test_create(self): fake_ctx._target.node.properties = { 'rules': [] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) @@ -353,6 +364,17 @@ def test_delete(self): fake_ctx._target.node.properties = { 'rules': [] } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + fake_ctx._source.instance.runtime_properties = { + 'gateway_lock': False, + 'vcloud_vapp_name': 'vapp' + } self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index ba2d30c..3d80df2 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -26,9 +26,10 @@ from cloudify import context from cloudify import exceptions as cfy_exc -TASK_RECHECK_TIMEOUT = 3 -RELOGIN_TIMEOUT = 3 -LOGIN_RETRY_NUM = 5 + +TASK_RECHECK_TIMEOUT = 5 +RELOGIN_TIMEOUT = 5 +LOGIN_RETRY_NUM = 15 TASK_STATUS_SUCCESS = 'success' TASK_STATUS_ERROR = 'error' From d160ff1fd90d4ed57b5fdab16ab9846050c348e4 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 11 Sep 2015 17:46:00 +0300 Subject: [PATCH 116/228] CFY-2841: pep8 fix --- storage_plugin/volume.py | 1 + 1 file changed, 1 insertion(+) diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index b922572..0c79f78 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import time from cloudify import ctx from cloudify import exceptions as cfy_exc From 289a4fab08e9285e69c17a9773b8d03110c7edaf Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 28 Aug 2015 08:55:42 +0400 Subject: [PATCH 117/228] CFY-3457 Add create-vdc and delete-vdc options to vcloud plugin Backport of 0a33298cc8acb0d4aeaf151bdb602c9e331338a7 --- plugin.yaml | 25 +++++ server_plugin/vdc.py | 97 +++++++++++++++++++ tests/integration/test_server_plugin.py | 42 +++++++- .../test_mock_network_plugin_public_nat.py | 4 +- 4 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 server_plugin/vdc.py diff --git a/plugin.yaml b/plugin.yaml index 9299d12..de51cf2 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -162,6 +162,29 @@ node_types: creation: implementation: vcloud.storage_plugin.volume.creation_validation + cloudify.vcloud.nodes.VDC: + derived_from: cloudify.nodes.Root + properties: + name: + default: '' + use_external_resource: + default: false + resource_id: + default: '' + vcloud_config: + default: {} + interfaces: + cloudify.interfaces.lifecycle: + create: + implementation: vcloud.server_plugin.vdc.create + inputs: {} + delete: + implementation: vcloud.server_plugin.vdc.delete + inputs: {} + cloudify.interfaces.validation: + creation: + implementation: vcloud.server_plugin.vdc.creation_validation + relationships: cloudify.vcloud.server_connected_to_floating_ip: derived_from: cloudify.relationships.connected_to @@ -232,6 +255,8 @@ relationships: unlink: implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair inputs: {} + cloudify.vcloud.server_connected_to_vdc: + derived_from: cloudify.relationships.connected_to workflows: scoreinstall: vcloud.vcloud_plugin_common.workflows.install diff --git a/server_plugin/vdc.py b/server_plugin/vdc.py new file mode 100644 index 0000000..a77853c --- /dev/null +++ b/server_plugin/vdc.py @@ -0,0 +1,97 @@ + +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. + +from cloudify import ctx +from cloudify.decorators import operation +from cloudify import exceptions as cfy_exc + +from vcloud_plugin_common import (get_vcloud_config, + wait_for_task, + with_vca_client, + is_subscription, + error_response) + +VDC_NAME = 'vdc_name' +RESOURCE_ID = 'resource_id' +USE_EXTERNAL_RESOURCE = 'use_external_resource' + + +@operation +@with_vca_client +def creation_validation(vca_client, **kwargs): + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + if not ctx.node.properties.get(RESOURCE_ID): + raise cfy_exc.NonRecoverableError( + "resource_id server properties must be specified") + res_id = ctx.node.properties[RESOURCE_ID] + vdc = vca_client.get_vdc(res_id) + if not vdc: + raise cfy_exc.NonRecoverableError( + "Unable to find external VDC {0}." + .format(res_id)) + else: + vdc_name = ctx.node.properties.get('name') + if not vdc_name: + raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") + vdc = vca_client.get_vdc(vdc_name) + if vdc: + raise cfy_exc.NonRecoverableError( + "VDC '{0}' already exists." + .format(res_id)) + + +@operation +@with_vca_client +def create(vca_client, **kwargs): + config = get_vcloud_config() + if is_subscription(config['service_type']): + raise cfy_exc.NonRecoverableError( + "Unable create VDC on subscription service.") + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + res_id = ctx.node.properties[RESOURCE_ID] + ctx.instance.runtime_properties[VDC_NAME] = res_id + vdc = vca_client.get_vdc(res_id) + if not vdc: + raise cfy_exc.NonRecoverableError( + "Unable to find external VDC {0}." + .format(res_id)) + ctx.logger.info( + "External resource {0} has been used".format(res_id)) + else: + vdc_name = ctx.node.properties.get('name') + if not vdc_name: + raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") + task = vca_client.create_vdc(vdc_name) + if not task: + raise cfy_exc.NonRecoverableError("Could not create VDC: {0}" + .format(error_response(vca_client))) + wait_for_task(vca_client, task) + + +@operation +@with_vca_client +def delete(vca_client, **kwargs): + if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + ctx.logger.info('Not deleting VDC since an external VDC is ' + 'being used') + else: + vdc_name = ctx.node.properties.get('name') + status, task = vca_client.delete_vdc(vdc_name) + if not status: + raise cfy_exc.NonRecoverableError("Could not delete VDC: {0}" + .format(error_response(vca_client))) + wait_for_task(vca_client, task) + if VDC_NAME in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[VDC_NAME] diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index e0bec19..65c5d56 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -23,10 +23,14 @@ from server_plugin import server from server_plugin import volume +from server_plugin import vdc from tests.integration import TestCase from cloudify.mocks import MockCloudifyContext from server_plugin.server import VCLOUD_VAPP_NAME +from vcloud_plugin_common import VcloudAirClient + + RANDOM_PREFIX_LENGTH = 5 @@ -364,4 +368,40 @@ def links_count(): volume.attach_volume() self.assertEqual(links_before + 1, links_count()) volume.detach_volume() - self.assertEqual(links_before, links_count()) + + +class VdcTestCase(TestCase): + def setUp(self): + super(VdcTestCase, self).setUp() + self.vdc_test_dict = self.test_config['vdc'] + name = 'vdc' + self.properties = { + 'name': self.vdc_test_dict['name'], + 'use_external_resource': False, + 'resource_id': self.vdc_test_dict['name_exists'], + 'vcloud_config': self.vcloud_config + } + self.nodectx = cfy_mocks.MockCloudifyContext( + node_id=name, + node_name=name, + properties=self.properties + ) + self.ctx = self.nodectx + ctx_patch1 = mock.patch('server_plugin.vdc.ctx', self.nodectx) + ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.nodectx) + ctx_patch1.start() + ctx_patch2.start() + self.addCleanup(ctx_patch1.stop) + self.addCleanup(ctx_patch2.stop) + + def test_vdc_create_delete(self): + name = self.properties['name'] + self.assertFalse(name in self._get_vdc_names()) + vdc.create() + self.assertTrue(name in self._get_vdc_names()) + vdc.delete() + self.assertFalse(name in self._get_vdc_names()) + + def _get_vdc_names(self): + vca_client = VcloudAirClient().get(config=self.vcloud_config) + return vca_client.get_vdc_names() diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 0bbd307..e553792 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -305,7 +305,7 @@ def test_create_ip_range(self): fake_ctx._source.node.properties = { 'vcloud_config': { 'org': 'some_org', - 'vdc': 'some_org' + 'vdc': 'some_vdc' } } fake_ctx._target.instance.runtime_properties = {} @@ -330,7 +330,7 @@ def test_create_ip_range(self): public_nat._create_ip_range(fake_client, gate), '127.1.1.100 - 127.1.1.200' ) - fake_client.get_networks.assert_called_with("some_org") + fake_client.get_networks.assert_called_with("some_vdc") # network from gate gate.get_dhcp_pools = mock.MagicMock(return_value=[ self.genarate_pool( From b10866bac1481574bf218085e386ad8d76d5f13a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 14 Sep 2015 15:45:00 +0300 Subject: [PATCH 118/228] CFY-2841: add correct header and code cleanups --- manager_blueprint/scripts/configure.py | 14 +++ manager_blueprint/scripts/configure_docker.py | 14 +++ network_plugin/__init__.py | 14 +++ network_plugin/floatingip.py | 14 +++ network_plugin/keypair.py | 14 +++ network_plugin/network.py | 6 +- network_plugin/port.py | 14 +++ network_plugin/public_nat.py | 10 +- network_plugin/security_group.py | 14 +++ network_plugin/utils.py | 6 +- plugin.yaml | 2 +- server_plugin/server.py | 6 +- setup.py | 10 +- storage_plugin/__init__.py | 14 --- storage_plugin/volume.py | 26 ++--- system_tests/__init__.py | 6 +- system_tests/vcloud_handler.py | 6 +- tests/integration/__init__.py | 6 +- tests/integration/run_all_tests.py | 6 +- tests/integration/test_combined.py | 6 +- tests/integration/test_network_plugin.py | 6 +- tests/integration/test_server_plugin.py | 6 +- tests/syntax_check.py | 14 +++ tests/unittests/test_mock_base.py | 59 +++++++---- tests/unittests/test_mock_network_plugin.py | 6 +- .../test_mock_network_plugin_floatingip.py | 6 +- .../test_mock_network_plugin_keypair.py | 6 +- .../test_mock_network_plugin_network.py | 6 +- ...t_mock_network_plugin_network_subroutes.py | 6 +- .../test_mock_network_plugin_port.py | 6 +- .../test_mock_network_plugin_public_nat.py | 11 ++- ...test_mock_network_plugin_security_group.py | 6 +- .../test_mock_server_plugin_server.py | 6 +- ...est_mock_server_plugin_server_subroutes.py | 6 +- ....py => test_mock_storage_plugin_volume.py} | 10 +- .../test_mock_vcloud_plugin_common.py | 6 +- ...st_mock_vcloud_plugin_common_vca_client.py | 6 +- ...est_mock_vcloud_plugin_common_workflows.py | 98 +++++++++++++++++++ tox.ini | 6 +- vcloud_plugin_common/__init__.py | 6 +- vcloud_plugin_common/workflows.py | 30 +++--- 41 files changed, 374 insertions(+), 146 deletions(-) rename tests/unittests/{test_mock_server_plugin_volume.py => test_mock_storage_plugin_volume.py} (97%) create mode 100644 tests/unittests/test_mock_vcloud_plugin_common_workflows.py diff --git a/manager_blueprint/scripts/configure.py b/manager_blueprint/scripts/configure.py index f83b668..e96bb14 100644 --- a/manager_blueprint/scripts/configure.py +++ b/manager_blueprint/scripts/configure.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import tempfile import json diff --git a/manager_blueprint/scripts/configure_docker.py b/manager_blueprint/scripts/configure_docker.py index 22aa3bc..7fb147e 100644 --- a/manager_blueprint/scripts/configure_docker.py +++ b/manager_blueprint/scripts/configure_docker.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import fabric diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index d939a9f..a2bed39 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from IPy import IP from cloudify import exceptions as cfy_exc import collections diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 3a6e29e..e3bac1b 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index a29bf3b..9f74fb4 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/network.py b/network_plugin/network.py index e2bbb56..e3815a8 100644 --- a/network_plugin/network.py +++ b/network_plugin/network.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify import exceptions as cfy_exc diff --git a/network_plugin/port.py b/network_plugin/port.py index d6a5b67..bd85235 100644 --- a/network_plugin/port.py +++ b/network_plugin/port.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 6a40adf..d58947e 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify import exceptions as cfy_exc @@ -243,9 +243,9 @@ def _save_configuration(gateway, vca_client, operation, public_ip): if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] if SSH_PORT in ctx.target.instance.runtime_properties: - del ctx.source.instance.runtime_properties[SSH_PORT] + del ctx.target.instance.runtime_properties[SSH_PORT] if SSH_PUBLIC_IP in ctx.target.instance.runtime_properties: - del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] + del ctx.target.instance.runtime_properties[SSH_PUBLIC_IP] return True diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index 8010cca..b6e4a51 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation diff --git a/network_plugin/utils.py b/network_plugin/utils.py index 747f5cc..6729344 100644 --- a/network_plugin/utils.py +++ b/network_plugin/utils.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import exceptions as cfy_exc diff --git a/plugin.yaml b/plugin.yaml index 38b3193..6558285 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m5.zip node_types: cloudify.vcloud.nodes.Server: diff --git a/server_plugin/server.py b/server_plugin/server.py index b013aba..c1edabe 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify.decorators import operation diff --git a/setup.py b/setup.py index 12a5ebd..e4f2da8 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ -######### -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -9,10 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. - +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from setuptools import setup setup( diff --git a/storage_plugin/__init__.py b/storage_plugin/__init__.py index a9dfcc4..e69de29 100644 --- a/storage_plugin/__init__.py +++ b/storage_plugin/__init__.py @@ -1,14 +0,0 @@ -######### -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index 7930cee..0c79f78 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -8,9 +8,10 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import time from cloudify import ctx from cloudify import exceptions as cfy_exc @@ -18,8 +19,8 @@ from vcloud_plugin_common import (wait_for_task, with_vca_client, get_vcloud_config, get_mandatory, error_response) -from network_plugin import get_vapp_name -import time +from network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT + @operation @with_vca_client @@ -101,9 +102,7 @@ def creation_validation(vca_client, **kwargs): @operation @with_vca_client def attach_volume(vca_client, **kwargs): - """ - attach volume - """ + """attach volume""" _wait_for_boot() _volume_operation(vca_client, "ATTACH") @@ -168,15 +167,20 @@ def _wait_for_boot(): therefore user can do some manipulation for setup boot sequence. """ from fabric import api as fabric_api - ip = ctx.target.instance.runtime_properties.get('ssh_public_ip') + ip = ctx.target.instance.runtime_properties.get(SSH_PUBLIC_IP) if not ip: + # private ip will be used in case + # when we does not have public ip ip = ctx.target.instance.runtime_properties['ip'] + port = ctx.target.instance.runtime_properties.get(SSH_PORT, 22) ctx.logger.info("Using ip '{0}'.".format(ip)) for i in range(30): ctx.logger.info("Wait for boot '{0}'.".format(i)) try: - with fabric_api.settings(host_string=ip, warn_only=True, - abort_on_prompts=True): + with fabric_api.settings( + host_string=ip, port=port, warn_only=True, + abort_on_prompts=True + ): fabric_api.run('id') time.sleep(5) except SystemExit: diff --git a/system_tests/__init__.py b/system_tests/__init__.py index 1da0114..bd93320 100644 --- a/system_tests/__init__.py +++ b/system_tests/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from pkgutil import extend_path diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 22882c5..90b4867 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cosmo_tester.framework.handlers import ( BaseHandler, diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index c3fcb00..5afab65 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from testconfig import config import mock diff --git a/tests/integration/run_all_tests.py b/tests/integration/run_all_tests.py index 158932e..0364a52 100644 --- a/tests/integration/run_all_tests.py +++ b/tests/integration/run_all_tests.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import nose import os diff --git a/tests/integration/test_combined.py b/tests/integration/test_combined.py index 4e2548e..6965669 100644 --- a/tests/integration/test_combined.py +++ b/tests/integration/test_combined.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import contextlib import ipaddress diff --git a/tests/integration/test_network_plugin.py b/tests/integration/test_network_plugin.py index d0fb222..3529577 100644 --- a/tests/integration/test_network_plugin.py +++ b/tests/integration/test_network_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import os import mock diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index aaa83d6..65c5d56 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import random diff --git a/tests/syntax_check.py b/tests/syntax_check.py index 56db7b9..918ef2b 100644 --- a/tests/syntax_check.py +++ b/tests/syntax_check.py @@ -1,3 +1,17 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # Simple syntax check for blueprints and json examples import yaml diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 01a0540..d3bac29 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -8,19 +8,50 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest from cloudify import mocks as cfy_mocks -from network_plugin import BUSY_MESSAGE, NAT_ROUTED import network_plugin network_plugin.GATEWAY_TRY_COUNT = 2 network_plugin.GATEWAY_TIMEOUT = 1 +class MockToscaCloudifyContext(cfy_mocks.MockCloudifyContext): + """updated mock for use with tosca""" + + _local = False + + @property + def local(self): + return self._local + + _internal = None + + @property + def internal(self): + return self._internal + + _nodes = None + + @property + def nodes(self): + return self._nodes + + +class MockToscaNodeInstanceContext(cfy_mocks.MockNodeInstanceContext): + """node instance mock for use with tosca""" + + _relationships = None + + @property + def relationships(self): + return self._relationships + + class TestBase(unittest.TestCase): ERROR_PLACE = "ERROR_MESSAGE_PLACE_HOLDER" @@ -47,7 +78,7 @@ def set_services_conf_result(self, gateway, result): def set_gateway_busy(self, gateway): message = gateway.response.content message = message.replace( - self.ERROR_PLACE, BUSY_MESSAGE + self.ERROR_PLACE, network_plugin.BUSY_MESSAGE ) gateway.response.content = message @@ -175,7 +206,9 @@ def set_network_routed_in_client(self, fake_client): """ set any network as routed """ - network = self.generate_fake_client_network(NAT_ROUTED) + network = self.generate_fake_client_network( + network_plugin.NAT_ROUTED + ) fake_client.get_network = mock.MagicMock(return_value=network) def generate_fake_client_disk(self, name="some_disk"): @@ -328,7 +361,7 @@ def generate_relation_context(self): target = mock.Mock() target.node = mock.Mock() target.instance.runtime_properties = {} - fake_ctx = cfy_mocks.MockCloudifyContext( + fake_ctx = MockToscaCloudifyContext( source=source, target=target ) return fake_ctx @@ -338,14 +371,6 @@ def generate_node_context( runtime_properties=None ): - class MockInstanceContext(cfy_mocks.MockNodeInstanceContext): - - self._relationships = None - - @property - def relationships(self): - return self._relationships - if not properties: properties = { 'management_network': '_management_network', @@ -357,7 +382,7 @@ def relationships(self): runtime_properties = { 'vcloud_vapp_name': 'vapp_name' } - fake_ctx = cfy_mocks.MockCloudifyContext( + fake_ctx = MockToscaCloudifyContext( node_id='test', node_name='test', properties=properties, @@ -365,7 +390,7 @@ def relationships(self): runtime_properties=runtime_properties ) - fake_ctx._instance = MockInstanceContext( + fake_ctx._instance = MockToscaNodeInstanceContext( fake_ctx.instance._id, fake_ctx.instance._runtime_properties ) diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index e0894d3..dabc3d0 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 538c9c6..c2fd9db 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 706bc2d..491418c 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import unittest import mock diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 64ea473..69852a5 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 109db43..67e3515 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 379a582..685ed32 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 307dd6e..e553792 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest @@ -304,7 +304,8 @@ def test_create_ip_range(self): } fake_ctx._source.node.properties = { 'vcloud_config': { - 'vdc': 'some_org' + 'org': 'some_org', + 'vdc': 'some_vdc' } } fake_ctx._target.instance.runtime_properties = {} @@ -329,7 +330,7 @@ def test_create_ip_range(self): public_nat._create_ip_range(fake_client, gate), '127.1.1.100 - 127.1.1.200' ) - fake_client.get_networks.assert_called_with("some_org") + fake_client.get_networks.assert_called_with("some_vdc") # network from gate gate.get_dhcp_pools = mock.MagicMock(return_value=[ self.genarate_pool( diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index ad55e63..a4b67d9 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index ecc4fb5..85e6acd 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 7b42040..f8b0602 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_server_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py similarity index 97% rename from tests/unittests/test_mock_server_plugin_volume.py rename to tests/unittests/test_mock_storage_plugin_volume.py index 5bf11e4..442b877 100644 --- a/tests/unittests/test_mock_server_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest @@ -23,7 +23,7 @@ import network_plugin -class ServerPluginServerMockTestCase(test_mock_base.TestBase): +class StoaragePluginVolumeMockTestCase(test_mock_base.TestBase): # vapp name used for tests VAPPNAME = "some_other" @@ -40,7 +40,7 @@ def test_creation_validation_external_resource(self): } } ) - # use external without resorse_id + # use external without resource_id with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 320e674..3439227 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 725cc6e..a63f253 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import mock import unittest diff --git a/tests/unittests/test_mock_vcloud_plugin_common_workflows.py b/tests/unittests/test_mock_vcloud_plugin_common_workflows.py new file mode 100644 index 0000000..b340ffe --- /dev/null +++ b/tests/unittests/test_mock_vcloud_plugin_common_workflows.py @@ -0,0 +1,98 @@ +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from tests.unittests import test_mock_base +import vcloud_plugin_common +import vcloud_plugin_common.workflows + + +class VcloudPluginCommonWorkflowsMockTestCase(test_mock_base.TestBase): + + def _generate_instance(self): + fake_instance = mock.Mock() + fake_instance._node_instance = { + 'runtime_properties': { + }, + 'version': None + } + fake_instance.id = "fake_instance" + return fake_instance + + def check_instance(self, call_function, fake_instance): + call_function.assert_called_with( + fake_instance._node_instance + ) + # check for installed token and url + self.assertEqual( + fake_instance._node_instance, { + 'runtime_properties': { + vcloud_plugin_common.ORG_URL: 'org_url', + vcloud_plugin_common.SESSION_TOKEN: 'token' + }, + 'version': 0 + } + ) + + def test_update(self): + """check update logic""" + fake_ctx = self.generate_node_context() + fake_instance = self._generate_instance() + call_function = mock.MagicMock() + with mock.patch( + 'vcloud_plugin_common.workflows.update_node_instance', + call_function + ): + vcloud_plugin_common.workflows.update( + fake_ctx, fake_instance, "token", "org_url" + ) + self.check_instance(call_function, fake_instance) + # use local version + fake_ctx._local = True + internal = mock.MagicMock() + update_call = mock.MagicMock() + internal.handler.storage.update_node_instance = update_call + fake_ctx._internal = internal + vcloud_plugin_common.workflows.update( + fake_ctx, fake_instance, "token", "org_url" + ) + update_call.assert_called_with( + 'fake_instance', 0, { + 'org_url': 'org_url', + 'session_token': 'token' + }, None + ) + + def test_get_all_nodes_instances(self): + """update all instances in context""" + fake_ctx = self.generate_node_context() + fake_instance = self._generate_instance() + call_function = mock.MagicMock() + # create fake node with all prpoerties + fake_node = mock.MagicMock() + fake_node.properties = { + vcloud_plugin_common.VCLOUD_CONFIG: 'some_magic_here' + } + fake_node.instances = [fake_instance] + fake_ctx._nodes = [fake_node] + # try to run + with mock.patch( + 'vcloud_plugin_common.workflows.update_node_instance', + call_function + ): + vcloud_plugin_common.workflows._get_all_nodes_instances( + fake_ctx, "token", "org_url" + ) + self.check_instance(call_function, fake_instance) diff --git a/tox.ini b/tox.ini index 282784b..20c84e6 100644 --- a/tox.ini +++ b/tox.ini @@ -16,11 +16,11 @@ commands = nosetests -x -s --tc=ondemand: tests/integration {posargs} commands = nosetests -x -s --tc=subscription: tests/integration {posargs} [testenv:py27-unittests] -commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin +commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin --cover-package=storage_plugin [testenv:pep8] commands= - flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts -ignore = + flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts storage_plugin +ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 9121bbd..3d80df2 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -8,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import atexit from functools import wraps diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index 0bcf6d5..0202ffc 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -1,29 +1,31 @@ -######## -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify.decorators import workflow -import cloudify.plugins.workflows as default_workflow from cloudify.manager import update_node_instance -from vcloud_plugin_common import (SESSION_TOKEN, ORG_URL, VCLOUD_CONFIG) +import cloudify.plugins.workflows as default_workflow +import vcloud_plugin_common def update(ctx, instance, token, org_url): + """updete token and url in instance""" node_instance = instance._node_instance rt_properties = node_instance['runtime_properties'] - rt_properties.update({SESSION_TOKEN: token, - ORG_URL: org_url}) + rt_properties.update({ + vcloud_plugin_common.SESSION_TOKEN: token, + vcloud_plugin_common.ORG_URL: org_url + }) version = node_instance['version'] node_instance['version'] = version if version else 0 if ctx.local: @@ -37,11 +39,13 @@ def update(ctx, instance, token, org_url): def _get_all_nodes_instances(ctx, token, org_url): + """return all instances from context nodes""" node_instances = set() for node in ctx.nodes: - for instance in node.instances: - if token and org_url and VCLOUD_CONFIG in node.properties: - update(ctx, instance, token, org_url) + if vcloud_plugin_common.VCLOUD_CONFIG in node.properties: + for instance in node.instances: + if token and org_url: + update(ctx, instance, token, org_url) node_instances.add(instance) return node_instances From 8194f826a143efe5f859e43508879a8a6fc054c7 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 11 Sep 2015 13:37:55 +0400 Subject: [PATCH 119/228] CFY-3585 User session token for login in standalone cloudify manager and local executions --- tests/integration/test_server_plugin.py | 2 +- ...st_mock_vcloud_plugin_common_vca_client.py | 27 +++- vcloud_plugin_common/__init__.py | 150 +++++++++--------- 3 files changed, 95 insertions(+), 84 deletions(-) diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index 65c5d56..e9cad58 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -22,7 +22,7 @@ from cloudify import mocks as cfy_mocks from server_plugin import server -from server_plugin import volume +from storage_plugin import volume from server_plugin import vdc from tests.integration import TestCase from cloudify.mocks import MockCloudifyContext diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index a63f253..079186e 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -53,9 +53,14 @@ def _run( with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - return client._subscription_login( - url, username, password, token, service, - org_name) + with mock.patch( + 'pyvcloud.vcloudair.VCS', + mock.MagicMock()): + with mock.patch('vcloud_plugin_common.local_session_token', + None): + return client._subscription_login( + url, username, password, token, service, + org_name) # can't login with token with self.assertRaises(cfy_exc.NonRecoverableError): _run( @@ -123,9 +128,13 @@ def _run( with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - return client._ondemand_login( - url, username, password, token, instance_id) - + with mock.patch( + 'pyvcloud.vcloudair.VCS', + mock.MagicMock()): + with mock.patch('vcloud_plugin_common.local_session_token', + None): + return client._ondemand_login( + url, username, password, token, instance_id) # bad case without instance with self.assertRaises(cfy_exc.NonRecoverableError): _run( @@ -375,7 +384,6 @@ def loginc_check(fake_client): 'url': 'url', 'username': 'username' }) - with mock.patch( 'time.sleep', mock.MagicMock(return_value=None) @@ -387,7 +395,10 @@ def loginc_check(fake_client): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - loginc_check(fake_client) + with mock.patch( + 'pyvcloud.vcloudair.VCS', + mock.MagicMock()): + loginc_check(fake_client) def test_get(self): client = vcloud_plugin_common.VcloudAirClient() diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 3d80df2..41da980 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -72,6 +72,9 @@ ORG_URL = 'org_url' VCLOUD_CONFIG = 'vcloud_config' +local_session_token = None +local_org_url = None + def transform_resource_name(res, ctx): """ @@ -200,53 +203,44 @@ def _subscription_login(self, url, username, password, token, service, version=version) if session_token: - if session_login(vca, org_url, session_token, version): + vca = login_to_vca_with_token(vca, org_url, session_token, version) + if vca: return vca else: raise cfy_exc.NonRecoverableError("Invalid session credentials") + global local_org_url + global local_session_token + if local_session_token: + vca = login_to_vca_with_token(vca, local_org_url, + local_session_token, version) + if vca: + return vca + # login with token if token: - for _ in range(LOGIN_RETRY_NUM): - logined = vca.login(token=token) - if logined is False: - ctx.logger.info("Login using token failed.") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login using token successful.") - break + logined = login_with_retry(vca.login, [None, token], + "Login using token") # outdated token, try login by password if logined is False and password: - for _ in range(LOGIN_RETRY_NUM): - logined = vca.login(password) - if logined is False: - ctx.logger.info("Login using password failed. Retrying...") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login using password successful.") - break + logined = login_with_retry(vca.login, [password, None], + "Login using token") # can't login to system at all if logined is False: raise cfy_exc.NonRecoverableError("Invalid login credentials") - for _ in range(LOGIN_RETRY_NUM): - vdc_logined = vca.login_to_org(service, org_name) - if vdc_logined is False: - ctx.logger.info("Login to VDC failed. Retrying...") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login to VDC successful.") - break + vdc_logined = login_with_retry(vca.login_to_org, [service, org_name], + "Login to org") # we can login to system, # but have some troubles with login to organization, # lets retry later - if vdc_logined is False: + if vdc_logined: + local_session_token = vca.vcloud_session.token + local_org_url = vca.vcloud_session.org_url + else: raise cfy_exc.RecoverableError(message="Could not login to VDC", retry_after=RELOGIN_TIMEOUT) @@ -273,36 +267,30 @@ def get_instance(vca, instance_id): vca = vcloudair.VCA( url, username, service_type=ONDEMAND_SERVICE_TYPE, version=version) - if session_token: - if session_login(vca, org_url, session_token, version): + vca = login_to_vca_with_token(vca, org_url, session_token, version) + if vca: return vca else: raise cfy_exc.NonRecoverableError("Invalid session credentials") + global local_org_url + global local_session_token + if local_session_token: + vca = login_to_vca_with_token(vca, local_org_url, + local_session_token, version) + if vca: + return vca + # login with token if token: - for _ in range(LOGIN_RETRY_NUM): - logined = vca.login(token=token) - if logined is False: - ctx.logger.info("Login using token failed.") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login using token successful.") - break + logined = login_with_retry(vca.login, [None, token], + "Login using token") # outdated token, try login by password if logined is False and password: - for _ in range(LOGIN_RETRY_NUM): - logined = vca.login(password) - if logined is False: - ctx.logger.info("Login using password failed. Retrying...") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login using password successful.") - break + logined = login_with_retry(vca.login, [password, None], + "Login using token") # can't login to system at all if logined is False: @@ -313,36 +301,24 @@ def get_instance(vca, instance_id): raise cfy_exc.NonRecoverableError( "Instance {0} could not be found.".format(instance_id)) - for _ in range(LOGIN_RETRY_NUM): - instance_logined = vca.login_to_instance( - instance_id, password, token, None) - if instance_logined is False: - ctx.logger.info("Login to instance failed. Retrying...") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login to instance successful.") - break - - for _ in range(LOGIN_RETRY_NUM): - - instance_logined = vca.login_to_instance( - instance_id, - None, - vca.vcloud_session.token, - vca.vcloud_session.org_url) - if instance_logined is False: - ctx.logger.info("Login to instance failed. Retrying...") - time.sleep(RELOGIN_TIMEOUT) - continue - else: - ctx.logger.info("Login to instance successful.") - break + instance_logined = login_with_retry(vca.login_to_instance, + [instance_id, password], + "Login to instance with password") + + if instance_logined: + instance_logined = login_with_retry(vca.login_to_instance, + [instance_id, None, + vca.vcloud_session.token, + vca.vcloud_session.org_url], + "Login to instance with token") # we can login to system, # but have some troubles with login to instance, # lets retry later - if instance_logined is False: + if instance_logined: + local_session_token = vca.vcloud_session.token + local_org_url = vca.vcloud_session.org_url + else: raise cfy_exc.RecoverableError( message="Could not login to instance", retry_after=RELOGIN_TIMEOUT) @@ -521,3 +497,27 @@ def session_login(vca, org_url, session_token, version): ctx.logger.info("Login using session token successful.") return True return False + + +def login_to_vca_with_token(vca, org_url, session_token, version): + for _ in range(LOGIN_RETRY_NUM): + logined = session_login(vca, org_url, session_token, version) + if logined is False: + ctx.logger.info("Login using session token failed.") + time.sleep(RELOGIN_TIMEOUT) + continue + else: + return vca + + +def login_with_retry(function, arguments, message): + for _ in range(LOGIN_RETRY_NUM): + logined = function(*arguments) + if logined is False: + ctx.logger.info("{0} failed. Retrying...".format(message)) + time.sleep(RELOGIN_TIMEOUT) + continue + else: + ctx.logger.info("{0} successful.".format(message)) + return True + return False From aeb08e477158096c9c4d241985c6e55b5628170c Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 2 Sep 2015 15:21:30 +0400 Subject: [PATCH 120/228] CFY-3509 Remove SSH priv keys when they are no longer necessary CFY-3509 Update customization script CFY-3509 Search vcloud config in target node CFY-3509 use target too in get_vcloud_config CFY-3509 Reboot VM after customization. Modify remove keys function CFY-3509 Update key remove script CFY-3509 Script refactoring CFY-3509 Improve sed command CFY-3509 Fix replace string CFY-3509 Update tests CFY-3509 Add parameter for prevent key file generation --- network_plugin/keypair.py | 33 ++++--- plugin.yaml | 9 +- server_plugin/server.py | 89 +++++++++++++++---- .../test_mock_network_plugin_keypair.py | 4 +- ...est_mock_server_plugin_server_subroutes.py | 10 ++- vcloud_plugin_common/__init__.py | 8 +- 6 files changed, 118 insertions(+), 35 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 9f74fb4..511df90 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -23,6 +23,7 @@ AUTO_GENERATE = 'auto_generate' PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' +CREATE_PRIVATE_KEY_FILE = 'create_private_key_file' PATH = 'path' KEY = 'key' USER = 'user' @@ -55,33 +56,39 @@ def create(**kwargs): if ctx.node.properties.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") public, private = _generate_pair() - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = public - _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], - ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) + if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], + ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = \ ctx.node.properties.get(PUBLIC_KEY, {}).get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = \ ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY) - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ - ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) - if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() - _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], - ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) + if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ + ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) + if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() + _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], + ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @operation def delete(**kwargs): if ctx.node.properties[AUTO_GENERATE]: - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) + if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) else: if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) - del ctx.instance.runtime_properties[PRIVATE_KEY] - del ctx.instance.runtime_properties[PUBLIC_KEY] + if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) + if PRIVATE_KEY in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[PRIVATE_KEY] + if PUBLIC_KEY in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[PUBLIC_KEY] @operation diff --git a/plugin.yaml b/plugin.yaml index de51cf2..1b4696e 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -120,6 +120,8 @@ node_types: properties: auto_generate: default: false + create_private_key_file: + default: false private_key: default: {} public_key: @@ -255,8 +257,13 @@ relationships: unlink: implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair inputs: {} - cloudify.vcloud.server_connected_to_vdc: + cloudify.vcloud.delete_public_key_from_server: derived_from: cloudify.relationships.connected_to + target_interfaces: + cloudify.interfaces.relationship_lifecycle: + establish: + implementation: vcloud.server_plugin.server.remove_keys + inputs: {} workflows: scoreinstall: vcloud.vcloud_plugin_common.workflows.install diff --git a/server_plugin/server.py b/server_plugin/server.py index 83394b5..984de72 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -290,7 +290,7 @@ def configure(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Unable to find vAPP server " "by its name {0}.".format(vapp_name)) - ctx.logger.info("Using vAPP {0}".format(str(vapp))) + ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') @@ -341,6 +341,62 @@ def configure(vca_client, **kwargs): format(task, error_response(vapp))) +@operation +@with_vca_client +def remove_keys(vca_client, **kwargs): + ctx.logger.info("Remove public keys from VM.") + relationships = getattr(ctx.target.instance, 'relationships', None) + if relationships: + public_keys = [relationship.target.instance.runtime_properties['public_key'] + for relationship in relationships + if 'public_key' in + relationship.target.instance.runtime_properties] + else: + return + vdc = vca_client.get_vdc(get_vcloud_config()['vdc']) + vapp_name = ctx.target.instance.id + vapp = vca_client.get_vapp(vdc, vapp_name) + if not vapp: + raise cfy_exc.NonRecoverableError( + "Unable to find vAPP server " + "by its name {0}.".format(vapp_name)) + ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) + script = "#!/bin/sh\n" + _build_public_keys_script(public_keys, + _remove_key_script) + task = vapp.undeploy() + if not task: + raise cfy_exc.NonRecoverableError( + "Can't power off VM. {0}".format(vapp_name)) + wait_for_task(vca_client, task) + task = vapp.customize_guest_os( + vapp_name, + customization_script=script) + if not task: + raise cfy_exc.NonRecoverableError( + "Could not set guest customization parameters. {0}.". + format(error_response(vapp))) + wait_for_task(vca_client, task) + if vapp.customize_on_next_poweron(): + ctx.logger.info("Customizations successful.") + else: + raise cfy_exc.NonRecoverableError( + "Can't run customization on next power on. {0}.". + format(error_response(vapp))) + vapp = vca_client.get_vapp(vdc, vapp_name) + task = vapp.poweron() + if not task: + raise cfy_exc.NonRecoverableError( + "Can't poweron VM. {0}".format(vapp_name)) + wait_for_task(vca_client, task) + ctx.logger.info("Power on after deleting public key successful.") + + +def _remove_key_script(commands, user, ssh_dir, keys_file, public_key): + sed_template = " sed -i /{0}/d {1}" + commands.append(sed_template.format(public_key.split()[1].replace('/', '[/]'), + keys_file)) + + def _get_state(vca_client): """ check network connection availability for host @@ -408,8 +464,9 @@ def _build_script(custom, public_keys): post_script = custom.get('post_script', "") if not pre_script and not post_script and not public_keys: return None - script_executor = custom.get('script_executor', DEFAULT_EXECUTOR) - public_keys_script = _build_public_keys_script(public_keys) + script_executor = DEFAULT_EXECUTOR + public_keys_script = _build_public_keys_script(public_keys, + _add_key_script) script_template = """#!{0} echo performing customization tasks with param $1 \ at `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log @@ -443,13 +500,7 @@ def _get_connected_keypairs(): return [] -def _build_public_keys_script(public_keys): - """ - create script for update ssh keys - """ - key_commands = [] - ssh_dir_template = "{0}/{1}/.ssh" - authorized_keys_template = "{0}/authorized_keys" +def _add_key_script(commands, user, ssh_dir, keys_file, public_key): add_key_template = "echo '{0}\n' >> {1}" test_ssh_dir_template = """ if [ ! -d {1} ];then @@ -461,6 +512,18 @@ def _build_public_keys_script(public_keys): chmod 600 {2} fi """ + test_ssh_dir = test_ssh_dir_template.format(user, ssh_dir, keys_file) + commands.append(test_ssh_dir) + commands.append(add_key_template.format(public_key, keys_file)) + + +def _build_public_keys_script(public_keys, script_function): + """ + create script for update ssh keys + """ + key_commands = [] + ssh_dir_template = "{0}/{1}/.ssh" + authorized_keys_template = "{0}/authorized_keys" for key in public_keys: public_key = key.get('key') if not public_key: @@ -473,11 +536,7 @@ def _build_public_keys_script(public_keys): home = '' if user == 'root' else DEFAULT_HOME ssh_dir = ssh_dir_template.format(home, user) authorized_keys = authorized_keys_template.format(ssh_dir) - test_ssh_dir = test_ssh_dir_template.format( - user, ssh_dir, authorized_keys) - key_commands.append(test_ssh_dir) - key_commands.append( - add_key_template.format(public_key, authorized_keys)) + script_function(key_commands, user, ssh_dir, authorized_keys, public_key) return "\n".join(key_commands) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 491418c..b904570 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -52,7 +52,8 @@ def test_create(self): patcher3.start() fake_ctx = self.generate_node_context( - properties={'auto_generate': True}) + properties={'auto_generate': True, + 'create_private_key_file': True}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties self.assertEqual('~/.ssh/test_private.key', @@ -62,6 +63,7 @@ def test_create(self): fake_ctx = self.generate_node_context( properties={'auto_generate': False, + 'create_private_key_file': True, 'private_key': {'key': 'private'}}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index f8b0602..e4f4e23 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -79,20 +79,22 @@ def test_build_script(self): self.assertNotEqual(None, server._build_script(custom, [])) def test_build_public_keys_script(self): - self.assertEqual('', server._build_public_keys_script([])) + def script_fun(a, b, c, d, e): + return a.append("{}{}{}{}".format(b, c, d, e)) + self.assertEqual('', server._build_public_keys_script([], script_fun)) self.assertEqual('', server._build_public_keys_script([ {'key': False} - ])) + ], script_fun)) self.assertNotEqual('', server._build_public_keys_script([ {'key': True} - ])) + ], script_fun)) self.assertNotEqual('', server._build_public_keys_script([ { 'key': True, 'user': 'test', 'home': 'home' } - ])) + ], script_fun)) def test_creation_validation_empty_settings(self): fake_ctx = cfy_mocks.MockCloudifyContext( diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 3d80df2..caf8d5a 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -412,7 +412,11 @@ def wrapper(*args, **kw): prop = ctx.instance.runtime_properties elif ctx.type == context.RELATIONSHIP_INSTANCE: config = ctx.source.node.properties.get(VCLOUD_CONFIG) - prop = ctx.source.instance.runtime_properties + if config: + prop = ctx.source.instance.runtime_properties + else: + config = ctx.target.node.properties.get(VCLOUD_CONFIG) + prop = ctx.target.instance.runtime_properties else: raise cfy_exc.NonRecoverableError("Unsupported context") if config and prop: @@ -465,6 +469,8 @@ def get_vcloud_config(): config = ctx.node.properties.get(VCLOUD_CONFIG) elif ctx.type == context.RELATIONSHIP_INSTANCE: config = ctx.source.node.properties.get(VCLOUD_CONFIG) + if not config: + config = ctx.target.node.properties.get(VCLOUD_CONFIG) else: raise cfy_exc.NonRecoverableError("Unsupported context") static_config = Config().get() From b41243cbb3eb87a7d0403ccc6b14fa7d2edf5e42 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 16 Sep 2015 10:57:05 +0300 Subject: [PATCH 121/228] CFY-2841: add vdc test coverage and comments to code --- network_plugin/__init__.py | 12 +- network_plugin/security_group.py | 1 + server_plugin/vdc.py | 24 ++- .../unittests/test_mock_server_plugin_vdc.py | 200 ++++++++++++++++++ vcloud_plugin_common/workflows.py | 2 +- 5 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 tests/unittests/test_mock_server_plugin_vdc.py diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 95ed62d..466fcf4 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -289,6 +289,7 @@ def del_ondemand_public_ip(vca_client, gateway, ip, ctx): try to deallocate public ip """ ctx.logger.info("Try to deallocate public IP {0}".format(ip)) + wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.deallocate_public_ip(ip) if task: wait_for_task(vca_client, task) @@ -375,8 +376,15 @@ def wrapper(*args, **kw): ctx.logger.info("Lock gateway.") update_parameters(ctx, True) vca_client = kw['vca_client'] - gateway_name = get_vcloud_config()['edge_gateway'] - wait_for_gateway(vca_client, gateway_name, ctx) + gateway_name = get_vcloud_config().get('edge_gateway') + if gateway_name: + wait_for_gateway(vca_client, gateway_name, ctx) + else: + # we need gateway_name from vcloud for use this functionality + ctx.logger.info( + "'edge_gateway' in vcloud_config is empty." + + " Can't check state of gateway correctly." + ) try: result = f(*args, **kw) finally: diff --git a/network_plugin/security_group.py b/network_plugin/security_group.py index bec924b..b6e4a51 100644 --- a/network_plugin/security_group.py +++ b/network_plugin/security_group.py @@ -139,6 +139,7 @@ def _rule_operation(operation, vca_client): ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) + ctx.logger.info("Saving security group configuration") return save_gateway_configuration(gateway, vca_client, ctx) diff --git a/server_plugin/vdc.py b/server_plugin/vdc.py index a77853c..a833e0e 100644 --- a/server_plugin/vdc.py +++ b/server_plugin/vdc.py @@ -31,6 +31,19 @@ @operation @with_vca_client def creation_validation(vca_client, **kwargs): + """check params + + e.g.: + { + 'name': 'not_existed' + } + or: + { + 'use_external_resource': True, + 'resource_id': 'not_existed' + } + + """ if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): if not ctx.node.properties.get(RESOURCE_ID): raise cfy_exc.NonRecoverableError( @@ -49,17 +62,21 @@ def creation_validation(vca_client, **kwargs): if vdc: raise cfy_exc.NonRecoverableError( "VDC '{0}' already exists." - .format(res_id)) + .format(vdc_name)) @operation @with_vca_client def create(vca_client, **kwargs): + """create vdc""" config = get_vcloud_config() + # Subscription service does not support vdc create, + # you must use predefined vdc only if is_subscription(config['service_type']): raise cfy_exc.NonRecoverableError( "Unable create VDC on subscription service.") if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + # use external resource, does not create anything res_id = ctx.node.properties[RESOURCE_ID] ctx.instance.runtime_properties[VDC_NAME] = res_id vdc = vca_client.get_vdc(res_id) @@ -70,6 +87,7 @@ def create(vca_client, **kwargs): ctx.logger.info( "External resource {0} has been used".format(res_id)) else: + # create new vdc vdc_name = ctx.node.properties.get('name') if not vdc_name: raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") @@ -83,15 +101,19 @@ def create(vca_client, **kwargs): @operation @with_vca_client def delete(vca_client, **kwargs): + """delete vdc""" + # external resource - no actions if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): ctx.logger.info('Not deleting VDC since an external VDC is ' 'being used') else: + # created in our workflow vdc_name = ctx.node.properties.get('name') status, task = vca_client.delete_vdc(vdc_name) if not status: raise cfy_exc.NonRecoverableError("Could not delete VDC: {0}" .format(error_response(vca_client))) wait_for_task(vca_client, task) + # clean up runtime_properties if VDC_NAME in ctx.instance.runtime_properties: del ctx.instance.runtime_properties[VDC_NAME] diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py new file mode 100644 index 0000000..f52eb19 --- /dev/null +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -0,0 +1,200 @@ +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from cloudify import exceptions as cfy_exc +from server_plugin import vdc +import vcloud_plugin_common +from tests.unittests import test_mock_base + + +class ServerPluginVdcMockTestCase(test_mock_base.TestBase): + + def test_creation_validation(self): + """check validation for vdc operations""" + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + fake_ctx = self.generate_node_context( + properties={} + ) + # no vdc name + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.creation_validation(ctx=fake_ctx) + # name exist but someone already created this vdc + fake_ctx = self.generate_node_context( + properties={ + 'name': 'not_existed' + } + ) + fake_client.get_vdc = mock.MagicMock( + return_value=mock.MagicMock() + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.creation_validation(ctx=fake_ctx) + fake_client.get_vdc.assert_called_with('not_existed') + # everthing fine + fake_client.get_vdc = mock.MagicMock(return_value=None) + vdc.creation_validation(ctx=fake_ctx) + # external but without name + fake_ctx = self.generate_node_context( + properties={ + 'use_external_resource': True + } + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.creation_validation(ctx=fake_ctx) + # use unexisted vdc + fake_ctx = self.generate_node_context( + properties={ + 'use_external_resource': True, + 'resource_id': 'not_existed' + } + ) + fake_client.get_vdc = mock.MagicMock(return_value=None) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.creation_validation(ctx=fake_ctx) + fake_client.get_vdc.assert_called_with('not_existed') + # exist everything + fake_client.get_vdc = mock.MagicMock( + return_value=mock.MagicMock() + ) + vdc.creation_validation(ctx=fake_ctx) + fake_client.get_vdc.assert_called_with('not_existed') + + def test_create(self): + """check vdc creation operation""" + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + # tried to create new vdc on subscription + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + } + } + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.create(ctx=fake_ctx) + # use ondemand + # use external resource without vdc + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + }, + 'use_external_resource': True, + 'resource_id': 'not_existed' + } + ) + fake_client.get_vdc = mock.MagicMock(return_value=None) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.create(ctx=fake_ctx) + fake_client.get_vdc.assert_called_with('not_existed') + # successful for create on external resource + fake_client.get_vdc = mock.MagicMock( + return_value=mock.MagicMock() + ) + vdc.create(ctx=fake_ctx) + # no name for vdc + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + }, + 'use_external_resource': False, + } + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.create(ctx=fake_ctx) + # create new vdc for deployment + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + }, + 'use_external_resource': False, + 'name': "something" + } + ) + # no task returned + fake_client.create_vdc = mock.MagicMock( + return_value=None + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.create(ctx=fake_ctx) + # everything fine + fake_client.create_vdc = mock.MagicMock( + return_value=self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) + vdc.create(ctx=fake_ctx) + + def test_delete(self): + """check vdc deletion operation""" + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + # external resorce + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + }, + 'use_external_resource': True, + 'resource_id': 'not_existed' + } + ) + vdc.delete(ctx=fake_ctx) + # return fail from delete vdc + fake_client.delete_vdc = mock.MagicMock( + return_value=(False, None) + ) + fake_ctx = self.generate_node_context( + properties={ + 'vcloud_config': { + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + }, + 'use_external_resource': False, + 'name': "something" + }, + runtime_properties={ + vdc.VDC_NAME: "something" + } + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + vdc.delete(ctx=fake_ctx) + fake_client.delete_vdc.assert_called_with("something") + self.assertTrue( + vdc.VDC_NAME in fake_ctx.instance.runtime_properties + ) + # succesful delete + fake_client.delete_vdc = mock.MagicMock( + return_value=(True, self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + )) + ) + vdc.delete(ctx=fake_ctx) + self.assertFalse( + vdc.VDC_NAME in fake_ctx.instance.runtime_properties + ) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index 0202ffc..ec66ca0 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -19,7 +19,7 @@ def update(ctx, instance, token, org_url): - """updete token and url in instance""" + """update token and url in instance""" node_instance = instance._node_instance rt_properties = node_instance['runtime_properties'] rt_properties.update({ From 5754f7f8f278314393d0cd73a0727722f8fc4278 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 16 Sep 2015 11:55:45 +0300 Subject: [PATCH 122/228] CFY-2841: fix version in plugin --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 6558285..38b3193 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.2.1m5.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip node_types: cloudify.vcloud.nodes.Server: From bf53544d060e5b2b86ed683bf3a4cebcb775b36c Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 17 Sep 2015 10:06:57 +0400 Subject: [PATCH 123/228] More strict validation for creating key file. --- network_plugin/keypair.py | 27 ++++++++++--------- .../test_mock_network_plugin_keypair.py | 7 ++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 511df90..118a867 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -23,7 +23,7 @@ AUTO_GENERATE = 'auto_generate' PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' -CREATE_PRIVATE_KEY_FILE = 'create_private_key_file' +CREATE_PRIVATE_KEY_FILE = 'create_file' PATH = 'path' KEY = 'key' USER = 'user' @@ -58,7 +58,7 @@ def create(**kwargs): public, private = _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = public - if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @@ -67,7 +67,7 @@ def create(**kwargs): ctx.node.properties.get(PUBLIC_KEY, {}).get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = \ ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY) - if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): + if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): @@ -79,12 +79,12 @@ def create(**kwargs): @operation def delete(**kwargs): if ctx.node.properties[AUTO_GENERATE]: - if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) + if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + _delete_key_file(ctx.instance.runtime_properties) else: if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): - if ctx.node.properties.get(CREATE_PRIVATE_KEY_FILE): - _delete_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH]) + if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + _delete_key_file(ctx.instance.runtime_properties) if PRIVATE_KEY in ctx.instance.runtime_properties: del ctx.instance.runtime_properties[PRIVATE_KEY] if PUBLIC_KEY in ctx.instance.runtime_properties: @@ -94,11 +94,12 @@ def delete(**kwargs): @operation def server_connect_to_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties + target_rt_properties = ctx.target.instance.runtime_properties if SSH_KEY not in host_rt_properties: host_rt_properties[SSH_KEY] = {} - host_rt_properties[SSH_KEY][PATH] = ctx.target.instance.runtime_properties[PRIVATE_KEY][PATH] - host_rt_properties[SSH_KEY][KEY] = ctx.target.instance.runtime_properties[PRIVATE_KEY][KEY] - host_rt_properties[SSH_KEY][USER] = ctx.target.instance.runtime_properties[PUBLIC_KEY][USER] + host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) + host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) + host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) @operation @@ -131,5 +132,7 @@ def _save_key_file(path, value): content_file.write(value) -def _delete_key_file(path): - os.unlink(os.path.expanduser(path)) +def _delete_key_file(properties): + if PRIVATE_KEY in properties and PATH in properties[PRIVATE_KEY]: + path = properties[PRIVATE_KEY][PATH] + os.unlink(os.path.expanduser(path)) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index b904570..24a8bf4 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -53,7 +53,8 @@ def test_create(self): fake_ctx = self.generate_node_context( properties={'auto_generate': True, - 'create_private_key_file': True}) + 'private_key' :{ + 'create_file': True}}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties self.assertEqual('~/.ssh/test_private.key', @@ -63,8 +64,8 @@ def test_create(self): fake_ctx = self.generate_node_context( properties={'auto_generate': False, - 'create_private_key_file': True, - 'private_key': {'key': 'private'}}) + 'private_key': {'key': 'private', + 'create_file': True}}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties self.assertEqual('~/.ssh/test_private.key', From 0115f104899ccab0a558a5be1bb964bd7e3011fb Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 17 Sep 2015 10:49:07 +0400 Subject: [PATCH 124/228] Add lost relationship delete_public_key_from_server --- plugin.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 38b3193..ccabb8b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -257,8 +257,14 @@ relationships: inputs: {} cloudify.vcloud.server_connected_to_vdc: derived_from: cloudify.relationships.connected_to + cloudify.vcloud.delete_public_key_from_server: + derived_from: cloudify.relationships.connected_to + target_interfaces: + cloudify.interfaces.relationship_lifecycle: + establish: + implementation: vcloud.server_plugin.server.remove_keys + inputs: {} workflows: scoreinstall: vcloud.vcloud_plugin_common.workflows.install - scoreuninstall: vcloud.vcloud_plugin_common.workflows.uninstall From 61116f553346c6cce5981e22acc5de95f3c7b1b8 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 17 Sep 2015 13:00:34 +0400 Subject: [PATCH 125/228] Search vapp be name in property --- server_plugin/server.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server_plugin/server.py b/server_plugin/server.py index 984de72..3349261 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -357,9 +357,12 @@ def remove_keys(vca_client, **kwargs): vapp_name = ctx.target.instance.id vapp = vca_client.get_vapp(vdc, vapp_name) if not vapp: - raise cfy_exc.NonRecoverableError( - "Unable to find vAPP server " - "by its name {0}.".format(vapp_name)) + vapp_name = ctx.target.node.properties['server'].get('name', '') + vapp = vca_client.get_vapp(vdc, vapp_name) + if not vapp: + raise cfy_exc.NonRecoverableError( + "Unable to find vAPP server " + "by its name {0}.".format(vapp_name)) ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) script = "#!/bin/sh\n" + _build_public_keys_script(public_keys, _remove_key_script) From 81e9bf3a9cca702af11f0d7ed17d25611b9a1380 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 23 Sep 2015 11:33:05 +0400 Subject: [PATCH 126/228] Fix for creating node instance set --- vcloud_plugin_common/workflows.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index ec66ca0..c48a3ad 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -42,10 +42,11 @@ def _get_all_nodes_instances(ctx, token, org_url): """return all instances from context nodes""" node_instances = set() for node in ctx.nodes: - if vcloud_plugin_common.VCLOUD_CONFIG in node.properties: - for instance in node.instances: - if token and org_url: - update(ctx, instance, token, org_url) + for instance in node.instances: + if (vcloud_plugin_common.VCLOUD_CONFIG in node.properties + and token + and org_url): + update(ctx, instance, token, org_url) node_instances.add(instance) return node_instances From 243afb7a6f7ade5f810cdfb4d7fdb3b19ec1d6b8 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 16 Sep 2015 16:44:53 +0400 Subject: [PATCH 127/228] CFY-3598 Update integration tests --- README.md | 5 + manager_blueprint/inputs.yaml.example | 2 +- storage_plugin/volume.py | 6 +- tests/integration/__init__.py | 116 ++++- .../blueprints/floatingip_connect.yaml | 18 + tests/integration/blueprints/header.yaml | 97 ++++ tests/integration/blueprints/inputs.yaml | 5 + .../blueprints/keypair_connect.yaml | 19 + .../blueprints/keypair_create.yaml | 6 + tests/integration/blueprints/network_new.yaml | 18 + .../blueprints/network_use_external.yaml | 6 + .../blueprints/publicnat_to_network.yaml | 18 + .../blueprints/publicnat_to_server.yaml | 33 ++ .../blueprints/security_group_create.yaml | 41 ++ .../blueprints/server_remove_keys.yaml | 27 ++ .../blueprints/server_to_network.yaml | 20 + .../blueprints/server_to_port.yaml | 33 ++ .../blueprints/server_use_external.yaml | 8 + .../blueprints/server_with_name.yaml | 15 + .../blueprints/server_without_name.yaml | 9 + tests/integration/blueprints/vdc_new.yaml | 5 + .../blueprints/vdc_use_external.yaml | 6 + .../integration/blueprints/volume_attach.yaml | 29 ++ tests/integration/blueprints/volume_new.yaml | 7 + .../blueprints/volume_use_external.yaml | 6 + tests/integration/run_all_tests.py | 29 -- tests/integration/test_combined.py | 216 --------- tests/integration/test_network_plugin.py | 312 ++---------- tests/integration/test_server_plugin.py | 456 +++--------------- tests/integration/test_storage_plugin.py | 43 ++ .../test_mock_network_plugin_keypair.py | 3 +- 31 files changed, 698 insertions(+), 916 deletions(-) create mode 100644 tests/integration/blueprints/floatingip_connect.yaml create mode 100644 tests/integration/blueprints/header.yaml create mode 100644 tests/integration/blueprints/inputs.yaml create mode 100644 tests/integration/blueprints/keypair_connect.yaml create mode 100644 tests/integration/blueprints/keypair_create.yaml create mode 100644 tests/integration/blueprints/network_new.yaml create mode 100644 tests/integration/blueprints/network_use_external.yaml create mode 100644 tests/integration/blueprints/publicnat_to_network.yaml create mode 100644 tests/integration/blueprints/publicnat_to_server.yaml create mode 100644 tests/integration/blueprints/security_group_create.yaml create mode 100644 tests/integration/blueprints/server_remove_keys.yaml create mode 100644 tests/integration/blueprints/server_to_network.yaml create mode 100644 tests/integration/blueprints/server_to_port.yaml create mode 100644 tests/integration/blueprints/server_use_external.yaml create mode 100644 tests/integration/blueprints/server_with_name.yaml create mode 100644 tests/integration/blueprints/server_without_name.yaml create mode 100644 tests/integration/blueprints/vdc_new.yaml create mode 100644 tests/integration/blueprints/vdc_use_external.yaml create mode 100644 tests/integration/blueprints/volume_attach.yaml create mode 100644 tests/integration/blueprints/volume_new.yaml create mode 100644 tests/integration/blueprints/volume_use_external.yaml delete mode 100644 tests/integration/run_all_tests.py delete mode 100644 tests/integration/test_combined.py create mode 100644 tests/integration/test_storage_plugin.py diff --git a/README.md b/README.md index 5821223..c84950f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ tosca-vcloud-plugin ## Running Integration Tests +First, you must prepare vCloud enviroment. +Integration tests uses ondemand and subscription services. +On each service must be at least one existent network. +Firewall must be disabled, or allow by default. + Create virtual environment and install plugin in dev-mode ``` virtualenv venv && source venv/bin/activate diff --git a/manager_blueprint/inputs.yaml.example b/manager_blueprint/inputs.yaml.example index d4dab0c..c9b5abe 100644 --- a/manager_blueprint/inputs.yaml.example +++ b/manager_blueprint/inputs.yaml.example @@ -1,6 +1,6 @@ vcloud_username: some_user vcloud_password: some_password -vcloud_url: https://iam.vchs.vmware.com +vcloud_url: https://vca.vmware.com vcloud_service: VDC vcloud_org: VDC vcloud_vdc: VDC diff --git a/storage_plugin/volume.py b/storage_plugin/volume.py index 0c79f78..d02a076 100644 --- a/storage_plugin/volume.py +++ b/storage_plugin/volume.py @@ -41,10 +41,10 @@ def create_volume(vca_client, **kwargs): vdc_name = get_vcloud_config()['vdc'] name = ctx.node.properties['volume']['name'] size = ctx.node.properties['volume']['size'] - size_in_Mb = size * 1024 * 1024 + size_in_bytes = size * 1024 * 1024 ctx.logger.info("Create volume '{0}' to '{1}' with size {2}Mb." - .format(name, vdc_name, size_in_Mb)) - success, disk = vca_client.add_disk(vdc_name, name, size_in_Mb) + .format(name, vdc_name, size)) + success, disk = vca_client.add_disk(vdc_name, name, size_in_bytes) if success: wait_for_task(vca_client, disk.get_Tasks()[0]) ctx.logger.info("Volume node '{0}' has been created".format(name)) diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index 5afab65..4a95240 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -14,15 +14,28 @@ from testconfig import config import mock -import time import unittest - +import shutil +import os +import yaml +import tempfile +import requests +import time +from functools import wraps +from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType from cloudify import mocks as cfy_mocks -from cloudify.exceptions import OperationRetry from vcloud_plugin_common import Config, VcloudAirClient - +import cloudify_cli.commands.local as local_command +import cloudify_cli.logger as logger +from cloudify import exceptions as cfy_exc SUBSCRIPTION = 'subscription' ONDEMAND = 'ondemand' +RANDOM_PREFIX_LENGTH = 5 + + +class Objectview(object): + def __init__(self, d): + self.__dict__ = d class IntegrationSubscriptionTestConfig(Config): @@ -76,22 +89,93 @@ def __init__(self, testname): raise RuntimeError("vcloud_config empty") if not self.test_config: raise RuntimeError("test_config empty") - - def setUp(self): print "\nUsed config: {0}".format(self.service_type) + self.vca_client = self.get_client() + + def get_client(self): fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', node_name='test', properties={}) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - self.vca_client = VcloudAirClient().get(config=self.vcloud_config) + vca_client = VcloudAirClient().get(config=self.vcloud_config) + return vca_client - def _run_with_retry(self, func, ctx): - - while True: - try: - return func(ctx=ctx) - except OperationRetry as e: - ctx.operation._operation_retry = None - ctx.logger.info(format(str(e))) - time.sleep(e.retry_after) + def setUp(self): + self.inputs = yaml.load(open('blueprints/inputs.yaml')) + self.inputs.update(self.vcloud_config) + self.tempdir = tempfile.mkdtemp() + self.workdir = os.getcwd() + logger.configure_loggers() + self.failed = True + self.conf = Objectview(self.inputs) + + def tearDown(self): + try: + if self.failed: + self.uninstall() + except Exception as e: + print e + os.chdir(self.workdir) + shutil.rmtree(self.tempdir, True) + + def init(self, blueprint_file): + blueprint = yaml.load(open('blueprints/header.yaml')) + nodes = yaml.load(open('blueprints/{}'.format(blueprint_file))) + blueprint['node_templates'].update(nodes) + with open(os.path.join(self.tempdir, 'inputs.yaml'), 'w') as f: + yaml.dump(self.inputs, f) + with open(os.path.join(self.tempdir, 'blueprint.yaml'), 'w') as f: + yaml.dump(blueprint, f) + os.chdir(self.tempdir) + local_command.init('blueprint.yaml', 'inputs.yaml', False) + + def install(self): + self._execute_command('install') + + def uninstall(self): + self._execute_command('uninstall') + + def _execute_command(self, command): + local_command.execute(command, {}, False, 5, 5, 1) + + +def fail_guard(f): + @wraps(f) + def wrapper(*args, **kargs): + args[0].failed = True + f(*args, **kargs) + args[0].failed = False + return wrapper + + +def wait_for_task(vca_client, task): + """ + check status of current task and make request for recheck + task status in case when we have not well defined state + (not error and not success or by timeout) + """ + WAIT_TIME_MAX_MINUTES = 30 + TASK_RECHECK_TIMEOUT = 5 + TASK_STATUS_SUCCESS = 'success' + TASK_STATUS_ERROR = 'error' + MAX_ATTEMPTS = WAIT_TIME_MAX_MINUTES * 60 / TASK_RECHECK_TIMEOUT + print('Maximun task wait time {0} minutes.'.format(WAIT_TIME_MAX_MINUTES)) + print('Task recheck after {0} seconds.'.format(TASK_RECHECK_TIMEOUT)) + status = task.get_status() + for attempt in range(MAX_ATTEMPTS): + print('Attempt: {0}/{1}.'.format(attempt + 1, MAX_ATTEMPTS)) + if status == TASK_STATUS_SUCCESS: + print('Task completed in {0} seconds'.format(attempt * TASK_RECHECK_TIMEOUT)) + return + if status == TASK_STATUS_ERROR: + error = task.get_Error() + raise cfy_exc.NonRecoverableError( + "Error during task execution: {0}".format(error.get_message())) + time.sleep(TASK_RECHECK_TIMEOUT) + response = requests.get( + task.get_href(), + headers=vca_client.vcloud_session.get_vcloud_headers()) + task = taskType.parseString(response.content, True) + status = task.get_status() + raise cfy_exc.NonRecoverableError("Wait for task timeout.") diff --git a/tests/integration/blueprints/floatingip_connect.yaml b/tests/integration/blueprints/floatingip_connect.yaml new file mode 100644 index 0000000..8f43e5d --- /dev/null +++ b/tests/integration/blueprints/floatingip_connect.yaml @@ -0,0 +1,18 @@ + test_floatingip: + type: cloudify.vcloud.nodes.FloatingIP + properties: + floatingip: + edge_gateway: { get_input: edge_gateway } + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_floatingip + type: cloudify.vcloud.server_connected_to_floating_ip diff --git a/tests/integration/blueprints/header.yaml b/tests/integration/blueprints/header.yaml new file mode 100644 index 0000000..619ffa8 --- /dev/null +++ b/tests/integration/blueprints/header.yaml @@ -0,0 +1,97 @@ +tosca_definitions_version: cloudify_dsl_1_0 + +imports: + - http://s3.amazonaws.com/vcloud-score/types.yaml +# - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml + - http://www.getcloudify.org/spec/fabric-plugin/1.3m4/plugin.yaml + +inputs: + username: + type: string + password: + type: string + vdc: + type: string + instance: + type: string + default: '' + service: + type: string + default: '' + org: + type: string + default: '' + url: + type: string + default: '' + service_type: + type: string + default: '' + api_version: + type: string + default: '' + catalog: + type: string + default: '' + template: + type: string + default: '' + network_name: + type: string + default: '' + edge_gateway: + type: string + default: '' + public_ip: + type: string + default: '' + server_name: + type: string + default: '' + server_cpu: + type: integer + default: 1 + server_memory: + type: integer + default: 1024 + ssh_user: + type: string + default: ubuntu + auto_generate_ssh_keys: + type: boolean + default: false + test_vdc_name: + type: string + default: '' + volume_name: + type: string + default: '' + volume_size_Mb: + type: string + default: 1024 + test_network_name: + type: string + default: '' + +node_types: + vcloud_configuration: + derived_from: cloudify.nodes.Root + properties: + vcloud_config: {} + +node_templates: + vcloud_configuration: + type: vcloud_configuration + properties: + vcloud_config: + username: { get_input: username } + password: { get_input: password } + url: { get_input: url } + instance: { get_input: instance } + vdc: { get_input: vdc } + org: { get_input: org } + service: { get_input: service } + service_type: { get_input: service_type } + api_version: { get_input: api_version } + edge_gateway: { get_input: edge_gateway } diff --git a/tests/integration/blueprints/inputs.yaml b/tests/integration/blueprints/inputs.yaml new file mode 100644 index 0000000..57a646b --- /dev/null +++ b/tests/integration/blueprints/inputs.yaml @@ -0,0 +1,5 @@ +volume_name: test_volume +volume_size_Mb: 1024 +server_name: testserver +test_vdc_name: testvdc +test_network_name: newtestnetwork diff --git a/tests/integration/blueprints/keypair_connect.yaml b/tests/integration/blueprints/keypair_connect.yaml new file mode 100644 index 0000000..5a88b94 --- /dev/null +++ b/tests/integration/blueprints/keypair_connect.yaml @@ -0,0 +1,19 @@ + test_keypair: + type: cloudify.vcloud.nodes.KeyPair + properties: + auto_generate: true + private_key: + create_file: true + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_keypair + type: cloudify.vcloud.server_connected_to_keypair diff --git a/tests/integration/blueprints/keypair_create.yaml b/tests/integration/blueprints/keypair_create.yaml new file mode 100644 index 0000000..d30a955 --- /dev/null +++ b/tests/integration/blueprints/keypair_create.yaml @@ -0,0 +1,6 @@ + test_keypair: + type: cloudify.vcloud.nodes.KeyPair + properties: + auto_generate: true + private_key: + create_file: true \ No newline at end of file diff --git a/tests/integration/blueprints/network_new.yaml b/tests/integration/blueprints/network_new.yaml new file mode 100644 index 0000000..3bc8a44 --- /dev/null +++ b/tests/integration/blueprints/network_new.yaml @@ -0,0 +1,18 @@ + test_network: + type: cloudify.vcloud.nodes.Network + properties: + network: + edge_gateway: { get_input: edge_gateway } + name: { get_input: test_network_name } + static_range: 10.10.199.2-10.10.199.128 + netmask: 255.255.255.0 + gateway_ip: 10.10.199.1 + dns: + - 8.8.8.8 + - 10.10.199.1 + dns_suffix: testnet + dhcp: + dhcp_range: 10.10.199.129-10.10.199.254 + default_lease: 3600 + max_lease: 7200 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/network_use_external.yaml b/tests/integration/blueprints/network_use_external.yaml new file mode 100644 index 0000000..a5bb061 --- /dev/null +++ b/tests/integration/blueprints/network_use_external.yaml @@ -0,0 +1,6 @@ + test_network: + type: cloudify.vcloud.nodes.Network + properties: + use_external_resource: true + resource_id: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/publicnat_to_network.yaml b/tests/integration/blueprints/publicnat_to_network.yaml new file mode 100644 index 0000000..5959920 --- /dev/null +++ b/tests/integration/blueprints/publicnat_to_network.yaml @@ -0,0 +1,18 @@ + test_nat: + type: cloudify.vcloud.nodes.PublicNAT + properties: + nat: + edge_gateway: { get_input: edge_gateway } + rules: + - type: SNAT + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + test_network: + type: cloudify.vcloud.nodes.Network + properties: + use_external_resource: true + resource_id: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_nat + type: cloudify.vcloud.net_connected_to_public_nat diff --git a/tests/integration/blueprints/publicnat_to_server.yaml b/tests/integration/blueprints/publicnat_to_server.yaml new file mode 100644 index 0000000..acd7569 --- /dev/null +++ b/tests/integration/blueprints/publicnat_to_server.yaml @@ -0,0 +1,33 @@ + test_nat: + type: cloudify.vcloud.nodes.PublicNAT + properties: + nat: + edge_gateway: { get_input: edge_gateway } + rules: + - type: DNAT + protocol: tcp + original_port: 8086 + translated_port: 8086 + - type: DNAT + protocol: tcp + original_port: 443 + translated_port: 443 + - type: DNAT + protocol: tcp + original_port: 22 + translated_port: 22 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_nat + type: cloudify.vcloud.server_connected_to_public_nat diff --git a/tests/integration/blueprints/security_group_create.yaml b/tests/integration/blueprints/security_group_create.yaml new file mode 100644 index 0000000..151285a --- /dev/null +++ b/tests/integration/blueprints/security_group_create.yaml @@ -0,0 +1,41 @@ + test_security_group: + type: cloudify.vcloud.nodes.SecurityGroup + properties: + security_group: + name: nodevcloud_security_group + edge_gateway: { get_input: edge_gateway } + rules: + - source: external + destination: internal + destination_port: 22 + action: allow + description: > + ssh between external net and managment node + protocol: TCP + - source: external + destination: internal + destination_port: 80 + action: allow + description: > + http to management node + protocol: TCP + - source: external + destination: internal + action: allow + description: > + Allow ping + protocol: ICMP + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_security_group + type: cloudify.vcloud.server_connected_to_security_group diff --git a/tests/integration/blueprints/server_remove_keys.yaml b/tests/integration/blueprints/server_remove_keys.yaml new file mode 100644 index 0000000..785d851 --- /dev/null +++ b/tests/integration/blueprints/server_remove_keys.yaml @@ -0,0 +1,27 @@ + test_keypair: + type: cloudify.vcloud.nodes.KeyPair + properties: + auto_generate: true + private_key: + create_file: true + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_keypair + type: cloudify.vcloud.server_connected_to_keypair + + test_service: + type: cloudify.nodes.ApplicationServer + relationships: + - type: cloudify.relationships.contained_in + target: test_server + - type: cloudify.vcloud.delete_public_key_from_server + target: test_server diff --git a/tests/integration/blueprints/server_to_network.yaml b/tests/integration/blueprints/server_to_network.yaml new file mode 100644 index 0000000..b175315 --- /dev/null +++ b/tests/integration/blueprints/server_to_network.yaml @@ -0,0 +1,20 @@ + test_network: + type: cloudify.vcloud.nodes.Network + properties: + use_external_resource: true + resource_id: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_network + type: cloudify.vcloud.server_connected_to_network diff --git a/tests/integration/blueprints/server_to_port.yaml b/tests/integration/blueprints/server_to_port.yaml new file mode 100644 index 0000000..2a8e245 --- /dev/null +++ b/tests/integration/blueprints/server_to_port.yaml @@ -0,0 +1,33 @@ + test_port: + type: cloudify.vcloud.nodes.Port + properties: + port: + network: { get_input: network_name } + ip_allocation_mode: POOL + primary_interface: true + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_network + type: cloudify.vcloud.port_connected_to_network + + + test_network: + type: cloudify.vcloud.nodes.Network + properties: + use_external_resource: true + resource_id: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_port + type: cloudify.vcloud.server_connected_to_port diff --git a/tests/integration/blueprints/server_use_external.yaml b/tests/integration/blueprints/server_use_external.yaml new file mode 100644 index 0000000..cb40284 --- /dev/null +++ b/tests/integration/blueprints/server_use_external.yaml @@ -0,0 +1,8 @@ + test_server: + type: cloudify.vcloud.nodes.Server + properties: + use_external_resource: true + resource_id: { get_input: server_name } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/server_with_name.yaml b/tests/integration/blueprints/server_with_name.yaml new file mode 100644 index 0000000..d300428 --- /dev/null +++ b/tests/integration/blueprints/server_with_name.yaml @@ -0,0 +1,15 @@ + example_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + name: { get_input: server_name } + catalog: { get_input: catalog } + template: { get_input: template } + hardware: + cpu: { get_input: server_cpu } + memory: { get_input: server_memory } + guest_customization: + computer_name: { get_input: server_name } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/server_without_name.yaml b/tests/integration/blueprints/server_without_name.yaml new file mode 100644 index 0000000..29a63c4 --- /dev/null +++ b/tests/integration/blueprints/server_without_name.yaml @@ -0,0 +1,9 @@ + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/vdc_new.yaml b/tests/integration/blueprints/vdc_new.yaml new file mode 100644 index 0000000..00b7257 --- /dev/null +++ b/tests/integration/blueprints/vdc_new.yaml @@ -0,0 +1,5 @@ +test_vdc: + type: cloudify.vcloud.nodes.VDC + properties: + name: { get_input: test_vdc_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/vdc_use_external.yaml b/tests/integration/blueprints/vdc_use_external.yaml new file mode 100644 index 0000000..e398f2e --- /dev/null +++ b/tests/integration/blueprints/vdc_use_external.yaml @@ -0,0 +1,6 @@ +test_vdc: + type: cloudify.vcloud.nodes.VDC + properties: + use_external_resource: true + resource_id: { get_input: test_vdc_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/volume_attach.yaml b/tests/integration/blueprints/volume_attach.yaml new file mode 100644 index 0000000..b04de96 --- /dev/null +++ b/tests/integration/blueprints/volume_attach.yaml @@ -0,0 +1,29 @@ + test_floatingip: + type: cloudify.vcloud.nodes.FloatingIP + properties: + floatingip: + edge_gateway: { get_input: edge_gateway } + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_floatingip + type: cloudify.vcloud.server_connected_to_floating_ip + + test_volume: + type: cloudify.vcloud.nodes.Volume + properties: + volume: + name: { get_input: volume_name } + size: { get_input: volume_size_Mb } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - type: cloudify.vcloud.volume_attached_to_server + target: test_server diff --git a/tests/integration/blueprints/volume_new.yaml b/tests/integration/blueprints/volume_new.yaml new file mode 100644 index 0000000..63ffacd --- /dev/null +++ b/tests/integration/blueprints/volume_new.yaml @@ -0,0 +1,7 @@ + volume: + type: cloudify.vcloud.nodes.Volume + properties: + volume: + name: { get_input: volume_name } + size: { get_input: volume_size_Mb } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/blueprints/volume_use_external.yaml b/tests/integration/blueprints/volume_use_external.yaml new file mode 100644 index 0000000..2fdca53 --- /dev/null +++ b/tests/integration/blueprints/volume_use_external.yaml @@ -0,0 +1,6 @@ + volume: + type: cloudify.vcloud.nodes.Volume + properties: + use_external_resource: true + resource_id: { get_input: volume_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } diff --git a/tests/integration/run_all_tests.py b/tests/integration/run_all_tests.py deleted file mode 100644 index 0364a52..0000000 --- a/tests/integration/run_all_tests.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import nose -import os -from tests.integration import SUBSCRIPTION, ONDEMAND - -testfiles = [file for file in os.listdir('.') - if file.startswith("test") and file.endswith(".py")] -try: - for service in (SUBSCRIPTION, ONDEMAND): - for test in testfiles: - result = nose.run( - argv=['-x', '-v', '-s', '--tc={0}:'.format(service), test]) - if not result: - raise RuntimeError("Test failed") -except RuntimeError as e: - print e diff --git a/tests/integration/test_combined.py b/tests/integration/test_combined.py deleted file mode 100644 index 6965669..0000000 --- a/tests/integration/test_combined.py +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import contextlib -import ipaddress -import mock -import random -import string -import time -import unittest - -from cloudify import mocks as cfy_mocks - -from network_plugin import floatingip, network -from server_plugin import server - -from tests.integration import TestCase - -RANDOM_PREFIX_LENGTH = 5 - - -class CombinedTestCase(TestCase): - - def setUp(self): - super(CombinedTestCase, self).setUp() - chars = string.ascii_uppercase + string.digits - self.name_prefix = ('plugin_test_{0}_' - .format(''.join( - random.choice(chars) - for _ in range(RANDOM_PREFIX_LENGTH)))) - - def _setup_network(self): - network_use_existing = \ - self.test_config['combined']['network_use_existing'] - existing_network = self.test_config['combined']['network_name'] - self.network_name = (existing_network if network_use_existing - else self.name_prefix + "network") - self.network_ctx = cfy_mocks.MockCloudifyContext( - node_id=self.network_name, - node_name=self.network_name, - properties={ - "network": self.test_config['network'], - "use_external_resource": network_use_existing, - "resource_id": self.network_name, - "vcloud_config": self.vcloud_config}) - - def _setup_server(self, ip_allocation_mode): - self.server_name = self.name_prefix + 'server' - port_node_context = cfy_mocks.MockNodeContext( - properties={ - 'port': - { - 'network': self.network_name, - 'ip_allocation_mode': ip_allocation_mode, - 'primary_interface': True - } - } - ) - port_relationship = mock.Mock() - port_relationship.target = mock.Mock() - port_relationship.target.node = port_node_context - self.server_ctx = cfy_mocks.MockCloudifyContext( - node_id=self.server_name, - node_name=self.server_name, - properties={ - 'server': self.test_config['server'], - 'management_network': self.network_name, - "vcloud_config": self.vcloud_config - } - ) - self.server_ctx.instance.relationships = [port_relationship] - - def _setup_floating_ip(self): - self.fip_ctx = cfy_mocks.MockCloudifyContext( - node_id='test', - node_name='test', - properties={}, - target=cfy_mocks.MockCloudifyContext( - node_id="target", - properties={'floatingip': self.test_config['floatingip']}), - source=cfy_mocks.MockCloudifyContext( - node_id="source", - properties={'vcloud_config': self.vcloud_config}, - runtime_properties={server.VCLOUD_VAPP_NAME: self.server_name} - ) - ) - - def test_new_server_network_ip_allocation_dhcp(self): - self._setup_network() - - self._setup_server(ip_allocation_mode='dhcp') - - self.addCleanup(self._delete_network) - self._create_network() - - self.addCleanup(self._delete_server) - self._create_server() - self._wait_for_server_configured() - - if self.test_config['combined']['network_use_existing'] is False: - gw_ip = self.network_ctx.node.properties['network']['gateway_ip'] - netmask = self.network_ctx.node.properties['network']['netmask'] - gw_interface = ipaddress.IPv4Interface( - gw_ip + '/' + netmask) - vdc = self.vca_client.get_vdc(self.vcloud_config['org']) - vapp = self.vca_client.get_vapp( - vdc, - self.server_ctx.instance.runtime_properties[ - server.VCLOUD_VAPP_NAME] - ) - nw_connection = server._get_vm_network_connection( - vapp, self.network_name) - self.assertTrue(ipaddress.IPv4Address(unicode(nw_connection['ip'])) - in gw_interface.network, - "vm ip: {0}, expected network: {1}" - .format(nw_connection['ip'], - gw_interface.network)) - - def test_new_server_network_ip_allocation_pool(self): - self._setup_network() - - self._setup_server(ip_allocation_mode='pool') - - self.addCleanup(self._delete_network) - self._create_network() - - self.addCleanup(self._delete_server) - self._create_server() - self._wait_for_server_configured() - - if self.test_config['combined']['network_use_existing'] is False: - gw_ip = self.network_ctx.node.properties['network']['gateway_ip'] - netmask = self.network_ctx.node.properties['network']['netmask'] - gw_interface = ipaddress.IPv4Interface( - gw_ip + '/' + netmask) - vdc = self.vca_client.get_vdc(self.vcloud_config['org']) - vapp = self.vca_client.get_vapp( - vdc, - self.server_ctx.instance.runtime_properties[ - server.VCLOUD_VAPP_NAME] - ) - nw_connection = server._get_vm_network_connection( - vapp, self.network_name) - self.assertTrue(ipaddress.IPv4Address(unicode(nw_connection['ip'])) - in gw_interface.network, - "vm ip: {0}, expected network: {1}" - .format(nw_connection['ip'], - gw_interface.network)) - - def _create_network(self): - with contextlib.nested( - mock.patch('network_plugin.network.ctx', self.network_ctx), - mock.patch('vcloud_plugin_common.ctx', self.network_ctx)): - network.create() - - def _delete_network(self): - with contextlib.nested( - mock.patch('network_plugin.network.ctx', self.network_ctx), - mock.patch('vcloud_plugin_common.ctx', self.network_ctx)): - network.delete() - - def _create_server(self): - with contextlib.nested( - mock.patch('server_plugin.server.ctx', self.server_ctx), - mock.patch('vcloud_plugin_common.ctx', self.server_ctx)): - server.create() - self._run_with_retry(server.start, self.server_ctx) - - def _delete_server(self): - with contextlib.nested( - mock.patch('server_plugin.server.ctx', self.server_ctx), - mock.patch('vcloud_plugin_common.ctx', self.server_ctx)): - server.stop() - server.delete() - - def _wait_for_server_configured(self): - with contextlib.nested( - mock.patch('server_plugin.server.ctx', self.server_ctx), - mock.patch('vcloud_plugin_common.ctx', self.server_ctx)): - num_tries = 10 - verified = False - for _ in range(num_tries): - result = server._get_state(self.vca_client) - if result is True: - verified = True - break - time.sleep(10) - self.assertTrue(verified, - "Server configuration wasn't verified") - - def _connect_floating_ip(self): - with contextlib.nested( - mock.patch('network_plugin.floatingip.ctx', self.fip_ctx), - mock.patch('vcloud_plugin_common.ctx', self.fip_ctx)): - floatingip.connect_floatingip() - - def _disconnect_floating_ip(self): - with contextlib.nested( - mock.patch('network_plugin.floatingip.ctx', self.fip_ctx), - mock.patch('vcloud_plugin_common.ctx', self.fip_ctx)): - floatingip.disconnect_floatingip() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/integration/test_network_plugin.py b/tests/integration/test_network_plugin.py index 3529577..c82bb52 100644 --- a/tests/integration/test_network_plugin.py +++ b/tests/integration/test_network_plugin.py @@ -12,297 +12,77 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import mock -from cloudify.mocks import MockCloudifyContext -from network_plugin import (floatingip, network, security_group, public_nat, - keypair, port) -from server_plugin.server import VCLOUD_VAPP_NAME -from network_plugin.network import VCLOUD_NETWORK_NAME -from network_plugin import CheckAssignedExternalIp -from cloudify import exceptions as cfy_exc -from tests.integration import TestCase +from tests.integration import TestCase, fail_guard -# for skipping test add this before test function: -# @unittest.skip("skip test") - -class ValidationOperationsTestCase(TestCase): +class FloatingIpTestCase(TestCase): def setUp(self): - name = "testnode" - self.ctx = MockCloudifyContext( - node_id=name, - node_name=name, - properties={'vcloud_config': self.vcloud_config}) - ctx_patch = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch.start() - self.addCleanup(ctx_patch.stop) super(self.__class__, self).setUp() - def test_validation(self): - self.ctx.node.properties.update( - {'floatingip': self.test_config['floatingip']}) - with mock.patch('network_plugin.floatingip.ctx', self.ctx): - floatingip.creation_validation() - - self.ctx.node.properties.update( - {'floatingip': self.test_config['floatingip_auto']}) - with mock.patch('network_plugin.floatingip.ctx', self.ctx): - floatingip.creation_validation() - - self.ctx.node.properties.update( - {'private_key_path': os.path.realpath(__file__)}) - with mock.patch('network_plugin.keypair.ctx', self.ctx): - keypair.creation_validation() - - self.ctx.node.properties.update( - {"resource_id": self.test_config['network']['name'], - "network": self.test_config['network'], - "use_external_resource": False}) - with mock.patch('network_plugin.network.ctx', self.ctx): - network.creation_validation() + @fail_guard + def test_connect(self): + self.init('floatingip_connect.yaml') + self.install() + self.uninstall() - self.ctx.node.properties.update( - {'port': { - 'network': self.test_config['management_network'], - 'ip_allocation_mode': 'dhcp', - 'primary_interface': True}}) - with mock.patch('network_plugin.port.ctx', self.ctx): - port.creation_validation() - self.ctx.node.properties.update( - {"nat": self.test_config['public_nat']['nat'], - "rules": self.test_config['public_nat']['rules_net']}) - with mock.patch('network_plugin.public_nat.ctx', self.ctx): - public_nat.creation_validation() - - self.ctx.node.properties.update(self.test_config['security_group']) - with mock.patch('network_plugin.security_group.ctx', self.ctx): - security_group.creation_validation() - - -class FloatingIPOperationsTestCase(TestCase): +class KeypairTestCase(TestCase): def setUp(self): - name = "testnode" - self.properties = { - 'vcloud_config': self.vcloud_config, - 'floatingip': self.test_config['floatingip'] - } - self.ctx = MockCloudifyContext( - node_id=name, - node_name=name, - properties={}, - target=MockCloudifyContext(node_id="target", - properties=self.properties), - source=MockCloudifyContext( - node_id="source", - properties={'vcloud_config': self.vcloud_config}, - runtime_properties={ - VCLOUD_VAPP_NAME: self.test_config['test_vm']} - ) - ) - ctx_patch1 = mock.patch('network_plugin.floatingip.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) super(self.__class__, self).setUp() - def tearDown(self): - super(self.__class__, self).tearDown() - - def test_floating_ip_create_delete_with_explicit_ip(self): - self.ctx.target.node.properties['floatingip'].update( - self.test_config['floatingip']) - public_ip = self.ctx.target.node.properties['floatingip']['public_ip'] - CheckAssignedExternalIp(public_ip, self._get_gateway()) - floatingip.connect_floatingip() - floatingip.disconnect_floatingip() - CheckAssignedExternalIp(public_ip, self._get_gateway()) + @fail_guard + def test_create(self): + self.init('keypair_create.yaml') + self.install() + self.uninstall() - def test_floating_ip_create_delete_with_autoget_ip(self): - self.ctx.target.node.properties['floatingip'].update( - self.test_config['floatingip']) - del self.ctx.target.node.properties['floatingip']['public_ip'] - floatingip.connect_floatingip() - public_ip = self.ctx.target.instance.runtime_properties['public_ip'] - self.assertRaises(cfy_exc.NonRecoverableError, - CheckAssignedExternalIp, - public_ip, - self._get_gateway()) - self.assertTrue(public_ip) - floatingip.disconnect_floatingip() - CheckAssignedExternalIp(public_ip, self._get_gateway()) + @fail_guard + def test_connect(self): + self.init('keypair_connect.yaml') + self.install() + self.uninstall() - def _get_gateway(self): - return self.vca_client.get_gateway( - self.vcloud_config["org"], - self.ctx.target.node.properties['floatingip']['edge_gateway']) - -class OrgNetworkOperationsTestCase(TestCase): +class NetworkTestCase(TestCase): def setUp(self): - - self.net_name = self.test_config['network']['name'] - self.existing_net_name = self.test_config['test_network_name'] - self.ctx = MockCloudifyContext( - node_id=self.net_name, - node_name=self.net_name, - properties={"resource_id": self.existing_net_name, - "network": self.test_config['network'], - "vcloud_config": self.vcloud_config, - "use_external_resource": False}) - self.org_name = self.vcloud_config["org"] - ctx_patch1 = mock.patch('network_plugin.network.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) super(self.__class__, self).setUp() - def get_pools(self): - gateway = self.vca_client.get_gateways(self.org_name)[0] - if not gateway: - raise cfy_exc.NonRecoverableError("Gateway not found") - gatewayConfiguration = gateway.me.get_Configuration() - edgeGatewayServiceConfiguration = \ - gatewayConfiguration.get_EdgeGatewayServiceConfiguration() - dhcpService = filter( - lambda service: (service.__class__.__name__ - == "GatewayDhcpServiceType"), - edgeGatewayServiceConfiguration.get_NetworkService())[0] - return dhcpService.get_Pool() + @fail_guard + def test_network_new(self): + self.init('network_new.yaml') + self.install() + self.uninstall() - def tearDown(self): - super(self.__class__, self).tearDown() + @fail_guard + def test_network_use_external(self): + self.init('network_use_external.yaml') + self.install() + self.uninstall() - def test_orgnetwork_create_delete(self): - self.assertNotIn(self.net_name, - network._get_network_list(self.vca_client, - self.org_name)) - start_pools = len(self.get_pools()) - network.create() - self.assertIn(self.net_name, - network._get_network_list(self.vca_client, - self.org_name)) - self.assertEqual(start_pools + 1, len(self.get_pools())) - network.delete() - self.assertNotIn(self.net_name, - network._get_network_list(self.vca_client, - self.org_name)) - self.assertEqual(start_pools, len(self.get_pools())) - -class SecurityGroupOperationsTestCase(TestCase): +class PublicNatTestCase(TestCase): def setUp(self): - name = "testnode" - self.ctx = MockCloudifyContext( - node_id=name, - node_name=name, - properties={}, - target=MockCloudifyContext( - node_id="target", - properties=self.test_config['security_group']), - source=MockCloudifyContext( - node_id="source", - properties={'vcloud_config': self.vcloud_config}, - runtime_properties={ - VCLOUD_VAPP_NAME: self.test_config['test_vm']} - ) - ) - ctx_patch1 = mock.patch('network_plugin.security_group.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) - self.org_name = self.vcloud_config["org"] super(self.__class__, self).setUp() - def tearDown(self): - super(self.__class__, self).tearDown() - - def test_firewall_rules_create_delete(self): - rules = len(self.get_rules()) - security_group.create() - self.assertEqual(rules + 2, len(self.get_rules())) - security_group.delete() - self.assertEqual(rules, len(self.get_rules())) + @fail_guard + def test_connect_to_network(self): + self.init('publicnat_to_network.yaml') + self.install() + self.uninstall() - def get_rules(self): - gateway = self.vca_client.get_gateways(self.org_name)[0] - if not gateway: - raise cfy_exc.NonRecoverableError("Gateway not found") - gatewayConfiguration = gateway.me.get_Configuration() - edgeGatewayServiceConfiguration = \ - gatewayConfiguration.get_EdgeGatewayServiceConfiguration() - firewallService = filter( - lambda service: (service.__class__.__name__ - == "FirewallServiceType"), - edgeGatewayServiceConfiguration.get_NetworkService())[0] - return firewallService.get_FirewallRule() + @fail_guard + def test_connect_to_server(self): + self.init('publicnat_to_server.yaml') + self.install() + self.uninstall() -class PublicNatOperationsTestCase(TestCase): +class SecurityGroupTestCase(TestCase): def setUp(self): - name = "testnode" - self.ctx = MockCloudifyContext( - node_id=name, - node_name=name, - properties={}, - target=MockCloudifyContext( - node_id="target", - properties={ - "nat": self.test_config['public_nat']['nat'], - 'use_external_resource': False, - "rules": {}}), - source=MockCloudifyContext( - node_id="source", - properties={"vcloud_config": self.vcloud_config}, - runtime_properties={ - VCLOUD_VAPP_NAME: - self.test_config['public_nat']['test_vm'], - VCLOUD_NETWORK_NAME: - self.test_config['public_nat']['network_name']} - ) - ) - ctx_patch1 = mock.patch('network_plugin.public_nat.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) super(self.__class__, self).setUp() - def tearDown(self): - super(self.__class__, self).tearDown() - - def test_public_network_connected_to_nat(self): - self.ctx.target.node.properties['rules'] = \ - self.test_config['public_nat']['rules_net'] - self.ctx.source.node.properties['resource_id'] = \ - self.test_config['public_nat']['network_name'] - rules_count = self.get_rules_count() - public_nat.net_connect_to_nat() - self.assertEqual(rules_count + 1, self.get_rules_count()) - public_nat.net_disconnect_from_nat() - self.assertEqual(rules_count, self.get_rules_count()) - - def test_public_server_connected_to_nat(self): - self.ctx.target.node.properties['rules'] = \ - self.test_config['public_nat']['rules_port'] - rules_count = self.get_rules_count() - public_nat.server_connect_to_nat() - self.assertEqual(rules_count + 3, self.get_rules_count()) - public_nat.server_disconnect_from_nat() - self.assertEqual(rules_count, self.get_rules_count()) - - def get_rules_count(self): - return len(self._get_gateway().get_nat_rules()) - - def _get_gateway(self): - return self.vca_client.get_gateway( - self.vcloud_config["org"], - self.ctx.target.node.properties['nat']['edge_gateway']) + @fail_guard + def test_create(self): + self.init('security_group_create.yaml') + self.install() + self.uninstall() diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index e9cad58..51794c7 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -12,396 +12,86 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock -import random -import socket -import string -import time +from tests.integration import TestCase, wait_for_task, fail_guard -from cloudify import exceptions as cfy_exc -from cloudify import mocks as cfy_mocks -from server_plugin import server -from storage_plugin import volume -from server_plugin import vdc -from tests.integration import TestCase -from cloudify.mocks import MockCloudifyContext -from server_plugin.server import VCLOUD_VAPP_NAME - -from vcloud_plugin_common import VcloudAirClient - - -RANDOM_PREFIX_LENGTH = 5 - - -class ServerNoNetworkTestCase(TestCase): - def setUp(self): - super(ServerNoNetworkTestCase, self).setUp() - chars = string.ascii_uppercase + string.digits - self.name_prefix = ('plugin_test_{0}_' - .format(''.join( - random.choice(chars) - for _ in range(RANDOM_PREFIX_LENGTH))) - ) - server_test_dict = self.test_config['server'] - name = self.name_prefix + 'server' - - self.ctx = cfy_mocks.MockCloudifyContext( - node_id=name, - node_name=name, - properties={ - 'server': - { - 'name': name, - 'catalog': server_test_dict['catalog'], - 'template': server_test_dict['template'], - 'hardware': server_test_dict['hardware'], - 'guest_customization': - server_test_dict.get('guest_customization') - }, - 'management_network': self.test_config['management_network'], - 'vcloud_config': self.vcloud_config - } - ) - self.ctx.node.properties['server']['guest_customization'][ - 'public_keys'] = [self.test_config['manager_keypair'], - self.test_config['agent_keypair']] - self.ctx.instance.relationships = [] - ctx_patch1 = mock.patch('server_plugin.server.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) - - def tearDown(self): - try: - server.stop() - except Exception: - pass - try: - server.delete() - except Exception: - pass - super(ServerNoNetworkTestCase, self).tearDown() - - def test_server_creation_validation(self): - success = True - msg = None - try: - server.creation_validation() - except cfy_exc.NonRecoverableError as e: - success = False - msg = e.message - self.assertTrue(success, msg) - - def test_server_creation_validation_catalog_not_found(self): - self.ctx.node.properties['server']['catalog'] = 'fake-catalog' - self.assertRaises(cfy_exc.NonRecoverableError, - server.creation_validation) - - def test_server_creation_validation_template_not_found(self): - self.ctx.node.properties['server']['template'] = 'fake-template' - self.assertRaises(cfy_exc.NonRecoverableError, - server.creation_validation) - - def test_server_creation_validation_parameter_missing(self): - del self.ctx.node.properties['server']['template'] - self.assertRaises(cfy_exc.NonRecoverableError, - server.creation_validation) - - def test_server_create_delete(self): - server.create() - server.configure() - vdc = self.vca_client.get_vdc(self.vcloud_config['org']) - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertFalse(vapp is None) - self.assertFalse(server._vapp_is_on(vapp)) - self.check_hardware(vapp) - server.delete() - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertTrue(vapp is None) - - def test_server_stop_start(self): - server.create() - vdc = self.vca_client.get_vdc(self.vcloud_config['org']) - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertFalse(vapp is None) - self.assertFalse(server._vapp_is_on(vapp)) - - self._run_with_retry(server.start, self.ctx) - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertTrue(server._vapp_is_on(vapp)) - - server.stop() - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertFalse(server._vapp_is_on(vapp)) - - self._run_with_retry(server.start, self.ctx) - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertTrue(server._vapp_is_on(vapp)) - - def check_hardware(self, vapp): - data = vapp.get_vms_details()[0] - hardware = self.test_config['server']['hardware'] - if hardware: - self.assertEqual(data['cpus'], hardware['cpu']) - self.assertEqual(data['memory'] * 1024, hardware['memory']) - - -class ServerWithNetworkTestCase(TestCase): - def setUp(self): - super(ServerWithNetworkTestCase, self).setUp() - chars = string.ascii_uppercase + string.digits - self.name_prefix = ('plugin_test_{0}_' - .format(''.join( - random.choice(chars) - for _ in range(RANDOM_PREFIX_LENGTH))) - ) - - server_test_dict = self.test_config['server'] - name = self.name_prefix + 'server' - self.network_name = self.test_config['management_network'] - - port_node_context = cfy_mocks.MockNodeContext( - properties={ - 'port': - { - 'network': self.network_name, - 'ip_allocation_mode': 'pool', - 'primary_interface': True - } - } - ) - - network_node_context = cfy_mocks.MockNodeContext( - properties={ - 'network': - { - 'name': self.network_name - } - } - ) - - self.port_relationship = mock.Mock() - self.port_relationship.target = mock.Mock() - self.port_relationship.target.node = port_node_context - - self.network_relationship = mock.Mock() - self.network_relationship.target = mock.Mock() - self.network_relationship.target.node = network_node_context - self.properties = { - 'server': - { - 'name': name, - 'catalog': server_test_dict['catalog'], - 'template': server_test_dict['template'] - }, - 'management_network': self.network_name, - 'vcloud_config': self.vcloud_config - } - self.ctx = cfy_mocks.MockCloudifyContext( - node_id=name, - node_name=name, - properties=self.properties - ) - self.ctx.instance.relationships = [] - ctx_patch1 = mock.patch('server_plugin.server.ctx', self.ctx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.ctx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) - - def tearDown(self): - try: - server.stop() - except Exception: - pass - try: - server.delete() - except Exception: - pass - super(ServerWithNetworkTestCase, self).tearDown() - - def test_create_with_port_connection(self): - self.ctx.instance.relationships = [self.port_relationship] - self._create_test() - - def test_create_with_network_connection(self): - self.ctx.instance.relationships = [self.network_relationship] - self._create_test() - - def test_create_without_connections(self): - self.ctx.instance.relationships = [] - self._create_test() - - def _create_test(self): - server.create() - self._run_with_retry(server.start, self.ctx) - vdc = self.vca_client.get_vdc(self.vcloud_config['org']) - vapp = self.vca_client.get_vapp( - vdc, - self.ctx.node.properties['server']['name']) - self.assertFalse(vapp is None) - networks = server._get_vm_network_connections(vapp) - self.assertEqual(1, len(networks)) - self.assertEqual(self.network_name, networks[0]['network_name']) - - def test_get_state(self): - num_tries = 5 - verified = False - server.create() - self._run_with_retry(server.start, self.ctx) - for _ in range(num_tries): - result = server._get_state(self.vca_client) - if result is True: - self.assertTrue('ip' in self.ctx.instance.runtime_properties) - self.assertTrue('networks' - in self.ctx.instance.runtime_properties) - self.assertEqual(1, - len(self.ctx.instance. - runtime_properties['networks'].keys())) - self.assertEqual(self.network_name, - self.ctx.instance. - runtime_properties['networks'].keys()[0]) - ip_valid = True - try: - socket.inet_aton( - self.ctx.instance.runtime_properties['ip']) - except socket.error: - ip_valid = False - self.assertTrue(ip_valid) - verified = True - break - time.sleep(2) - self.assertTrue(verified) - - -class VolumeTestCase(TestCase): +class ServerTestCase(TestCase): def setUp(self): - super(VolumeTestCase, self).setUp() - self.volume_test_dict = self.test_config['volume'] - name = 'volume' - self.properties = { - 'volume': - { - 'name': self.volume_test_dict['name'], - 'size': self.volume_test_dict['size'] - }, - 'use_external_resource': True, - 'resource_id': self.volume_test_dict['name_exists'], - 'vcloud_config': self.vcloud_config - } - self.target = MockCloudifyContext( - node_id="target", - properties={'vcloud_config': self.vcloud_config}, - runtime_properties={ - VCLOUD_VAPP_NAME: self.test_config['test_vm'] - } - ) - self.source = MockCloudifyContext( - node_id="source", properties=self.properties - ) - self.nodectx = cfy_mocks.MockCloudifyContext( - node_id=name, - node_name=name, - properties=self.properties - ) - self.relationctx = cfy_mocks.MockCloudifyContext( - node_id=name, - node_name=name, - target=self.target, - source=self.source - ) - self.ctx = self.nodectx - ctx_patch1 = mock.patch('server_plugin.volume.ctx', self.nodectx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.nodectx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) - - def test_volume(self): - disks_count = lambda: len( - self.vca_client.get_disks(self.vcloud_config['vdc'])) - volume.creation_validation() - disks_before = disks_count() - volume.create_volume() - if self.relationctx.source.node.properties['use_external_resource']: - self.assertEqual(disks_before, disks_count()) + super(ServerTestCase, self).setUp() + + @fail_guard + def test_with_name(self): + self.init('server_with_name.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_without_name(self): + self.init('server_without_name.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_use_external(self): + task = self.vca_client.create_vapp(self.conf.vdc, self.conf.server_name, self.conf.template, + self.conf.catalog, network_name=self.conf.network_name, + vm_name=self.conf.server_name, deploy='false', poweron='false') + if task: + wait_for_task(self.vca_client, task) else: - self.assertEqual(disks_before + 1, disks_count()) - self._attach_detach() - volume.delete_volume() - self.assertEqual(disks_before, disks_count()) - - def _attach_detach(self): - def links_count(): - node_properties = self.relationctx.source.node.properties - if node_properties['use_external_resource']: - return [ - len(d[1]) for d in self.vca_client.get_disks( - self.vcloud_config['vdc'] - ) if d[0].name == node_properties['resource_id'] - ][0] - else: - return [ - len(d[1]) for d in self.vca_client.get_disks( - self.vcloud_config['vdc'] - ) if d[0].name == node_properties['volume']['name'] - ][0] - with mock.patch('server_plugin.volume.ctx', self.relationctx): - links_before = links_count() - volume.attach_volume() - self.assertEqual(links_before + 1, links_count()) - volume.detach_volume() + raise Exception("Can't create vm") + try: + self.init('server_use_external.yaml') + self.install() + self.uninstall() + finally: + self.vca_client.delete_vapp(self.conf.vdc, self.conf.server_name) + self.failed = False + + @fail_guard + def test_connect_to_network(self): + self.init('server_to_network.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_connect_to_port(self): + self.init('server_to_port.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_remove_keys(self): + self.init('server_remove_keys.yaml') + self.install() + self.uninstall() class VdcTestCase(TestCase): def setUp(self): super(VdcTestCase, self).setUp() - self.vdc_test_dict = self.test_config['vdc'] - name = 'vdc' - self.properties = { - 'name': self.vdc_test_dict['name'], - 'use_external_resource': False, - 'resource_id': self.vdc_test_dict['name_exists'], - 'vcloud_config': self.vcloud_config - } - self.nodectx = cfy_mocks.MockCloudifyContext( - node_id=name, - node_name=name, - properties=self.properties - ) - self.ctx = self.nodectx - ctx_patch1 = mock.patch('server_plugin.vdc.ctx', self.nodectx) - ctx_patch2 = mock.patch('vcloud_plugin_common.ctx', self.nodectx) - ctx_patch1.start() - ctx_patch2.start() - self.addCleanup(ctx_patch1.stop) - self.addCleanup(ctx_patch2.stop) - def test_vdc_create_delete(self): - name = self.properties['name'] - self.assertFalse(name in self._get_vdc_names()) - vdc.create() - self.assertTrue(name in self._get_vdc_names()) - vdc.delete() - self.assertFalse(name in self._get_vdc_names()) - - def _get_vdc_names(self): - vca_client = VcloudAirClient().get(config=self.vcloud_config) - return vca_client.get_vdc_names() + @fail_guard + def test_new(self): + if self.service_type == 'subscription': + print 'Testing only in ondemand service' + return + self.init('vdc_new.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_use_external(self): + task = self.vca_client.create_vdc(self.conf.test_vdc_name) + if task: + wait_for_task(self.vca_client, task) + else: + raise Exception("Can't create vdc") + self.init('vdc_use_external.yaml') + self.install() + self.uninstall() + self.vca_client = self.get_client() + result, task = self.vca_client.delete_vdc(self.conf.test_vdc_name) + if not result: + raise Exception(task) + wait_for_task(self.vca_client, task) diff --git a/tests/integration/test_storage_plugin.py b/tests/integration/test_storage_plugin.py new file mode 100644 index 0000000..0a2d93e --- /dev/null +++ b/tests/integration/test_storage_plugin.py @@ -0,0 +1,43 @@ +# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tests.integration import TestCase, wait_for_task, fail_guard + + +class VolumeTestCase(TestCase): + def setUp(self): + super(VolumeTestCase, self).setUp() + + @fail_guard + def test_new(self): + self.init('volume_new.yaml') + self.install() + self.uninstall() + + @fail_guard + def test_use_external(self): + status, disk = self.vca_client.add_disk(self.conf.vdc, self.conf.volume_name, self.conf.volume_size_Mb) + self.init('volume_use_external.yaml') + self.install() + self.uninstall() + self.vca_client = self.get_client() + status, task = self.vca_client.delete_disk(self.conf.vdc, self.conf.volume_name) + if status: + wait_for_task(self.vca_client, task) + + @fail_guard + def test_attach(self): + self.init('volume_attach.yaml') + self.install() + self.uninstall() diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 24a8bf4..b031291 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -53,8 +53,7 @@ def test_create(self): fake_ctx = self.generate_node_context( properties={'auto_generate': True, - 'private_key' :{ - 'create_file': True}}) + 'private_key': {'create_file': True}}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties self.assertEqual('~/.ssh/test_private.key', From 12f7d48a6a294af124bd16ad97a00a83d5da8a5a Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 21 Sep 2015 13:09:19 +0400 Subject: [PATCH 128/228] CFY-3509 remove ssh keys from runtime properties. --- network_plugin/keypair.py | 12 +++++++++--- server_plugin/server.py | 9 +++++++-- tests/unittests/test_mock_network_plugin_keypair.py | 3 +-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index 118a867..edd2747 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -97,9 +97,15 @@ def server_connect_to_keypair(**kwargs): target_rt_properties = ctx.target.instance.runtime_properties if SSH_KEY not in host_rt_properties: host_rt_properties[SSH_KEY] = {} - host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) - host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) - host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) + host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) + host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + ctx.source.instance.update() + if PRIVATE_KEY in target_rt_properties: + del target_rt_properties[PRIVATE_KEY] + if PUBLIC_KEY in target_rt_properties: + del target_rt_properties[PUBLIC_KEY] + ctx.target.instance.update() @operation diff --git a/server_plugin/server.py b/server_plugin/server.py index 3349261..8f60c06 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -22,9 +22,9 @@ with_vca_client, error_response, STATUS_POWERED_ON) - from network_plugin import (get_network_name, get_network, is_network_exists, get_vapp_name) +from network_plugin.keypair import PUBLIC_KEY, SSH_KEY VCLOUD_VAPP_NAME = 'vcloud_vapp_name' GUEST_CUSTOMIZATION = 'guest_customization' @@ -393,6 +393,11 @@ def remove_keys(vca_client, **kwargs): wait_for_task(vca_client, task) ctx.logger.info("Power on after deleting public key successful.") + ctx.logger.info("Remove keys from properties.") + host_rt_properties = ctx.target.instance.runtime_properties + if SSH_KEY in host_rt_properties: + del host_rt_properties[SSH_KEY] + def _remove_key_script(commands, user, ssh_dir, keys_file, public_key): sed_template = " sed -i /{0}/d {1}" @@ -495,7 +500,7 @@ def _build_script(custom, public_keys): def _get_connected_keypairs(): relationships = getattr(ctx.instance, 'relationships', None) if relationships: - return [relationship.target.instance.runtime_properties['public_key'] + return [relationship.target.instance.runtime_properties[PUBLIC_KEY] for relationship in relationships if 'public_key' in relationship.target.instance.runtime_properties] diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 24a8bf4..b031291 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -53,8 +53,7 @@ def test_create(self): fake_ctx = self.generate_node_context( properties={'auto_generate': True, - 'private_key' :{ - 'create_file': True}}) + 'private_key': {'create_file': True}}) keypair.create(ctx=fake_ctx) prop = fake_ctx.instance.runtime_properties self.assertEqual('~/.ssh/test_private.key', From a95c1036cf1b65230984a2eaf1d1c97a79806a15 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 23 Sep 2015 17:50:34 +0300 Subject: [PATCH 129/228] SCOR-216: support SELinux attributes for ssh --- server_plugin/server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server_plugin/server.py b/server_plugin/server.py index 8f60c06..32e62d3 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -518,6 +518,8 @@ def _add_key_script(commands, user, ssh_dir, keys_file, public_key): touch {2} chown {0}:{0} {2} chmod 600 {2} + # make centos with selinux happy + which restorecon && restorecon -Rv {1} fi """ test_ssh_dir = test_ssh_dir_template.format(user, ssh_dir, keys_file) From 8b9aa2e97fbc172bd98d2f6720aae6858eecf3db Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 30 Sep 2015 10:43:39 +0300 Subject: [PATCH 130/228] SCOR-216: add retry operations and check ips on configure step --- network_plugin/__init__.py | 26 +++++++- network_plugin/floatingip.py | 3 +- network_plugin/public_nat.py | 17 ++++- server_plugin/server.py | 102 ++++++++++++++++++++++-------- tests/unittests/test_mock_base.py | 5 +- vcloud_plugin_common/__init__.py | 12 ++-- 6 files changed, 126 insertions(+), 39 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 466fcf4..bd5023c 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -258,7 +258,7 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): new_ip = list(available_ips)[0] ctx.logger.info("Public IP {0} was reused.".format(new_ip)) return new_ip - for i in range(5): + for i in xrange(5): ctx.logger.info("Try to allocate public IP") wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.allocate_public_ip() @@ -325,12 +325,32 @@ def get_gateway(vca_client, gateway_name): def set_retry(ctx): + """ + set retry on cloudify level + """ return ctx.operation.retry( message='Waiting for gateway.', retry_after=GATEWAY_TIMEOUT) +def retry_operation(func): + """ + retry ten times to run funtion with sleep several second between + retry + """ + def f(*args, **kwargs): + for _ in xrange(10): + result = func(*args, **kwargs) + # return only in case successful operation + if result: + return result + time.sleep(GATEWAY_TIMEOUT) + return False + return f + + def save_ssh_parameters(ctx, port, ip): + """save port and ip for ssh to context""" retries_update = 3 update_pending = True while retries_update > 0 and update_pending: @@ -350,7 +370,8 @@ def save_ssh_parameters(ctx, port, ip): def wait_for_gateway(vca_client, gateway_name, ctx): - for i in range(10): + """try ten times to wait 10 seconds for gateway""" + for i in xrange(10): gateway = get_gateway(vca_client, gateway_name) if not gateway.is_busy(): return @@ -361,6 +382,7 @@ def wait_for_gateway(vca_client, gateway_name, ctx): def lock_gateway(f): + """loc gateway before operation""" def update_parameters(ctx, value): ctx.source.instance.runtime_properties[GATEWAY_LOCK] = value ctx.source.instance.update() diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index e3bac1b..2b94ec2 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -23,7 +23,7 @@ CREATE, DELETE, PUBLIC_IP, get_gateway, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, - set_retry, lock_gateway) + set_retry, lock_gateway, retry_operation) @operation @@ -74,6 +74,7 @@ def creation_validation(vca_client, **kwargs): getFreeIP(gateway) +@retry_operation def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index d58947e..1f5b625 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -21,7 +21,8 @@ get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry, lock_gateway) + del_ondemand_public_ip, utils, set_retry, lock_gateway, + retry_operation) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP @@ -120,6 +121,7 @@ def creation_validation(vca_client, **kwargs): "Parameter 'translated_port' must be integer") +@retry_operation def prepare_network_operation(vca_client, operation): """ create nat rules by rules from network node @@ -128,7 +130,13 @@ def prepare_network_operation(vca_client, operation): gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) + if not public_ip: + ctx.logger.info("We dont have public ip. Retrying...") + return False private_ip = _create_ip_range(vca_client, gateway) + if not private_ip: + ctx.logger.info("We dont have private ip. Retrying...") + return False for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] nat_network_operation( @@ -142,6 +150,7 @@ def prepare_network_operation(vca_client, operation): return _save_configuration(gateway, vca_client, operation, public_ip) +@retry_operation def prepare_server_operation(vca_client, operation): """ generate nat rules by current list of rules in node @@ -150,7 +159,13 @@ def prepare_server_operation(vca_client, operation): gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) + if not public_ip: + ctx.logger.info("We dont have public ip. Retrying...") + return False private_ip = get_vm_ip(vca_client, ctx, gateway) + if not private_ip: + ctx.logger.info("We dont have private ip. Retrying...") + return False has_snat = False for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] diff --git a/server_plugin/server.py b/server_plugin/server.py index 32e62d3..7bed4e9 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import time + from cloudify import ctx from cloudify.decorators import operation from cloudify import exceptions as cfy_exc @@ -23,7 +25,7 @@ error_response, STATUS_POWERED_ON) from network_plugin import (get_network_name, get_network, is_network_exists, - get_vapp_name) + get_vapp_name, GATEWAY_TIMEOUT) from network_plugin.keypair import PUBLIC_KEY, SSH_KEY VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -192,6 +194,18 @@ def _create(vca_client, config, server): wait_for_task(vca_client, task) +def _power_on_vm(vca_client, vapp, vapp_name): + """Poweron VM""" + if _vapp_is_on(vapp) is False: + ctx.logger.info("Power-on VApp {0}".format(vapp_name)) + task = vapp.poweron() + if not task: + raise cfy_exc.NonRecoverableError( + "Could not power-on vApp. {0}". + format(error_response(vapp))) + wait_for_task(vca_client, task) + + @operation @with_vca_client def start(vca_client, **kwargs): @@ -206,14 +220,7 @@ def start(vca_client, **kwargs): config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) - if _vapp_is_on(vapp) is False: - ctx.logger.info("Power-on VApp {0}".format(vapp_name)) - task = vapp.poweron() - if not task: - raise cfy_exc.NonRecoverableError( - "Could not power-on vApp. {0}". - format(error_response(vapp))) - wait_for_task(vca_client, task) + _power_on_vm(vca_client, vapp, vapp_name) if not _get_state(vca_client): return ctx.operation.retry( @@ -267,6 +274,21 @@ def delete(vca_client, **kwargs): del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] +def _all_primary_connections_have_ip(vapp): + """Return True in case when all primary interfaces have some ip""" + network_info = vapp.get_vms_network_info() + # we dont have any network, skip checks + if not network_info: + return True + if not network_info[0]: + return True + # we have some networks + for conn in network_info[0]: + if conn['is_connected'] and conn['is_primary'] and conn['ip']: + return True + return False + + @operation @with_vca_client def configure(vca_client, **kwargs): @@ -283,14 +305,16 @@ def configure(vca_client, **kwargs): config = get_vcloud_config() custom = server.get(GUEST_CUSTOMIZATION, {}) public_keys = _get_connected_keypairs() + + vdc = vca_client.get_vdc(config['vdc']) + vapp = vca_client.get_vapp(vdc, vapp_name) + if not vapp: + raise cfy_exc.NonRecoverableError( + "Unable to find vAPP server " + "by its name {0}.".format(vapp_name)) + ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) + if custom or public_keys: - vdc = vca_client.get_vdc(config['vdc']) - vapp = vca_client.get_vapp(vdc, vapp_name) - if not vapp: - raise cfy_exc.NonRecoverableError( - "Unable to find vAPP server " - "by its name {0}.".format(vapp_name)) - ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') @@ -318,12 +342,11 @@ def configure(vca_client, **kwargs): cpu = hardware.get('cpu') memory = hardware.get('memory') _check_hardware(cpu, memory) - vapp = vca_client.get_vapp( - vca_client.get_vdc(config['vdc']), vapp_name - ) if memory: try: - ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) + ctx.logger.info( + "Customize VM memory: '{0}'.".format(memory) + ) task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) except Exception: @@ -332,7 +355,9 @@ def configure(vca_client, **kwargs): format(task, error_response(vapp))) if cpu: try: - ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) + ctx.logger.info( + "Customize VM cpu: '{0}'.".format(cpu) + ) task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) except Exception: @@ -340,6 +365,21 @@ def configure(vca_client, **kwargs): "Customize VM cpu failed: '{0}'. {1}". format(task, error_response(vapp))) + if not _all_primary_connections_have_ip(vapp): + ctx.logger.info("Power on server for get dhcp ip.") + # we have to start vapp before continue + _power_on_vm(vca_client, vapp, vapp_name) + for attempt in xrange(20): + vapp = vca_client.get_vapp(vdc, vapp_name) + if _all_primary_connections_have_ip(vapp): + return + ctx.logger.info( + "No ip assigned. Retrying... {}/20 attempt." + .format(attempt + 1) + ) + time.sleep(GATEWAY_TIMEOUT) + ctx.logger.info("We dont recieve ip for 10 minutes") + @operation @with_vca_client @@ -347,10 +387,12 @@ def remove_keys(vca_client, **kwargs): ctx.logger.info("Remove public keys from VM.") relationships = getattr(ctx.target.instance, 'relationships', None) if relationships: - public_keys = [relationship.target.instance.runtime_properties['public_key'] - for relationship in relationships - if 'public_key' in - relationship.target.instance.runtime_properties] + public_keys = [ + relationship.target.instance.runtime_properties['public_key'] + for relationship in relationships + if 'public_key' in + relationship.target.instance.runtime_properties + ] else: return vdc = vca_client.get_vdc(get_vcloud_config()['vdc']) @@ -401,8 +443,9 @@ def remove_keys(vca_client, **kwargs): def _remove_key_script(commands, user, ssh_dir, keys_file, public_key): sed_template = " sed -i /{0}/d {1}" - commands.append(sed_template.format(public_key.split()[1].replace('/', '[/]'), - keys_file)) + commands.append(sed_template.format( + public_key.split()[1].replace('/', '[/]'), keys_file) + ) def _get_state(vca_client): @@ -413,6 +456,7 @@ def _get_state(vca_client): config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) + nw_connections = _get_vm_network_connections(vapp) if len(nw_connections) == 0: ctx.logger.info("No networks connected") @@ -546,7 +590,9 @@ def _build_public_keys_script(public_keys, script_function): home = '' if user == 'root' else DEFAULT_HOME ssh_dir = ssh_dir_template.format(home, user) authorized_keys = authorized_keys_template.format(ssh_dir) - script_function(key_commands, user, ssh_dir, authorized_keys, public_key) + script_function( + key_commands, user, ssh_dir, authorized_keys, public_key + ) return "\n".join(key_commands) diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index d3bac29..fbc7267 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -334,7 +334,10 @@ def generate_vca(self): def generate_vapp(self, vms_networks=None): def _get_vms_network_info(): - return [vms_networks] + if vms_networks: + return [vms_networks] + else: + return [[]] vapp = mock.Mock() vapp.me = mock.Mock() diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index b91a334..27d0368 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -340,7 +340,7 @@ def _private_login(self, url, username, password, token, org_name, version=api_version) if logined is False and password: - for _ in range(LOGIN_RETRY_NUM): + for _ in xrange(LOGIN_RETRY_NUM): logined = vca.login(password, org=org_name) if logined is False: ctx.logger.info("Login using password failed. Retrying...") @@ -358,7 +358,7 @@ def _private_login(self, url, username, password, token, org_name, # Private mode requires being logged in with a token otherwise you # don't seem to be able to retrieve any VDCs if token: - for _ in range(LOGIN_RETRY_NUM): + for _ in xrange(LOGIN_RETRY_NUM): logined = vca.login(token=token, org_url=org_url) if logined is False: ctx.logger.info("Login using token failed.") @@ -417,7 +417,7 @@ def wait_for_task(vca_client, task): ctx.logger.debug('Task recheck after {0} seconds.' .format(TASK_RECHECK_TIMEOUT)) status = task.get_status() - for attempt in range(MAX_ATTEMPTS): + for attempt in xrange(MAX_ATTEMPTS): ctx.logger.debug('Attempt: {0}/{1}.'.format(attempt + 1, MAX_ATTEMPTS)) if status == TASK_STATUS_SUCCESS: ctx.logger.debug('Task completed in {0} seconds' @@ -493,7 +493,7 @@ def error_response(obj): def session_login(vca, org_url, session_token, version): vcs = vcloudair.VCS(org_url, None, None, None, org_url, org_url, version) - for _ in range(LOGIN_RETRY_NUM): + for _ in xrange(LOGIN_RETRY_NUM): if not vcs.login(token=session_token): ctx.logger.info("Login using session token failed.") time.sleep(RELOGIN_TIMEOUT) @@ -506,7 +506,7 @@ def session_login(vca, org_url, session_token, version): def login_to_vca_with_token(vca, org_url, session_token, version): - for _ in range(LOGIN_RETRY_NUM): + for _ in xrange(LOGIN_RETRY_NUM): logined = session_login(vca, org_url, session_token, version) if logined is False: ctx.logger.info("Login using session token failed.") @@ -517,7 +517,7 @@ def login_to_vca_with_token(vca, org_url, session_token, version): def login_with_retry(function, arguments, message): - for _ in range(LOGIN_RETRY_NUM): + for _ in xrange(LOGIN_RETRY_NUM): logined = function(*arguments) if logined is False: ctx.logger.info("{0} failed. Retrying...".format(message)) From 03d2dc64d75079623187367a5f51aab91471bafa Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 30 Sep 2015 12:21:28 +0300 Subject: [PATCH 131/228] SCOR-216: delete retry_operation and use cloudify version of retry --- network_plugin/__init__.py | 28 ++++++++-------------------- network_plugin/floatingip.py | 3 +-- network_plugin/public_nat.py | 5 +---- server_plugin/server.py | 18 +++++++++--------- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index bd5023c..8e0236c 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -37,11 +37,15 @@ BUSY_MESSAGE = "is busy completing an operation" GATEWAY_TIMEOUT = 30 +# try n times before fail +RETRY_COUNT = 10 +# sleep n seconds before retry +RETRY_SLEEP = 10 def check_ip(address): """ - check ip + check ip format """ try: IP(address) @@ -258,7 +262,7 @@ def get_ondemand_public_ip(vca_client, gateway, ctx): new_ip = list(available_ips)[0] ctx.logger.info("Public IP {0} was reused.".format(new_ip)) return new_ip - for i in xrange(5): + for i in xrange(RETRY_COUNT): ctx.logger.info("Try to allocate public IP") wait_for_gateway(vca_client, gateway.get_name(), ctx) task = gateway.allocate_public_ip() @@ -333,22 +337,6 @@ def set_retry(ctx): retry_after=GATEWAY_TIMEOUT) -def retry_operation(func): - """ - retry ten times to run funtion with sleep several second between - retry - """ - def f(*args, **kwargs): - for _ in xrange(10): - result = func(*args, **kwargs) - # return only in case successful operation - if result: - return result - time.sleep(GATEWAY_TIMEOUT) - return False - return f - - def save_ssh_parameters(ctx, port, ip): """save port and ip for ssh to context""" retries_update = 3 @@ -371,12 +359,12 @@ def save_ssh_parameters(ctx, port, ip): def wait_for_gateway(vca_client, gateway_name, ctx): """try ten times to wait 10 seconds for gateway""" - for i in xrange(10): + for i in xrange(RETRY_COUNT): gateway = get_gateway(vca_client, gateway_name) if not gateway.is_busy(): return ctx.logger.info("Check {0}. Gateway is busy.".format(i)) - time.sleep(10) + time.sleep(RETRY_SLEEP) raise cfy_exc.NonRecoverableError( "Can't wait gateway {0}".format(gateway_name)) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index 2b94ec2..e3bac1b 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -23,7 +23,7 @@ CREATE, DELETE, PUBLIC_IP, get_gateway, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, get_public_ip, del_ondemand_public_ip, - set_retry, lock_gateway, retry_operation) + set_retry, lock_gateway) @operation @@ -74,7 +74,6 @@ def creation_validation(vca_client, **kwargs): getFreeIP(gateway) -@retry_operation def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with diff --git a/network_plugin/public_nat.py b/network_plugin/public_nat.py index 1f5b625..c35856f 100644 --- a/network_plugin/public_nat.py +++ b/network_plugin/public_nat.py @@ -21,8 +21,7 @@ get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry, lock_gateway, - retry_operation) + del_ondemand_public_ip, utils, set_retry, lock_gateway) from network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP @@ -121,7 +120,6 @@ def creation_validation(vca_client, **kwargs): "Parameter 'translated_port' must be integer") -@retry_operation def prepare_network_operation(vca_client, operation): """ create nat rules by rules from network node @@ -150,7 +148,6 @@ def prepare_network_operation(vca_client, operation): return _save_configuration(gateway, vca_client, operation, public_ip) -@retry_operation def prepare_server_operation(vca_client, operation): """ generate nat rules by current list of rules in node diff --git a/server_plugin/server.py b/server_plugin/server.py index 7bed4e9..8c796cf 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -25,7 +25,7 @@ error_response, STATUS_POWERED_ON) from network_plugin import (get_network_name, get_network, is_network_exists, - get_vapp_name, GATEWAY_TIMEOUT) + get_vapp_name, GATEWAY_TIMEOUT, RETRY_COUNT) from network_plugin.keypair import PUBLIC_KEY, SSH_KEY VCLOUD_VAPP_NAME = 'vcloud_vapp_name' @@ -274,8 +274,8 @@ def delete(vca_client, **kwargs): del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] -def _all_primary_connections_have_ip(vapp): - """Return True in case when all primary interfaces have some ip""" +def _is_primary_connection_has_ip(vapp): + """Return True in case when primary interface has some ip""" network_info = vapp.get_vms_network_info() # we dont have any network, skip checks if not network_info: @@ -365,20 +365,20 @@ def configure(vca_client, **kwargs): "Customize VM cpu failed: '{0}'. {1}". format(task, error_response(vapp))) - if not _all_primary_connections_have_ip(vapp): + if not _is_primary_connection_has_ip(vapp): ctx.logger.info("Power on server for get dhcp ip.") # we have to start vapp before continue _power_on_vm(vca_client, vapp, vapp_name) - for attempt in xrange(20): + for attempt in xrange(RETRY_COUNT): vapp = vca_client.get_vapp(vdc, vapp_name) - if _all_primary_connections_have_ip(vapp): + if _is_primary_connection_has_ip(vapp): return ctx.logger.info( - "No ip assigned. Retrying... {}/20 attempt." - .format(attempt + 1) + "No ip assigned. Retrying... {}/{} attempt." + .format(attempt + 1, RETRY_COUNT) ) time.sleep(GATEWAY_TIMEOUT) - ctx.logger.info("We dont recieve ip for 10 minutes") + ctx.logger.info("We dont recieve ip, try next time...") @operation From 7bebb131a45fe5764760069b8d92ccb680f1d088 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 2 Oct 2015 10:23:16 +0400 Subject: [PATCH 132/228] Don't delete keys from keypair node. Use curl instead of wget for downloading docker --- manager_blueprint/scripts/configure.py | 3 +-- network_plugin/keypair.py | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/manager_blueprint/scripts/configure.py b/manager_blueprint/scripts/configure.py index e96bb14..e416ff9 100644 --- a/manager_blueprint/scripts/configure.py +++ b/manager_blueprint/scripts/configure.py @@ -55,8 +55,7 @@ def _install_docker(): kernel_version = fabric.api.run( 'python -c "import platform; print platform.release()"') if kernel_version.startswith("3.13") and 'Ubuntu' in distro: - fabric.api.run("wget -qO- https://get.docker.com/ | sudo sh") - + fabric.api.run("curl -sSL https://get.docker.com/ | sudo sh") def _save_context(): """ diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index edd2747..d890d15 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -67,9 +67,9 @@ def create(**kwargs): ctx.node.properties.get(PUBLIC_KEY, {}).get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = \ ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY) + ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ + ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ - ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], @@ -97,15 +97,12 @@ def server_connect_to_keypair(**kwargs): target_rt_properties = ctx.target.instance.runtime_properties if SSH_KEY not in host_rt_properties: host_rt_properties[SSH_KEY] = {} - host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) - host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) - host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) - ctx.source.instance.update() if PRIVATE_KEY in target_rt_properties: - del target_rt_properties[PRIVATE_KEY] + host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) + host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) if PUBLIC_KEY in target_rt_properties: - del target_rt_properties[PUBLIC_KEY] - ctx.target.instance.update() + host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + ctx.source.instance.update() @operation From ab60d07d368cf6dcd903ed38a6a3976a08f292f3 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 2 Oct 2015 16:01:46 +0300 Subject: [PATCH 133/228] SCOR-216: use try block also for lock operation --- network_plugin/__init__.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 8e0236c..f1693d4 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -383,19 +383,19 @@ def wrapper(*args, **kw): if ctx.source.instance.runtime_properties.get(GATEWAY_LOCK): ctx.logger.info("Gateway locked.") return set_retry(ctx) - ctx.logger.info("Lock gateway.") - update_parameters(ctx, True) - vca_client = kw['vca_client'] - gateway_name = get_vcloud_config().get('edge_gateway') - if gateway_name: - wait_for_gateway(vca_client, gateway_name, ctx) - else: - # we need gateway_name from vcloud for use this functionality - ctx.logger.info( - "'edge_gateway' in vcloud_config is empty." + - " Can't check state of gateway correctly." - ) try: + ctx.logger.info("Lock gateway.") + update_parameters(ctx, True) + vca_client = kw['vca_client'] + gateway_name = get_vcloud_config().get('edge_gateway') + if gateway_name: + wait_for_gateway(vca_client, gateway_name, ctx) + else: + # we need gateway_name from vcloud for use this functionality + ctx.logger.info( + "'edge_gateway' in vcloud_config is empty." + + " Can't check state of gateway correctly." + ) result = f(*args, **kw) finally: ctx.logger.info("Unlock gateway.") From d8fe5630af8ecdcd1c5cdea065ee16217a6f9dff Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 2 Oct 2015 16:34:44 +0300 Subject: [PATCH 134/228] SCOR-216: pep8 fix --- manager_blueprint/scripts/configure.py | 1 + 1 file changed, 1 insertion(+) diff --git a/manager_blueprint/scripts/configure.py b/manager_blueprint/scripts/configure.py index e416ff9..571e69e 100644 --- a/manager_blueprint/scripts/configure.py +++ b/manager_blueprint/scripts/configure.py @@ -57,6 +57,7 @@ def _install_docker(): if kernel_version.startswith("3.13") and 'Ubuntu' in distro: fabric.api.run("curl -sSL https://get.docker.com/ | sudo sh") + def _save_context(): """ save current managment network for use as default network for From fac4a85d96d5fbb17c28c38d70580b66c73f7a3c Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 13 Oct 2015 15:10:01 +0400 Subject: [PATCH 135/228] Save private key path to agent installer --- network_plugin/__init__.py | 3 ++- network_plugin/keypair.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 26a0d84..3141b87 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -36,7 +36,8 @@ AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') BUSY_MESSAGE = "is busy completing an operation" -GATEWAY_TIMEOUT = 30# try n times before fail +GATEWAY_TIMEOUT = 30 +# try n times before fail RETRY_COUNT = 10 # sleep n seconds before retry RETRY_SLEEP = 10 diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index d890d15..09d1e9b 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -24,6 +24,7 @@ PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' CREATE_PRIVATE_KEY_FILE = 'create_file' +CLOUDIFY_AGENT = 'cloudify_agent' PATH = 'path' KEY = 'key' USER = 'user' @@ -102,6 +103,9 @@ def server_connect_to_keypair(**kwargs): host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) if PUBLIC_KEY in target_rt_properties: host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + if target_rt_properties[PRIVATE_KEY].get(PATH): + host_rt_properties[CLOUDIFY_AGENT] = {} + host_rt_properties[CLOUDIFY_AGENT][KEY] = target_rt_properties[PRIVATE_KEY].get(PATH) ctx.source.instance.update() @@ -110,6 +114,8 @@ def server_disconnect_from_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY in host_rt_properties: del host_rt_properties[SSH_KEY] + if CLOUDIFY_AGENT in host_rt_properties: + del host_rt_properties[CLOUDIFY_AGENT] def _generate_pair(): From a04f1d97035252282bd393820cd8479d4d03d9eb Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 6 Oct 2015 13:12:55 +0400 Subject: [PATCH 136/228] Check gateway lock for all nodes --- network_plugin/__init__.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index f1693d4..fe57545 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -21,7 +21,7 @@ from cloudify_rest_client import exceptions as rest_exceptions import time from functools import wraps - +from cloudify.manager import get_rest_client VCLOUD_VAPP_NAME = 'vcloud_vapp_name' PUBLIC_IP = 'public_ip' @@ -369,6 +369,20 @@ def wait_for_gateway(vca_client, gateway_name, ctx): "Can't wait gateway {0}".format(gateway_name)) +def _is_gateway_locked(ctx): + if ctx.deployment.id == 'local': + storage = ctx.internal.handler.storage + node_instances = storage.get_node_instances() + else: + rest = get_rest_client() + node_instances = rest.node_instances.list(ctx.deployment.id) + for instance in node_instances: + rt_properties = instance['runtime_properties'] + if rt_properties.get(GATEWAY_LOCK): + return True + return False + + def lock_gateway(f): """loc gateway before operation""" def update_parameters(ctx, value): @@ -379,8 +393,8 @@ def update_parameters(ctx, value): def wrapper(*args, **kw): ctx = kw['ctx'] # Reset for getting last version of runtime_properties - ctx.source.instance._node_instance = None - if ctx.source.instance.runtime_properties.get(GATEWAY_LOCK): + #ctx.source.instance._node_instance = None + if _is_gateway_locked(ctx): ctx.logger.info("Gateway locked.") return set_retry(ctx) try: From 1c6c3829d9312301f0a9ff0afc378a87b8d26b5f Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 8 Oct 2015 10:03:55 +0400 Subject: [PATCH 137/228] Fix retry loop, when Public IP absent. --- network_plugin/floatingip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network_plugin/floatingip.py b/network_plugin/floatingip.py index e3bac1b..6f7f806 100644 --- a/network_plugin/floatingip.py +++ b/network_plugin/floatingip.py @@ -99,7 +99,7 @@ def _floatingip_operation(operation, vca_client, ctx): elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) - return + return True nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( From 96e3057313113546ea75c3e0a6f5610ce453eb8e Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 8 Oct 2015 11:26:56 +0400 Subject: [PATCH 138/228] Don't lock gateway in bootstrap --- network_plugin/__init__.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index fe57545..f62cd71 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -370,12 +370,18 @@ def wait_for_gateway(vca_client, gateway_name, ctx): def _is_gateway_locked(ctx): - if ctx.deployment.id == 'local': + rest = None + try: + rest = get_rest_client() + except KeyError: + pass + if rest: + node_instances = rest.node_instances.list(ctx.deployment.id) + elif ctx.deployment.id == 'local': storage = ctx.internal.handler.storage node_instances = storage.get_node_instances() else: - rest = get_rest_client() - node_instances = rest.node_instances.list(ctx.deployment.id) + return False for instance in node_instances: rt_properties = instance['runtime_properties'] if rt_properties.get(GATEWAY_LOCK): @@ -392,8 +398,6 @@ def update_parameters(ctx, value): @wraps(f) def wrapper(*args, **kw): ctx = kw['ctx'] - # Reset for getting last version of runtime_properties - #ctx.source.instance._node_instance = None if _is_gateway_locked(ctx): ctx.logger.info("Gateway locked.") return set_retry(ctx) From 370c5da6a19f9510909b6ad78b54a554ccac521e Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Mon, 12 Oct 2015 13:07:20 +0400 Subject: [PATCH 139/228] Fix gateway lock check in local execution --- network_plugin/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index f62cd71..26a0d84 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -36,8 +36,7 @@ AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') BUSY_MESSAGE = "is busy completing an operation" -GATEWAY_TIMEOUT = 30 -# try n times before fail +GATEWAY_TIMEOUT = 30# try n times before fail RETRY_COUNT = 10 # sleep n seconds before retry RETRY_SLEEP = 10 @@ -378,7 +377,7 @@ def _is_gateway_locked(ctx): if rest: node_instances = rest.node_instances.list(ctx.deployment.id) elif ctx.deployment.id == 'local': - storage = ctx.internal.handler.storage + storage = ctx._endpoint.storage node_instances = storage.get_node_instances() else: return False From 22cfbb5644880c9e09bc149c75bd5069ab729a6e Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 13 Oct 2015 15:10:01 +0400 Subject: [PATCH 140/228] Save private key path to agent installer Move server_connect_to_keypair to postconfigure --- network_plugin/__init__.py | 3 ++- network_plugin/keypair.py | 6 ++++++ plugin.yaml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 26a0d84..3141b87 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -36,7 +36,8 @@ AssignedIPs = collections.namedtuple('AssignedIPs', 'external internal') BUSY_MESSAGE = "is busy completing an operation" -GATEWAY_TIMEOUT = 30# try n times before fail +GATEWAY_TIMEOUT = 30 +# try n times before fail RETRY_COUNT = 10 # sleep n seconds before retry RETRY_SLEEP = 10 diff --git a/network_plugin/keypair.py b/network_plugin/keypair.py index d890d15..09d1e9b 100644 --- a/network_plugin/keypair.py +++ b/network_plugin/keypair.py @@ -24,6 +24,7 @@ PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' CREATE_PRIVATE_KEY_FILE = 'create_file' +CLOUDIFY_AGENT = 'cloudify_agent' PATH = 'path' KEY = 'key' USER = 'user' @@ -102,6 +103,9 @@ def server_connect_to_keypair(**kwargs): host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) if PUBLIC_KEY in target_rt_properties: host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + if target_rt_properties[PRIVATE_KEY].get(PATH): + host_rt_properties[CLOUDIFY_AGENT] = {} + host_rt_properties[CLOUDIFY_AGENT][KEY] = target_rt_properties[PRIVATE_KEY].get(PATH) ctx.source.instance.update() @@ -110,6 +114,8 @@ def server_disconnect_from_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY in host_rt_properties: del host_rt_properties[SSH_KEY] + if CLOUDIFY_AGENT in host_rt_properties: + del host_rt_properties[CLOUDIFY_AGENT] def _generate_pair(): diff --git a/plugin.yaml b/plugin.yaml index ccabb8b..8feda7a 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -249,7 +249,7 @@ relationships: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: - establish: + postconfigure: implementation: vcloud.network_plugin.keypair.server_connect_to_keypair inputs: {} unlink: From 6acb668e9bffda5ed4374b6ceb988f708b486eac Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 16 Oct 2015 10:04:31 +0300 Subject: [PATCH 141/228] use 3.3m7/3.3a7 versions --- examples/blueprint.yaml | 6 +++--- setup.py | 4 ++-- tests/integration/blueprints/header.yaml | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index ef9c801..3e543a4 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,8 +1,8 @@ -tosca_definitions_version: cloudify_dsl_1_0 +tosca_definitions_version: cloudify_dsl_1_2 imports: - - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3m4/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/3.3m7/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3m7/plugin.yaml node_types: vcloud_configuration: diff --git a/setup.py b/setup.py index e4f2da8..ab08ac1 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3m5', + version='1.3a7', packages=[ 'vcloud_plugin_common', 'server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3a4', + 'cloudify-plugins-common>=3.3a7', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', diff --git a/tests/integration/blueprints/header.yaml b/tests/integration/blueprints/header.yaml index 619ffa8..ed6b415 100644 --- a/tests/integration/blueprints/header.yaml +++ b/tests/integration/blueprints/header.yaml @@ -1,10 +1,9 @@ -tosca_definitions_version: cloudify_dsl_1_0 +tosca_definitions_version: cloudify_dsl_1_2 imports: - http://s3.amazonaws.com/vcloud-score/types.yaml -# - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.3m4/plugin.yaml + - http://www.getcloudify.org/spec/fabric-plugin/1.3m7/plugin.yaml inputs: username: From c1a20a111e4b30023042d707de80d2acd6a17d92 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 19 Oct 2015 18:01:40 +0300 Subject: [PATCH 142/228] allow self-signed certificates for private cloud --- vcloud_plugin_common/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 27d0368..800b817 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -160,6 +160,7 @@ def connect(self, cfg): service_type = cfg.get('service_type', SUBSCRIPTION_SERVICE_TYPE) instance = cfg.get('instance') org_url = cfg.get(ORG_URL, None) + verify = cfg.get('ssl_verify', True) api_version = cfg.get('api_version', '5.6') session_token = cfg.get(SESSION_TOKEN) org_url = cfg.get(ORG_URL) @@ -184,7 +185,8 @@ def connect(self, cfg): # 'private' as well, for user friendliness of inputs elif service_type in (PRIVATE_SERVICE_TYPE, 'private'): vcloud_air = self._private_login( - url, username, password, token, org_name, org_url, api_version) + url, username, password, token, org_name, org_url, + api_version, verify) else: raise cfy_exc.NonRecoverableError( "Unrecognized service type: {0}".format(service_type)) @@ -327,7 +329,7 @@ def get_instance(vca, instance_id): return vca def _private_login(self, url, username, password, token, org_name, - org_url=None, api_version='5.6'): + org_url=None, api_version='5.6', verify=True): """ login to private instance """ @@ -337,7 +339,8 @@ def _private_login(self, url, username, password, token, org_name, host=url, username=username, service_type=PRIVATE_SERVICE_TYPE, - version=api_version) + version=api_version, + verify=verify) if logined is False and password: for _ in xrange(LOGIN_RETRY_NUM): From db233b63cdf27353bef1a491c59db80f7b9d3b09 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 21 Oct 2015 14:31:44 +0300 Subject: [PATCH 143/228] Optimization for private cloud with old cloud version --- network_plugin/__init__.py | 4 +- server_plugin/server.py | 84 +++++++++++-------- setup.py | 2 +- tests/unittests/test_mock_base.py | 6 ++ tests/unittests/test_mock_network_plugin.py | 7 +- .../test_mock_network_plugin_public_nat.py | 2 +- .../test_mock_server_plugin_server.py | 35 ++++++-- .../test_mock_vcloud_plugin_common.py | 7 +- ...st_mock_vcloud_plugin_common_vca_client.py | 4 +- vcloud_plugin_common/__init__.py | 4 +- 10 files changed, 100 insertions(+), 55 deletions(-) diff --git a/network_plugin/__init__.py b/network_plugin/__init__.py index 3141b87..5b052d1 100644 --- a/network_plugin/__init__.py +++ b/network_plugin/__init__.py @@ -17,7 +17,7 @@ import collections from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType from vcloud_plugin_common import (wait_for_task, get_vcloud_config, - is_subscription, error_response) + is_ondemand, error_response) from cloudify_rest_client import exceptions as rest_exceptions import time from functools import wraps @@ -308,7 +308,7 @@ def get_public_ip(vca_client, gateway, service_type, ctx): """ return new public ip """ - if is_subscription(service_type): + if not is_ondemand(service_type): public_ip = getFreeIP(gateway) ctx.logger.info("Assign external IP {0}".format(public_ip)) else: diff --git a/server_plugin/server.py b/server_plugin/server.py index 8c796cf..4fe8181 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -140,24 +140,30 @@ def _create(vca_client, config, server): task = vca_client.create_vapp(config['vdc'], vapp_name, vapp_template, - vapp_catalog, - vm_name=vapp_name) + vapp_catalog) if not task: raise cfy_exc.NonRecoverableError("Could not create vApp: {0}" .format(error_response(vca_client))) wait_for_task(vca_client, task) + vdc = vca_client.get_vdc(config['vdc']) + vapp = vca_client.get_vapp(vdc, vapp_name) + if vapp is None: + raise cfy_exc.NonRecoverableError( + "vApp '{0}' could not be found".format(vapp_name)) + + task = vapp.modify_vm_name(1, vapp_name) + if not task: + raise cfy_exc.NonRecoverableError( + "Can't modyfy VM name".format(vapp_name)) + wait_for_task(vca_client, task) + ctx.logger.info("VM '{0}' has been renamed.".format(vapp_name)) + ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = vapp_name # we allways have connection to management_network_name if connections: for index, connection in enumerate(connections): - vdc = vca_client.get_vdc(config['vdc']) - vapp = vca_client.get_vapp(vdc, vapp_name) - if vapp is None: - raise cfy_exc.NonRecoverableError( - "vApp '{0}' could not be found".format(vapp_name)) - network_name = connection.get('network') network = get_network(vca_client, network_name) ctx.logger.info("Connect network '{0}' to server '{1}'." @@ -314,29 +320,6 @@ def configure(vca_client, **kwargs): "by its name {0}.".format(vapp_name)) ctx.logger.info("Using vAPP {0}".format(str(vapp_name))) - if custom or public_keys: - script = _build_script(custom, public_keys) - password = custom.get('admin_password') - computer_name = custom.get('computer_name') - ctx.logger.info("Customizing guest OS.") - task = vapp.customize_guest_os( - vapp_name, - customization_script=script, - computer_name=computer_name, - admin_password=password - ) - if task is None: - raise cfy_exc.NonRecoverableError( - "Could not set guest customization parameters. {0}". - format(error_response(vapp))) - wait_for_task(vca_client, task) - if vapp.customize_on_next_poweron(): - ctx.logger.info("Customizations successful") - else: - raise cfy_exc.NonRecoverableError( - "Can't run customization in next power on. {0}". - format(error_response(vapp))) - hardware = server.get('hardware') if hardware: cpu = hardware.get('cpu') @@ -365,6 +348,34 @@ def configure(vca_client, **kwargs): "Customize VM cpu failed: '{0}'. {1}". format(task, error_response(vapp))) + if custom or public_keys: + script = _build_script(custom, public_keys) + password = custom.get('admin_password') + computer_name = custom.get('computer_name') + ctx.logger.info("Customizing guest OS.") + task = vapp.customize_guest_os( + vapp_name, + customization_script=script, + computer_name=computer_name, + admin_password=password + ) + if task is None: + raise cfy_exc.NonRecoverableError( + "Could not set guest customization parameters. {0}". + format(error_response(vapp))) + wait_for_task(vca_client, task) + if vapp.customize_on_next_poweron(): + ctx.logger.info("Customizations successful") + else: + customization_task = vapp.force_customization(vapp_name) + if customization_task: + ctx.logger.info("Customizations forced") + wait_for_task(vca_client, customization_task) + else: + raise cfy_exc.NonRecoverableError( + "Can't run customization in next power on. {0}". + format(error_response(vapp))) + if not _is_primary_connection_has_ip(vapp): ctx.logger.info("Power on server for get dhcp ip.") # we have to start vapp before continue @@ -424,9 +435,14 @@ def remove_keys(vca_client, **kwargs): if vapp.customize_on_next_poweron(): ctx.logger.info("Customizations successful.") else: - raise cfy_exc.NonRecoverableError( - "Can't run customization on next power on. {0}.". - format(error_response(vapp))) + customization_task = vapp.force_customization(vapp_name) + if customization_task: + ctx.logger.info("Customizations forced") + wait_for_task(vca_client, customization_task) + else: + raise cfy_exc.NonRecoverableError( + "Can't run customization on next power on. {0}.". + format(error_response(vapp))) vapp = vca_client.get_vapp(vdc, vapp_name) task = vapp.poweron() if not task: diff --git a/setup.py b/setup.py index ab08ac1..a574621 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3a7', + 'cloudify-plugins-common>=3.3a6', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index fbc7267..9a27deb 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -356,13 +356,19 @@ def _get_vms_network_info(): vapp.modify_vm_cpu = mock.MagicMock( return_value=None ) + vapp.modify_vm_name = mock.MagicMock( + return_value=None + ) + return vapp def generate_relation_context(self): source = mock.Mock() source.node = mock.Mock() + source.node.properties = {} target = mock.Mock() target.node = mock.Mock() + target.node.properties = {} target.instance.runtime_properties = {} fake_ctx = MockToscaCloudifyContext( source=source, target=target diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index dabc3d0..2baa818 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -172,7 +172,7 @@ def test_del_ondemand_public_ip(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): network_plugin.del_ondemand_public_ip( fake_client, gateway, '127.0.0.1', fake_ctx) @@ -184,6 +184,7 @@ def test_save_gateway_configuration(self): """ gateway = self.generate_gateway() fake_client = self.generate_client() + fake_ctx = self.generate_node_context() # cant save configuration - error in first call self.set_services_conf_result( gateway, None @@ -197,14 +198,14 @@ def test_save_gateway_configuration(self): gateway, vcloud_plugin_common.TASK_STATUS_ERROR ) with self.assertRaises(cfy_exc.NonRecoverableError): - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx) # everything fine self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertTrue( network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx)) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index e553792..a093189 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -408,7 +408,7 @@ def _ip_exist_in_runtime(fake_ctx): 'network_plugin.public_nat.ctx', fake_ctx ): # success save configuration - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): public_nat._save_configuration( gateway, fake_client, network_plugin.CREATE, "1.2.3.4") self.assertEqual( diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 85e6acd..fee8368 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -269,9 +269,7 @@ def test_create_default_values(self): fake_ctx.instance._relationships = None with self.assertRaises(cfy_exc.NonRecoverableError): server.create(ctx=fake_ctx) - fake_client.create_vapp.assert_called_with( - 'vdc_name', 'test', 'template', 'catalog', - vm_name='test') + self.check_create_call(fake_client, fake_ctx) def test_create_cpu_mem_values(self): """ @@ -330,14 +328,24 @@ def test_create_cpu_mem_values(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) + fake_client._vapp.modify_vm_name = mock.MagicMock( + return_value=self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) # everything fine server.create(ctx=fake_ctx) + fake_client._vapp.modify_vm_name.assert_called_with( + 1, 'test' + ) - def check_create_call(self, fake_client, fake_ctx): + def check_create_call(self, fake_client, fake_ctx, positive=True): fake_client.create_vapp.assert_called_with( - 'vdc_name', 'test', 'template', 'catalog', - vm_name='test') - self.assertTrue( + 'vdc_name', 'test', 'template', 'catalog' + ) + + self.assertEqual( + positive, server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties ) @@ -558,8 +566,16 @@ def test_create_link_success(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - server.create(ctx=fake_ctx) + # can't change vapp_name + with self.assertRaises(cfy_exc.NonRecoverableError): + server.create(ctx=fake_ctx) self.check_create_call(fake_client, fake_ctx) + fake_client._vapp.modify_vm_name = mock.MagicMock( + return_value=self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + ) + server.create(ctx=fake_ctx) def test_create_customization(self): """ @@ -616,6 +632,9 @@ def test_create_customization_un_customized(self): fake_client._vapp.customize_on_next_poweron = mock.MagicMock( return_value=None ) + fake_client._vapp.force_customization = mock.MagicMock( + return_value=None + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 3439227..bf2ae5d 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -178,18 +178,19 @@ def test_is_ondemand(self): def test_wait_for_task(self): fake_client = self.generate_client() + fake_ctx = self.generate_node_context() # error in task fake_task = self.generate_task( vcloud_plugin_common.TASK_STATUS_ERROR ) - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): vcloud_plugin_common.wait_for_task(fake_client, fake_task) # success in task fake_task = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS ) - with mock.patch('vcloud_plugin_common.ctx', mock.MagicMock()): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): vcloud_plugin_common.wait_for_task(fake_client, fake_task) # success after wait fake_task = self.generate_task( @@ -213,7 +214,7 @@ def test_wait_for_task(self): sleep ): with mock.patch('vcloud_plugin_common.ctx', - mock.MagicMock()): + fake_ctx): vcloud_plugin_common.wait_for_task( fake_client, fake_task) diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 079186e..20576fb 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -255,7 +255,7 @@ def _run( fake_vca_client.assert_called_with( service_type='vcd', username='root', host='some_url', - version='upstream' + version='upstream', verify=True ) fake_client.login.assert_called_with( token='secret_token', org_url='org_url' @@ -270,7 +270,7 @@ def _run( fake_vca_client.assert_called_with( service_type='vcd', username='root', host='some_url', - version='upstream' + version='upstream', verify=True ) fake_client.login.assert_called_with( 'secret_password', org='org_name' diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 800b817..a969149 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -420,6 +420,7 @@ def wait_for_task(vca_client, task): ctx.logger.debug('Task recheck after {0} seconds.' .format(TASK_RECHECK_TIMEOUT)) status = task.get_status() + config = get_vcloud_config() for attempt in xrange(MAX_ATTEMPTS): ctx.logger.debug('Attempt: {0}/{1}.'.format(attempt + 1, MAX_ATTEMPTS)) if status == TASK_STATUS_SUCCESS: @@ -433,7 +434,8 @@ def wait_for_task(vca_client, task): time.sleep(TASK_RECHECK_TIMEOUT) response = requests.get( task.get_href(), - headers=vca_client.vcloud_session.get_vcloud_headers()) + headers=vca_client.vcloud_session.get_vcloud_headers(), + verify=config.get('ssl_verify', True)) task = taskType.parseString(response.content, True) status = task.get_status() raise cfy_exc.NonRecoverableError("Wait for task timeout.") From c133d3d8757177df762690b22572d4a5f784185e Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 21 Oct 2015 16:14:55 +0300 Subject: [PATCH 144/228] add reread vapp before connect network --- server_plugin/server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server_plugin/server.py b/server_plugin/server.py index 4fe8181..352f686 100644 --- a/server_plugin/server.py +++ b/server_plugin/server.py @@ -159,6 +159,8 @@ def _create(vca_client, config, server): wait_for_task(vca_client, task) ctx.logger.info("VM '{0}' has been renamed.".format(vapp_name)) + # reread vapp + vapp = vca_client.get_vapp(vdc, vapp_name) ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = vapp_name # we allways have connection to management_network_name From 7a6fdee03a67989ad00a1fff60072bea83d3da32 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 22 Oct 2015 09:22:51 +0400 Subject: [PATCH 145/228] Create implementation for system tests. --- system_tests/manager/__init__.py | 25 ++++++++++++++++ system_tests/manager/nodecellar_test.py | 39 +++++++++++++++++++++++++ system_tests/vcloud_handler.py | 16 +++++----- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 system_tests/manager/__init__.py create mode 100644 system_tests/manager/nodecellar_test.py diff --git a/system_tests/manager/__init__.py b/system_tests/manager/__init__.py new file mode 100644 index 0000000..10de568 --- /dev/null +++ b/system_tests/manager/__init__.py @@ -0,0 +1,25 @@ +######## +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. + + +from cosmo_tester.framework.testenv import bootstrap, teardown + + +def setUp(): + bootstrap() + + +def tearDown(): + teardown() diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py new file mode 100644 index 0000000..73398af --- /dev/null +++ b/system_tests/manager/nodecellar_test.py @@ -0,0 +1,39 @@ +######## +# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. + +from cosmo_tester.test_suites.test_blueprints import nodecellar_test + + +class VcloudNodeCellarTest(nodecellar_test.NodecellarAppTest): + + def test_vcloud_nodecellar(self): + self._test_nodecellar_impl('vcloud-blueprint.yaml') + + def get_inputs(self): + return { + 'catalog': self.env.manager_server_catalog, + 'template': self.env.manager_server_template, + 'edge_gateway': self.env.edge_gateway, + 'management_network_name': self.env.management_network_name, + 'agent_public_key': self.env.agent_public_key + } + + @property + def entrypoint_property_name(self): + return 'public_ip' + + @property + def expected_nodes_count(self): + return 9 diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 90b4867..26f0988 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -22,8 +22,14 @@ class VcloudCleanupContext(BaseHandler.CleanupContext): def __init__(self, context_name, env): super(VcloudCleanupContext, self).__init__(context_name, env) - def cleanup(self): - super(VcloudCleanupContext, self).cleanup() + @classmethod + def clean_all(cls, env): + """ + Cleans *all* resources, including resources that were not + created by the test + """ + super(OpenstackCleanupContext, cls).clean_all(env) + #delete test VDC class CloudifyVcloudInputsConfigReader(BaseCloudifyInputsConfigReader): @@ -115,15 +121,11 @@ def vcloud_region(self): class VcloudHandler(BaseHandler): - CleanupContext = VcloudCleanupContext CloudifyConfigReader = CloudifyVcloudInputsConfigReader def before_bootstrap(self): super(VcloudHandler, self).before_bootstrap() - - def after_bootstrap(self, provider_context): - super(VcloudHandler, self).after_bootstrap(provider_context) - + #create test VDC handler = VcloudHandler From f208bc023aeded1845265647d48bfb00cc4c87eb Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 22 Oct 2015 16:27:37 +0300 Subject: [PATCH 146/228] update dev requirements --- dev-requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 58602ac..0d2a746 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ --e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.2.1#egg=cloudify-dsl-parser==3.2.1 --e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.2.1#egg=cloudify-rest-client==3.2.1 --e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.2.1#egg=cloudify-plugins-common==3.2.1 +-e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.3m7#egg=cloudify-dsl-parser==3.3a7 +-e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.3m7#egg=cloudify-rest-client==3.3a7 +-e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.3m7#egg=cloudify-plugins-common==3.3a7 IPy pyvcloud>=14rc6 pycrypto From 3f238beae4e23d592569cabfcbd42fa1e2a4643f Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 27 Oct 2015 13:59:49 +0400 Subject: [PATCH 147/228] Update system tests --- system_tests/manager/nodecellar_test.py | 13 ++++- system_tests/vcloud_handler.py | 66 +++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index 73398af..f6a7010 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -23,8 +23,8 @@ def test_vcloud_nodecellar(self): def get_inputs(self): return { - 'catalog': self.env.manager_server_catalog, - 'template': self.env.manager_server_template, + 'catalog': 'Public Catalog', + 'template': 'Ubuntu Server 12.04 LTS (amd64 20150127)', 'edge_gateway': self.env.edge_gateway, 'management_network_name': self.env.management_network_name, 'agent_public_key': self.env.agent_public_key @@ -37,3 +37,12 @@ def entrypoint_property_name(self): @property def expected_nodes_count(self): return 9 + + @property + def repo_url(self): + return 'https://github.com/kostya13/cloudify-nodecellar-example.git' + + @property + def repo_branch(self): + return 'vcloud-example' + diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 26f0988..8562842 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -15,8 +15,14 @@ from cosmo_tester.framework.handlers import ( BaseHandler, BaseCloudifyInputsConfigReader) +from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType +from pyvcloud import vcloudair +import time +import requests +TEST_VDC = "systest" + class VcloudCleanupContext(BaseHandler.CleanupContext): def __init__(self, context_name, env): @@ -28,6 +34,7 @@ def clean_all(cls, env): Cleans *all* resources, including resources that were not created by the test """ + import pdb; pdb.set_trace() super(OpenstackCleanupContext, cls).clean_all(env) #delete test VDC @@ -65,15 +72,15 @@ def vcloud_vdc(self): @property def manager_server_name(self): - return self.config['manager_server_name'] + return self.config['server_name'] @property def manager_server_catalog(self): - return self.config['manager_server_catalog'] + return self.config['catalog'] @property def manager_server_template(self): - return self.config['manager_server_template'] + return self.config['template'] @property def management_network_use_existing(self): @@ -105,7 +112,7 @@ def manager_public_key(self): @property def agent_public_key(self): - return self.config['agent_public_key'] + return self.config['user_public_key'] @property def management_port_ip_allocation_mode(self): @@ -126,6 +133,55 @@ class VcloudHandler(BaseHandler): def before_bootstrap(self): super(VcloudHandler, self).before_bootstrap() - #create test VDC + vca = login(self.env.cloudify_config) + if vca.get_vdc(TEST_VDC): + task = vca.delete_vdc(TEST_VDC) + wait_for_task(vca, task) + if vca: + task = vca.create_vdc(TEST_VDC) + wait_for_task(vca, task) + else: + raise RuntimeError("Can't create test VDC") handler = VcloudHandler + + +def login(env): + vca = vcloudair.VCA( + host=env['vcloud_url'], + username=env['vcloud_username'], + service_type=env['vcloud_service_type'], + version="5.7", + verify=False) + logined = (vca.login(env['vcloud_password']) and + vca.login_to_instance(env['vcloud_instance'], env['vcloud_password']) and + vca.login_to_instance(env['vcloud_instance'], None, vca.vcloud_session.token, vca.vcloud_session.org_url)) + if logined: + return vca + else: + return None + +def wait_for_task(vca_client, task): + TASK_RECHECK_TIMEOUT = 5 + TASK_STATUS_SUCCESS = 'success' + TASK_STATUS_ERROR = 'error' + + WAIT_TIME_MAX_MINUTES = 30 + MAX_ATTEMPTS = WAIT_TIME_MAX_MINUTES * 60 / TASK_RECHECK_TIMEOUT + status = task.get_status() + for attempt in xrange(MAX_ATTEMPTS): + if status == TASK_STATUS_SUCCESS: + return + if status == TASK_STATUS_ERROR: + error = task.get_Error() + raise RuntimeError( + "Error during task execution: {0}".format(error.get_message())) + time.sleep(TASK_RECHECK_TIMEOUT) + response = requests.get( + task.get_href(), + headers=vca_client.vcloud_session.get_vcloud_headers(), + verify=False) + task = taskType.parseString(response.content, True) + status = task.get_status() + raise RuntimeError("Wait for task timeout.") + From 7cf21159c1d60751344875b7f25d94e1ed86dd36 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 27 Oct 2015 14:04:07 +0400 Subject: [PATCH 148/228] Fix error message Merge branch 'master' of https://github.com/cloudify-cosmo/tosca-vcloud-plugin --- vcloud_plugin_common/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index a969149..d63b72c 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -292,7 +292,7 @@ def get_instance(vca, instance_id): # outdated token, try login by password if logined is False and password: logined = login_with_retry(vca.login, [password, None], - "Login using token") + "Login using password") # can't login to system at all if logined is False: From 0d9e47e4304b7dd17b5e91beea172239c847c89a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 2 Nov 2015 12:53:23 +0200 Subject: [PATCH 149/228] Bump version to 1.3rc1 --- dev-requirements.txt | 6 +++--- examples/blueprint.yaml | 4 ++-- manager_blueprint/vcloud-manager-blueprint.yaml | 4 ++-- setup.py | 4 ++-- tests/integration/blueprints/header.yaml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 0d2a746..3eafacf 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ --e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.3m7#egg=cloudify-dsl-parser==3.3a7 --e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.3m7#egg=cloudify-rest-client==3.3a7 --e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.3m7#egg=cloudify-plugins-common==3.3a7 +-e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.3rc1#egg=cloudify-dsl-parser==3.3rc1 +-e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.3rc1#egg=cloudify-rest-client==3.3rc1 +-e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.3rc1#egg=cloudify-plugins-common==3.3rc1 IPy pyvcloud>=14rc6 pycrypto diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index 3e543a4..3a90ebe 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,8 +1,8 @@ tosca_definitions_version: cloudify_dsl_1_2 imports: - - http://www.getcloudify.org/spec/cloudify/3.3m7/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3m7/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/3.3rc1/types.yaml + - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3rc1/plugin.yaml node_types: vcloud_configuration: diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml index d478961..bd884d5 100644 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ b/manager_blueprint/vcloud-manager-blueprint.yaml @@ -1,9 +1,9 @@ tosca_definitions_version: cloudify_dsl_1_0 imports: - - http://www.getcloudify.org/spec/cloudify/3.3m4/types.yaml + - http://www.getcloudify.org/spec/cloudify/3.3rc1/types.yaml - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.3m4/plugin.yaml + - http://www.getcloudify.org/spec/fabric-plugin/1.3rc1/plugin.yaml inputs: vcloud_username: type: string diff --git a/setup.py b/setup.py index a574621..0242222 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3a7', + version='1.3rc1', packages=[ 'vcloud_plugin_common', 'server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3a6', + 'cloudify-plugins-common>=3.3a7', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', diff --git a/tests/integration/blueprints/header.yaml b/tests/integration/blueprints/header.yaml index ed6b415..6dba00d 100644 --- a/tests/integration/blueprints/header.yaml +++ b/tests/integration/blueprints/header.yaml @@ -3,7 +3,7 @@ tosca_definitions_version: cloudify_dsl_1_2 imports: - http://s3.amazonaws.com/vcloud-score/types.yaml - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.3m7/plugin.yaml + - http://www.getcloudify.org/spec/fabric-plugin/1.3rc1/plugin.yaml inputs: username: From c7cf425251597437802ea123966525fd7e55a5a2 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 3 Nov 2015 09:51:13 +0400 Subject: [PATCH 150/228] Remove test links --- system_tests/manager/nodecellar_test.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index f6a7010..841d2e5 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -37,12 +37,3 @@ def entrypoint_property_name(self): @property def expected_nodes_count(self): return 9 - - @property - def repo_url(self): - return 'https://github.com/kostya13/cloudify-nodecellar-example.git' - - @property - def repo_branch(self): - return 'vcloud-example' - From f7e70eadb685aac335669956ab3bd635a87ec183 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 3 Nov 2015 11:20:58 +0200 Subject: [PATCH 151/228] CFY-3988: rename packages --- plugin.yaml | 72 +++++----- setup.py | 6 +- tests/unittests/test_mock_base.py | 10 +- tests/unittests/test_mock_network_plugin.py | 118 ++++++++-------- .../test_mock_network_plugin_floatingip.py | 80 +++++------ .../test_mock_network_plugin_keypair.py | 20 +-- .../test_mock_network_plugin_network.py | 2 +- ...t_mock_network_plugin_network_subroutes.py | 8 +- .../test_mock_network_plugin_port.py | 2 +- .../test_mock_network_plugin_public_nat.py | 126 +++++++++--------- ...test_mock_network_plugin_security_group.py | 6 +- .../test_mock_server_plugin_server.py | 2 +- ...est_mock_server_plugin_server_subroutes.py | 20 +-- .../unittests/test_mock_server_plugin_vdc.py | 2 +- .../test_mock_storage_plugin_volume.py | 10 +- tox.ini | 4 +- .../__init__.py | 0 .../floatingip.py | 2 +- .../keypair.py | 0 .../network.py | 2 +- .../port.py | 2 +- .../public_nat.py | 4 +- .../security_group.py | 2 +- .../utils.py | 0 .../__init__.py | 0 .../server.py | 4 +- .../vdc.py | 0 .../__init__.py | 0 .../storage.py | 0 .../volume.py | 2 +- 30 files changed, 253 insertions(+), 253 deletions(-) rename {network_plugin => vcloud_network_plugin}/__init__.py (100%) rename {network_plugin => vcloud_network_plugin}/floatingip.py (98%) rename {network_plugin => vcloud_network_plugin}/keypair.py (100%) rename {network_plugin => vcloud_network_plugin}/network.py (99%) rename {network_plugin => vcloud_network_plugin}/port.py (97%) rename {network_plugin => vcloud_network_plugin}/public_nat.py (99%) rename {network_plugin => vcloud_network_plugin}/security_group.py (98%) rename {network_plugin => vcloud_network_plugin}/utils.py (100%) rename {server_plugin => vcloud_server_plugin}/__init__.py (100%) rename {server_plugin => vcloud_server_plugin}/server.py (99%) rename {server_plugin => vcloud_server_plugin}/vdc.py (100%) rename {storage_plugin => vcloud_storage_plugin}/__init__.py (100%) rename {storage_plugin => vcloud_storage_plugin}/storage.py (100%) rename {storage_plugin => vcloud_storage_plugin}/volume.py (98%) diff --git a/plugin.yaml b/plugin.yaml index 8feda7a..8e03fc0 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -20,23 +20,23 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.server_plugin.server.create + implementation: vcloud.vcloud_server_plugin.server.create inputs: {} configure: - implementation: vcloud.server_plugin.server.configure + implementation: vcloud.vcloud_server_plugin.server.configure inputs: {} start: - implementation: vcloud.server_plugin.server.start + implementation: vcloud.vcloud_server_plugin.server.start inputs: {} stop: - implementation: vcloud.server_plugin.server.stop + implementation: vcloud.vcloud_server_plugin.server.stop inputs: {} delete: - implementation: vcloud.server_plugin.server.delete + implementation: vcloud.vcloud_server_plugin.server.delete inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.server_plugin.server.creation_validation + implementation: vcloud.vcloud_server_plugin.server.creation_validation cloudify.vcloud.nodes.Network: derived_from: cloudify.nodes.Network @@ -52,14 +52,14 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.network_plugin.network.create + implementation: vcloud.vcloud_network_plugin.network.create inputs: {} delete: - implementation: vcloud.network_plugin.network.delete + implementation: vcloud.vcloud_network_plugin.network.delete inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.network.creation_validation + implementation: vcloud.vcloud_network_plugin.network.creation_validation cloudify.vcloud.nodes.Port: derived_from: cloudify.nodes.Port @@ -71,7 +71,7 @@ node_types: interfaces: cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.port.creation_validation + implementation: vcloud.vcloud_network_plugin.port.creation_validation cloudify.vcloud.nodes.FloatingIP: derived_from: cloudify.nodes.VirtualIP @@ -83,7 +83,7 @@ node_types: interfaces: cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.floatingip.creation_validation + implementation: vcloud.vcloud_network_plugin.floatingip.creation_validation cloudify.vcloud.nodes.PublicNAT: derived_from: cloudify.nodes.VirtualIP @@ -99,7 +99,7 @@ node_types: interfaces: cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.public_nat.creation_validation + implementation: vcloud.vcloud_network_plugin.public_nat.creation_validation cloudify.vcloud.nodes.SecurityGroup: derived_from: cloudify.nodes.SecurityGroup @@ -113,7 +113,7 @@ node_types: interfaces: cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.security_group.creation_validation + implementation: vcloud.vcloud_network_plugin.security_group.creation_validation cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root @@ -127,13 +127,13 @@ node_types: interfaces: cloudify.interfaces.validation: creation: - implementation: vcloud.network_plugin.keypair.creation_validation + implementation: vcloud.vcloud_network_plugin.keypair.creation_validation cloudify.interfaces.lifecycle: create: - implementation: vcloud.network_plugin.keypair.create + implementation: vcloud.vcloud_network_plugin.keypair.create inputs: {} delete: - implementation: vcloud.network_plugin.keypair.delete + implementation: vcloud.vcloud_network_plugin.keypair.delete inputs: {} @@ -153,14 +153,14 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.storage_plugin.volume.create_volume + implementation: vcloud.vcloud_storage_plugin.volume.create_volume inputs: {} delete: - implementation: vcloud.storage_plugin.volume.delete_volume + implementation: vcloud.vcloud_storage_plugin.volume.delete_volume inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.storage_plugin.volume.creation_validation + implementation: vcloud.vcloud_storage_plugin.volume.creation_validation cloudify.vcloud.nodes.VDC: derived_from: cloudify.nodes.Root @@ -176,14 +176,14 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.server_plugin.vdc.create + implementation: vcloud.vcloud_server_plugin.vdc.create inputs: {} delete: - implementation: vcloud.server_plugin.vdc.delete + implementation: vcloud.vcloud_server_plugin.vdc.delete inputs: {} cloudify.interfaces.validation: creation: - implementation: vcloud.server_plugin.vdc.creation_validation + implementation: vcloud.vcloud_server_plugin.vdc.creation_validation relationships: cloudify.vcloud.server_connected_to_floating_ip: @@ -191,10 +191,10 @@ relationships: target_interfaces: cloudify.interfaces.relationship_lifecycle: postconfigure: - implementation: vcloud.network_plugin.floatingip.connect_floatingip + implementation: vcloud.vcloud_network_plugin.floatingip.connect_floatingip inputs: {} unlink: - implementation: vcloud.network_plugin.floatingip.disconnect_floatingip + implementation: vcloud.vcloud_network_plugin.floatingip.disconnect_floatingip inputs: {} cloudify.vcloud.server_connected_to_network: derived_from: cloudify.relationships.connected_to @@ -207,53 +207,53 @@ relationships: target_interfaces: cloudify.interfaces.relationship_lifecycle: postconfigure: - implementation: vcloud.network_plugin.security_group.create + implementation: vcloud.vcloud_network_plugin.security_group.create inputs: {} unlink: - implementation: vcloud.network_plugin.security_group.delete + implementation: vcloud.vcloud_network_plugin.security_group.delete inputs: {} cloudify.vcloud.net_connected_to_public_nat: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: preconfigure: - implementation: vcloud.network_plugin.public_nat.net_connect_to_nat_preconfigure + implementation: vcloud.vcloud_network_plugin.public_nat.net_connect_to_nat_preconfigure inputs: {} postconfigure: - implementation: vcloud.network_plugin.public_nat.net_connect_to_nat + implementation: vcloud.vcloud_network_plugin.public_nat.net_connect_to_nat inputs: {} unlink: - implementation: vcloud.network_plugin.public_nat.net_disconnect_from_nat + implementation: vcloud.vcloud_network_plugin.public_nat.net_disconnect_from_nat inputs: {} cloudify.vcloud.server_connected_to_public_nat: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: postconfigure: - implementation: vcloud.network_plugin.public_nat.server_connect_to_nat + implementation: vcloud.vcloud_network_plugin.public_nat.server_connect_to_nat inputs: {} unlink: - implementation: vcloud.network_plugin.public_nat.server_disconnect_from_nat + implementation: vcloud.vcloud_network_plugin.public_nat.server_disconnect_from_nat inputs: {} cloudify.vcloud.volume_attached_to_server: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: establish: - implementation: vcloud.storage_plugin.volume.attach_volume + implementation: vcloud.vcloud_storage_plugin.volume.attach_volume inputs: {} unlink: - implementation: vcloud.storage_plugin.volume.detach_volume + implementation: vcloud.vcloud_storage_plugin.volume.detach_volume inputs: {} cloudify.vcloud.server_connected_to_keypair: derived_from: cloudify.relationships.connected_to target_interfaces: cloudify.interfaces.relationship_lifecycle: postconfigure: - implementation: vcloud.network_plugin.keypair.server_connect_to_keypair + implementation: vcloud.vcloud_network_plugin.keypair.server_connect_to_keypair inputs: {} unlink: - implementation: vcloud.network_plugin.keypair.server_disconnect_from_keypair + implementation: vcloud.vcloud_network_plugin.keypair.server_disconnect_from_keypair inputs: {} cloudify.vcloud.server_connected_to_vdc: derived_from: cloudify.relationships.connected_to @@ -262,7 +262,7 @@ relationships: target_interfaces: cloudify.interfaces.relationship_lifecycle: establish: - implementation: vcloud.server_plugin.server.remove_keys + implementation: vcloud.vcloud_server_plugin.server.remove_keys inputs: {} workflows: diff --git a/setup.py b/setup.py index 0242222..f5adda1 100644 --- a/setup.py +++ b/setup.py @@ -19,9 +19,9 @@ version='1.3rc1', packages=[ 'vcloud_plugin_common', - 'server_plugin', - 'storage_plugin', - 'network_plugin' + 'vcloud_server_plugin', + 'vcloud_storage_plugin', + 'vcloud_network_plugin' ], license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 9a27deb..4c90643 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -15,9 +15,9 @@ import mock import unittest from cloudify import mocks as cfy_mocks -import network_plugin -network_plugin.GATEWAY_TRY_COUNT = 2 -network_plugin.GATEWAY_TIMEOUT = 1 +import vcloud_network_plugin +vcloud_network_plugin.GATEWAY_TRY_COUNT = 2 +vcloud_network_plugin.GATEWAY_TIMEOUT = 1 class MockToscaCloudifyContext(cfy_mocks.MockCloudifyContext): @@ -78,7 +78,7 @@ def set_services_conf_result(self, gateway, result): def set_gateway_busy(self, gateway): message = gateway.response.content message = message.replace( - self.ERROR_PLACE, network_plugin.BUSY_MESSAGE + self.ERROR_PLACE, vcloud_network_plugin.BUSY_MESSAGE ) gateway.response.content = message @@ -207,7 +207,7 @@ def set_network_routed_in_client(self, fake_client): set any network as routed """ network = self.generate_fake_client_network( - network_plugin.NAT_ROUTED + vcloud_network_plugin.NAT_ROUTED ) fake_client.get_network = mock.MagicMock(return_value=network) diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 2baa818..7bbd443 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -18,8 +18,8 @@ from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -import network_plugin -from network_plugin import utils +import vcloud_network_plugin +from vcloud_network_plugin import utils import vcloud_plugin_common @@ -38,12 +38,12 @@ def test_get_vm_ip(self): } } fake_ctx._source.instance.runtime_properties = { - network_plugin.VCLOUD_VAPP_NAME: "name" + vcloud_network_plugin.VCLOUD_VAPP_NAME: "name" } # empty connections/no connection name with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_vm_ip( + vcloud_network_plugin.get_vm_ip( fake_client, fake_ctx, fake_client._vdc_gateway ) vms_networks = [{ @@ -56,14 +56,14 @@ def test_get_vm_ip(self): # not routed with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_vm_ip( + vcloud_network_plugin.get_vm_ip( fake_client, fake_ctx, fake_client._vdc_gateway ) # routed self.set_network_routed_in_client(fake_client) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( - network_plugin.get_vm_ip( + vcloud_network_plugin.get_vm_ip( fake_client, fake_ctx, fake_client._vdc_gateway ), '1.1.1.1' @@ -74,14 +74,14 @@ def test_get_vm_ip(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_vm_ip( + vcloud_network_plugin.get_vm_ip( fake_client, fake_ctx, fake_client._vdc_gateway ) # no vapp fake_client.get_vapp = mock.MagicMock(return_value=None) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_vm_ip( + vcloud_network_plugin.get_vm_ip( fake_client, fake_ctx, fake_client._vdc_gateway ) @@ -92,7 +92,7 @@ def test_collectAssignedIps(self): """ # empty gateway self.assertEqual( - network_plugin.collectAssignedIps(None), + vcloud_network_plugin.collectAssignedIps(None), set([]) ) # snat @@ -104,9 +104,9 @@ def test_collectAssignedIps(self): return_value=[rule_inlist] ) self.assertEqual( - network_plugin.collectAssignedIps(gateway), + vcloud_network_plugin.collectAssignedIps(gateway), set( - [network_plugin.AssignedIPs( + [vcloud_network_plugin.AssignedIPs( external='internal', internal='external' )] ) @@ -120,9 +120,9 @@ def test_collectAssignedIps(self): rule_inlist ]) self.assertEqual( - network_plugin.collectAssignedIps(gateway), + vcloud_network_plugin.collectAssignedIps(gateway), set( - [network_plugin.AssignedIPs( + [vcloud_network_plugin.AssignedIPs( external='external', internal='internal' )] ) @@ -142,7 +142,7 @@ def test_getFreeIP(self): ) gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) self.assertEqual( - network_plugin.getFreeIP(gateway), + vcloud_network_plugin.getFreeIP(gateway), '10.18.1.2' ) # no free ips @@ -150,7 +150,7 @@ def test_getFreeIP(self): '10.18.1.1' ]) with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.getFreeIP(gateway) + vcloud_network_plugin.getFreeIP(gateway) def test_del_ondemand_public_ip(self): """ @@ -161,9 +161,9 @@ def test_del_ondemand_public_ip(self): fake_ctx = self.generate_node_context() # can't deallocate ip gateway.deallocate_public_ip = mock.MagicMock(return_value=None) - with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): + with mock.patch('vcloud_network_plugin.wait_for_gateway', mock.MagicMock()): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.del_ondemand_public_ip( + vcloud_network_plugin.del_ondemand_public_ip( fake_client, gateway, '127.0.0.1', fake_ctx) gateway.deallocate_public_ip.assert_called_with('127.0.0.1') # successfully dropped public ip @@ -173,8 +173,8 @@ def test_del_ondemand_public_ip(self): ) ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with mock.patch('network_plugin.wait_for_gateway', mock.MagicMock()): - network_plugin.del_ondemand_public_ip( + with mock.patch('vcloud_network_plugin.wait_for_gateway', mock.MagicMock()): + vcloud_network_plugin.del_ondemand_public_ip( fake_client, gateway, '127.0.0.1', fake_ctx) def test_save_gateway_configuration(self): @@ -191,7 +191,7 @@ def test_save_gateway_configuration(self): ) fake_ctx = self.generate_node_context() with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.save_gateway_configuration( + vcloud_network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx) # error in status self.set_services_conf_result( @@ -199,7 +199,7 @@ def test_save_gateway_configuration(self): ) with self.assertRaises(cfy_exc.NonRecoverableError): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - network_plugin.save_gateway_configuration( + vcloud_network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx) # everything fine self.set_services_conf_result( @@ -207,7 +207,7 @@ def test_save_gateway_configuration(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertTrue( - network_plugin.save_gateway_configuration( + vcloud_network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx)) # server busy self.set_services_conf_result( @@ -215,7 +215,7 @@ def test_save_gateway_configuration(self): ) self.set_gateway_busy(gateway) self.assertFalse( - network_plugin.save_gateway_configuration( + vcloud_network_plugin.save_gateway_configuration( gateway, fake_client, fake_ctx)) def test_is_network_routed(self): @@ -236,7 +236,7 @@ def test_is_network_routed(self): network = self.generate_fake_client_network("not_routed") fake_client.get_network = mock.MagicMock(return_value=network) self.assertFalse( - network_plugin.is_network_routed( + vcloud_network_plugin.is_network_routed( fake_client, 'network_name', fake_client._vdc_gateway ) @@ -244,14 +244,14 @@ def test_is_network_routed(self): # nat routed self.set_network_routed_in_client(fake_client) self.assertTrue( - network_plugin.is_network_routed( + vcloud_network_plugin.is_network_routed( fake_client, 'network_name', fake_client._vdc_gateway ) ) # nat routed but for other network self.assertFalse( - network_plugin.is_network_routed( + vcloud_network_plugin.is_network_routed( fake_client, 'other_network_name', fake_client._vdc_gateway ) @@ -262,13 +262,13 @@ def test_get_vapp_name(self): check get vapp name """ self.assertEqual( - network_plugin.get_vapp_name({ - network_plugin.VCLOUD_VAPP_NAME: "name" + vcloud_network_plugin.get_vapp_name({ + vcloud_network_plugin.VCLOUD_VAPP_NAME: "name" }), "name" ) with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_vapp_name({ + vcloud_network_plugin.get_vapp_name({ "aa": "aaa" }) @@ -302,12 +302,12 @@ def test_CheckAssignedExternalIp(self): return_value=[rule_inlist] ) # free ip - network_plugin.CheckAssignedExternalIp( + vcloud_network_plugin.CheckAssignedExternalIp( '10.10.1.2', gateway ) # assigned ip with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.CheckAssignedExternalIp( + vcloud_network_plugin.CheckAssignedExternalIp( '10.1.1.1', gateway ) @@ -326,12 +326,12 @@ def test_CheckAssignedInternalIp(self): return_value=[rule_inlist] ) # free ip - network_plugin.CheckAssignedInternalIp( + vcloud_network_plugin.CheckAssignedInternalIp( '123.1.1.2', gateway ) # assigned ip with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.CheckAssignedInternalIp( + vcloud_network_plugin.CheckAssignedInternalIp( '123.1.1.1', gateway ) @@ -344,7 +344,7 @@ def test_get_gateway(self): fake_ctx = self.generate_node_context() with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( - network_plugin.get_gateway( + vcloud_network_plugin.get_gateway( fake_client, 'test name' ), fake_client._vdc_gateway @@ -358,7 +358,7 @@ def test_get_gateway(self): fake_client.get_gateway = mock.MagicMock(return_value=None) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_gateway( + vcloud_network_plugin.get_gateway( fake_client, 'test name' ) @@ -377,7 +377,7 @@ def test_get_network(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( - network_plugin.get_network( + vcloud_network_plugin.get_network( fake_client, 'test name' ), fake_network @@ -391,7 +391,7 @@ def test_get_network(self): fake_client.get_network = mock.MagicMock(return_value=None) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_network( + vcloud_network_plugin.get_network( fake_client, 'test name' ) # worse case = nework == None @@ -399,7 +399,7 @@ def test_get_network(self): fake_ctx = self.generate_node_context() with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_network( + vcloud_network_plugin.get_network( fake_client, None ) @@ -409,12 +409,12 @@ def test_get_network_name(self): """ # external without resource_id with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_network_name({ + vcloud_network_plugin.get_network_name({ 'use_external_resource': True }) # exteranal with resource_id self.assertEqual( - network_plugin.get_network_name({ + vcloud_network_plugin.get_network_name({ 'use_external_resource': True, 'resource_id': 'some_text' }), @@ -422,17 +422,17 @@ def test_get_network_name(self): ) # internal, without network with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_network_name({}) + vcloud_network_plugin.get_network_name({}) # network without name with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_network_name({ + vcloud_network_plugin.get_network_name({ 'network': { 'name': None } }) # good case self.assertEqual( - network_plugin.get_network_name({ + vcloud_network_plugin.get_network_name({ 'network': { 'name': 'good_text' } @@ -465,7 +465,7 @@ def test_get_ondemand_public_ip(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_ondemand_public_ip( + vcloud_network_plugin.get_ondemand_public_ip( fake_client, fake_client._vdc_gateway, fake_ctx ) # success allocate ips, but empty list of ips @@ -476,7 +476,7 @@ def test_get_ondemand_public_ip(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.get_ondemand_public_ip( + vcloud_network_plugin.get_ondemand_public_ip( fake_client, fake_client._vdc_gateway, fake_ctx ) # exist some new ip @@ -489,7 +489,7 @@ def test_get_ondemand_public_ip(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( - network_plugin.get_ondemand_public_ip( + vcloud_network_plugin.get_ondemand_public_ip( fake_client, fake_client._vdc_gateway, fake_ctx ), '1.1.1.1' @@ -512,7 +512,7 @@ def test_get_public_ip_subscription(self): fake_ctx = self.generate_node_context() # for subscription we dont use client self.assertEqual( - network_plugin.get_public_ip( + vcloud_network_plugin.get_public_ip( None, gateway, vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE, fake_ctx ), @@ -543,7 +543,7 @@ def test_get_public_ip_ondemand(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( - network_plugin.get_public_ip( + vcloud_network_plugin.get_public_ip( fake_client, fake_client._vdc_gateway, vcloud_plugin_common.ONDEMAND_SERVICE_TYPE, fake_ctx ), @@ -556,13 +556,13 @@ def test_check_ip(self): """ # wrong type with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.check_ip({'wrong': None}) + vcloud_network_plugin.check_ip({'wrong': None}) # wrong value with self.assertRaises(cfy_exc.NonRecoverableError): - network_plugin.check_ip("1.1.1.400") + vcloud_network_plugin.check_ip("1.1.1.400") # good case self.assertEqual( - network_plugin.check_ip("1.1.1.40"), + vcloud_network_plugin.check_ip("1.1.1.40"), "1.1.1.40" ) @@ -572,11 +572,11 @@ def test_is_valid_ip_range(self): """ # wrong range self.assertFalse( - network_plugin.is_valid_ip_range("1.1.1.50", "1.1.1.40") + vcloud_network_plugin.is_valid_ip_range("1.1.1.50", "1.1.1.40") ) # good case self.assertTrue( - network_plugin.is_valid_ip_range("1.1.1.40", "1.1.1.50") + vcloud_network_plugin.is_valid_ip_range("1.1.1.40", "1.1.1.50") ) def test_is_network_exists(self): @@ -591,7 +591,7 @@ def test_is_network_exists(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertTrue( - network_plugin.is_network_exists(fake_client, 'test') + vcloud_network_plugin.is_network_exists(fake_client, 'test') ) fake_client.get_network.assert_called_with('vdc_name', 'test') # network not exist @@ -602,7 +602,7 @@ def test_is_network_exists(self): ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertFalse( - network_plugin.is_network_exists(fake_client, 'test') + vcloud_network_plugin.is_network_exists(fake_client, 'test') ) def test_is_ips_in_same_subnet(self): @@ -611,13 +611,13 @@ def test_is_ips_in_same_subnet(self): """ # ips from several networks self.assertFalse( - network_plugin.is_ips_in_same_subnet( + vcloud_network_plugin.is_ips_in_same_subnet( ['123.11.1.1', '123.11.3.1'], 24 ) ) # ips from same network self.assertTrue( - network_plugin.is_ips_in_same_subnet( + vcloud_network_plugin.is_ips_in_same_subnet( ['123.11.1.1', '123.11.1.1'], 24 ) ) @@ -629,14 +629,14 @@ def test_is_separate_ranges(self): IPRange = collections.namedtuple('IPRange', 'start end') # positive case self.assertTrue( - network_plugin.is_separate_ranges( + vcloud_network_plugin.is_separate_ranges( IPRange(start='1.1.1.1', end='1.1.1.11'), IPRange(start='1.1.1.12', end='1.1.1.23') ) ) # negative case self.assertFalse( - network_plugin.is_separate_ranges( + vcloud_network_plugin.is_separate_ranges( IPRange(start='1.1.1.1', end='1.1.1.15'), IPRange(start='1.1.1.9', end='1.1.1.23') ) diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index c2fd9db..110e53a 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -16,9 +16,9 @@ import unittest from tests.unittests import test_mock_base -from network_plugin import floatingip +from vcloud_network_plugin import floatingip from cloudify import exceptions as cfy_exc -import network_plugin +import vcloud_network_plugin import vcloud_plugin_common @@ -26,7 +26,7 @@ class NetworkPluginFloatingIpMockTestCase(test_mock_base.TestBase): def test_add_nat_rule_snat(self): fake_ctx = self.generate_node_context() - with mock.patch('network_plugin.floatingip.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway._add_nat_rule = mock.MagicMock(return_value=None) floatingip._add_nat_rule( @@ -38,7 +38,7 @@ def test_add_nat_rule_snat(self): def test_add_nat_rule_dnat(self): fake_ctx = self.generate_node_context() - with mock.patch('network_plugin.floatingip.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway._add_nat_rule = mock.MagicMock(return_value=None) floatingip._add_nat_rule( @@ -50,7 +50,7 @@ def test_add_nat_rule_dnat(self): def test_del_nat_rule_snat(self): fake_ctx = self.generate_node_context() - with mock.patch('network_plugin.floatingip.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway.del_nat_rule = mock.MagicMock(return_value=None) floatingip._del_nat_rule( @@ -62,7 +62,7 @@ def test_del_nat_rule_snat(self): def test_del_nat_rule_dnat(self): fake_ctx = self.generate_node_context() - with mock.patch('network_plugin.floatingip.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway.del_nat_rule = mock.MagicMock(return_value=None) floatingip._del_nat_rule( @@ -113,7 +113,7 @@ def test_creation_validation(self): }, 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: 'some' + vcloud_network_plugin.PUBLIC_IP: 'some' } } ) @@ -148,7 +148,7 @@ def test_creation_validation(self): }, 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.10.1.2', + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2', 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE } }) @@ -215,10 +215,10 @@ def test_floatingip_operation_delete(self): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx + vcloud_network_plugin.DELETE, fake_client, fake_ctx ) # busy in save with ip in node_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() @@ -230,17 +230,17 @@ def test_floatingip_operation_delete(self): fake_ctx._target.node.properties = { 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } } with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): self.assertFalse(floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx + vcloud_network_plugin.DELETE, fake_client, fake_ctx )) # busy in save with ip in runtime_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() @@ -255,30 +255,30 @@ def test_floatingip_operation_delete(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): self.assertFalse(floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx + vcloud_network_plugin.DELETE, fake_client, fake_ctx )) # unknow operation fake_client, fake_ctx = self.generate_client_and_context_floating_ip() fake_ctx._target.node.properties = { 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } } with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): with self.assertRaises(cfy_exc.NonRecoverableError): floatingip._floatingip_operation( @@ -292,7 +292,7 @@ def test_floatingip_operation_delete(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } fake_ctx._source.instance.runtime_properties = { @@ -309,14 +309,14 @@ def test_floatingip_operation_delete(self): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx + vcloud_network_plugin.DELETE, fake_client, fake_ctx ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) # delete to end, subscription fake_client, fake_ctx = self.generate_client_and_context_floating_ip( @@ -328,7 +328,7 @@ def test_floatingip_operation_delete(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } fake_ctx._source.instance.runtime_properties = { 'vcloud_vapp_name': 'vapp', @@ -344,14 +344,14 @@ def test_floatingip_operation_delete(self): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): floatingip._floatingip_operation( - network_plugin.DELETE, fake_client, fake_ctx + vcloud_network_plugin.DELETE, fake_client, fake_ctx ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) def test_disconnect_floatingip(self): @@ -362,7 +362,7 @@ def test_disconnect_floatingip(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '10.10.1.2' + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' } fake_ctx._source.instance.runtime_properties = { 'vcloud_vapp_name': 'vapp', @@ -391,7 +391,7 @@ def test_disconnect_floatingip(self): ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) def test_connect_floatingip(self): @@ -404,7 +404,7 @@ def test_connect_floatingip(self): fake_ctx._target.node.properties = { 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.10.2.3' + vcloud_network_plugin.PUBLIC_IP: '10.10.2.3' }} fake_ctx._source.node.properties = { 'vcloud_config': @@ -432,10 +432,10 @@ def test_connect_floatingip(self): ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) self.assertEqual( - runtime_properties.get(network_plugin.PUBLIC_IP), + runtime_properties.get(vcloud_network_plugin.PUBLIC_IP), '10.10.2.3' ) @@ -466,17 +466,17 @@ def test_floatingip_operation_create(self): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): floatingip._floatingip_operation( - network_plugin.CREATE, fake_client, fake_ctx + vcloud_network_plugin.CREATE, fake_client, fake_ctx ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) self.assertEqual( - runtime_properties.get(network_plugin.PUBLIC_IP), + runtime_properties.get(vcloud_network_plugin.PUBLIC_IP), '10.18.1.1' ) # with already explicitly defined ip @@ -486,7 +486,7 @@ def test_floatingip_operation_create(self): fake_ctx._target.node.properties = { 'floatingip': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.10.2.3' + vcloud_network_plugin.PUBLIC_IP: '10.10.2.3' } } fake_ctx._target.instance.runtime_properties = {} @@ -503,17 +503,17 @@ def test_floatingip_operation_create(self): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'network_plugin.floatingip.ctx', fake_ctx + 'vcloud_network_plugin.floatingip.ctx', fake_ctx ): floatingip._floatingip_operation( - network_plugin.CREATE, fake_client, fake_ctx + vcloud_network_plugin.CREATE, fake_client, fake_ctx ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( - network_plugin.PUBLIC_IP in runtime_properties + vcloud_network_plugin.PUBLIC_IP in runtime_properties ) self.assertEqual( - runtime_properties.get(network_plugin.PUBLIC_IP), + runtime_properties.get(vcloud_network_plugin.PUBLIC_IP), '10.10.2.3' ) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index b031291..4f732ff 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -16,7 +16,7 @@ import mock from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -from network_plugin import keypair +from vcloud_network_plugin import keypair class NetworkPluginKeyPairpMockTestCase(test_mock_base.TestBase): @@ -39,12 +39,12 @@ def test_creation_validation(self): keypair.creation_validation(ctx=fake_ctx) def test_create(self): - patcher1 = mock.patch('network_plugin.keypair._save_key_file', + patcher1 = mock.patch('vcloud_network_plugin.keypair._save_key_file', mock.MagicMock()) - patcher2 = mock.patch('network_plugin.keypair._generate_pair', + patcher2 = mock.patch('vcloud_network_plugin.keypair._generate_pair', mock.MagicMock(return_value=('public', 'private'))) - patcher3 = mock.patch('network_plugin.keypair._create_path', + patcher3 = mock.patch('vcloud_network_plugin.keypair._create_path', mock.MagicMock(return_value=( '~/.ssh/test_private.key'))) patcher1.start() @@ -72,7 +72,7 @@ def test_create(self): mock.patch.stopall() def test_delete(self): - patcher = mock.patch('network_plugin.keypair._delete_key_file', + patcher = mock.patch('vcloud_network_plugin.keypair._delete_key_file', mock.MagicMock()) patcher.start() @@ -115,8 +115,8 @@ def test_create_path(self): fake_ctx._context = {} fake_ctx._context['storage'] = mock.MagicMock() fake_ctx._context['storage']._storage_dir = 'storage_dir' - patcher1 = mock.patch('network_plugin.keypair.ctx', fake_ctx) - patcher2 = mock.patch('network_plugin.keypair.os.environ', + patcher1 = mock.patch('vcloud_network_plugin.keypair.ctx', fake_ctx) + patcher2 = mock.patch('vcloud_network_plugin.keypair.os.environ', {'VIRTUALENV': '/path/to/dir'}) patcher1.start() patcher2.start() @@ -125,7 +125,7 @@ def test_create_path(self): patcher1.stop() fake_ctx._local = False - patcher1 = mock.patch('network_plugin.keypair.ctx', fake_ctx) + patcher1 = mock.patch('vcloud_network_plugin.keypair.ctx', fake_ctx) patcher1.start() path = keypair._create_path() self.assertEqual('/path/to/id_private.key', path) @@ -137,14 +137,14 @@ def test_save_key_file(self): with mock.patch( '__builtin__.open', fake_file, create=True): with mock.patch( - 'network_plugin.keypair.chmod'): + 'vcloud_network_plugin.keypair.chmod'): keypair._save_key_file('/path/to/file/', 'private') handle = fake_file() handle.write.assert_called_once_with('private') def test_delete_key_file(self): with mock.patch( - 'network_plugin.keypair.os.unlink'): + 'vcloud_network_plugin.keypair.os.unlink'): keypair._delete_key_file('/path/') if __name__ == '__main__': diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 69852a5..590ec1b 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -from network_plugin import network +from vcloud_network_plugin import network import vcloud_plugin_common diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 67e3515..a6cb995 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc import test_mock_base -from network_plugin import network +from vcloud_network_plugin import network class NetworkPluginNetworkSubroutesMockTestCase(test_mock_base.TestBase): @@ -57,7 +57,7 @@ def test__dhcp_operation(self): 'vdc': 'vdc_name' } }) - with mock.patch('network_plugin.network.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): network._dhcp_operation( fake_client, '_management_network', network.ADD_POOL @@ -74,7 +74,7 @@ def test__dhcp_operation(self): 'vdc': 'vdc_name' } }) - with mock.patch('network_plugin.network.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): network._dhcp_operation( @@ -93,7 +93,7 @@ def test__dhcp_operation(self): } }) - with mock.patch('network_plugin.network.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): # returned error/None from server with self.assertRaises(cfy_exc.NonRecoverableError): diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 685ed32..a619417 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -from network_plugin import port +from vcloud_network_plugin import port class NetworkPluginPortMockTestCase(test_mock_base.TestBase): diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index a093189..510c70b 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -17,9 +17,9 @@ from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -from network_plugin import public_nat -from network_plugin import utils -import network_plugin +from vcloud_network_plugin import public_nat +from vcloud_network_plugin import utils +import vcloud_network_plugin import vcloud_plugin_common from IPy import IP @@ -50,7 +50,7 @@ def test_get_original_port_for_delete(self): public_nat.PORT_REPLACEMENT: {}} with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertEqual( public_nat._get_original_port_for_delete("10.1.1.1", "11"), @@ -64,7 +64,7 @@ def test_get_original_port_for_delete(self): } } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertEqual( public_nat._get_original_port_for_delete("10.1.1.1", "11"), @@ -78,7 +78,7 @@ def test_get_original_port_for_delete(self): } } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertEqual( public_nat._get_original_port_for_delete("10.1.1.2", "11"), @@ -92,7 +92,7 @@ def test_get_original_port_for_create(self): 'DNAT', 'external', 'any', 'internal', '11', 'TCP') gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): # exeption about same port with self.assertRaises(cfy_exc.NonRecoverableError): @@ -121,7 +121,7 @@ def test_get_original_port_for_create_with_ctx(self): ) gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertEqual( public_nat._get_original_port_for_create( @@ -140,7 +140,7 @@ def test_get_original_port_for_create_with_ctx(self): # same but without replacement at all fake_ctx._target.instance.runtime_properties = {} with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertEqual( public_nat._get_original_port_for_create( @@ -164,7 +164,7 @@ def test_get_original_port_for_create_with_ctx(self): gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) fake_ctx._target.instance.runtime_properties = {} with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat._get_original_port_for_create( @@ -199,14 +199,14 @@ def test_get_gateway_ip_range(self): def test_obtain_public_ip(self): fake_ctx = self.generate_relation_context() fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } gateway = mock.Mock() fake_client = mock.Mock() # exist some ip for delete self.assertEqual( public_nat._obtain_public_ip( - fake_client, fake_ctx, gateway, network_plugin.DELETE + fake_client, fake_ctx, gateway, vcloud_network_plugin.DELETE ), '192.168.1.1' ) @@ -214,7 +214,7 @@ def test_obtain_public_ip(self): fake_ctx._target.instance.runtime_properties = {} with self.assertRaises(cfy_exc.NonRecoverableError): public_nat._obtain_public_ip( - fake_client, fake_ctx, gateway, network_plugin.DELETE + fake_client, fake_ctx, gateway, vcloud_network_plugin.DELETE ) # unknow operation with self.assertRaises(cfy_exc.NonRecoverableError): @@ -224,12 +224,12 @@ def test_obtain_public_ip(self): # exist some public ip fake_ctx._target.node.properties = { 'nat': { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } } self.assertEqual( public_nat._obtain_public_ip( - fake_client, fake_ctx, gateway, network_plugin.CREATE + fake_client, fake_ctx, gateway, vcloud_network_plugin.CREATE ), '192.168.1.1' ) @@ -253,7 +253,7 @@ def test_obtain_public_ip(self): return_value=[rule_inlist] ) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx @@ -261,7 +261,7 @@ def test_obtain_public_ip(self): self.assertEqual( public_nat._obtain_public_ip( fake_client, fake_ctx, gateway, - network_plugin.CREATE + vcloud_network_plugin.CREATE ), '10.18.1.2' ) @@ -300,7 +300,7 @@ def test_create_ip_range(self): # context fake_ctx = self.generate_relation_context() fake_ctx._source.instance.runtime_properties = { - network_plugin.network.VCLOUD_NETWORK_NAME: "some" + vcloud_network_plugin.network.VCLOUD_NETWORK_NAME: "some" } fake_ctx._source.node.properties = { 'vcloud_config': { @@ -319,7 +319,7 @@ def test_create_ip_range(self): ) fake_client.get_networks = mock.MagicMock(return_value=[network]) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx @@ -363,7 +363,7 @@ def _context_for_delete(service_type): gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: "1.2.3.4" + vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" } properties = { 'vcloud_config': { @@ -382,7 +382,7 @@ def _ip_exist_in_runtime(fake_ctx): ip still exist in ctx """ runtime_properties = fake_ctx._target.instance.runtime_properties - return network_plugin.PUBLIC_IP in runtime_properties + return vcloud_network_plugin.PUBLIC_IP in runtime_properties fake_client = self.generate_client() gateway = fake_client._vdc_gateway @@ -393,10 +393,10 @@ def _ip_exist_in_runtime(fake_ctx): self.set_gateway_busy(gateway) fake_ctx = self.generate_relation_context() with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertFalse(public_nat._save_configuration( - gateway, fake_client, network_plugin.CREATE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.CREATE, "1.2.3.4" )) # operation create @@ -405,16 +405,16 @@ def _ip_exist_in_runtime(fake_ctx): gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): # success save configuration with mock.patch('vcloud_plugin_common.ctx', fake_ctx): public_nat._save_configuration( - gateway, fake_client, network_plugin.CREATE, "1.2.3.4") + gateway, fake_client, vcloud_network_plugin.CREATE, "1.2.3.4") self.assertEqual( fake_ctx._target.instance.runtime_properties, { - network_plugin.PUBLIC_IP: "1.2.3.4" + vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" } ) # delete - subscription service @@ -422,26 +422,26 @@ def _ip_exist_in_runtime(fake_ctx): vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE ) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) # delete - without service fake_ctx = _context_for_delete(None) with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -451,17 +451,17 @@ def _ip_exist_in_runtime(fake_ctx): ) fake_ctx._target.node.properties = { 'nat': { - network_plugin.PUBLIC_IP: "1.2.3.4" + vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" } } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -478,14 +478,14 @@ def _ip_exist_in_runtime(fake_ctx): 'nat': {} } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): # import pdb;pdb.set_trace() public_nat._save_configuration( - gateway, fake_client, network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" ) gateway.deallocate_public_ip.assert_called_with("1.2.3.4") self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -503,10 +503,10 @@ def test_nat_network_operation(self): fake_ctx = self.generate_relation_context() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {}} - for operation in [network_plugin.DELETE, network_plugin.CREATE]: + for operation in [vcloud_network_plugin.DELETE, vcloud_network_plugin.CREATE]: for rule_type in ["SNAT", "DNAT"]: with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx @@ -516,7 +516,7 @@ def test_nat_network_operation(self): "1.2.3.4", "2.3.4.5", "11", "11", "TCP" ) if rule_type == "DNAT": - if operation == network_plugin.DELETE: + if operation == vcloud_network_plugin.DELETE: gateway.del_nat_rule.assert_called_with( 'DNAT', '1.2.3.4', '11', '2.3.4.5', '11', 'TCP' @@ -527,7 +527,7 @@ def test_nat_network_operation(self): 'TCP' ) else: - if operation == network_plugin.DELETE: + if operation == vcloud_network_plugin.DELETE: gateway.del_nat_rule.assert_called_with( 'SNAT', '2.3.4.5', 'any', '1.2.3.4', 'any', 'any' @@ -562,7 +562,7 @@ def generate_client_and_context_server(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } self.set_services_conf_result( fake_client._vdc_gateway, @@ -575,14 +575,14 @@ def test_prepare_server_operation(self): fake_client, fake_ctx = self.generate_client_and_context_server() # no rules for update with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.prepare_server_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) # with some rules fake_client, fake_ctx = self.generate_client_and_context_server() @@ -598,13 +598,13 @@ def test_prepare_server_operation(self): }] } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat.prepare_server_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', '11', '1.1.1.1', '11', 'TCP' @@ -612,7 +612,7 @@ def test_prepare_server_operation(self): # with default value fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } fake_ctx._target.node.properties = { 'nat': { @@ -623,13 +623,13 @@ def test_prepare_server_operation(self): }] } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat.prepare_server_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '1.1.1.1', 'any', 'any' @@ -643,13 +643,13 @@ def test_prepare_server_operation(self): 'rules': [{'type': 'SNAT'}, {'type': 'SNAT'}] } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat.prepare_server_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'SNAT', '1.1.1.1', 'any', '192.168.1.1', 'any', 'any' @@ -679,7 +679,7 @@ def generate_client_and_context_network(self): # ctx fake_ctx = self.generate_relation_context() fake_ctx._source.instance.runtime_properties = { - network_plugin.network.VCLOUD_NETWORK_NAME: "some" + vcloud_network_plugin.network.VCLOUD_NETWORK_NAME: "some" } fake_ctx._source.node.properties = { 'vcloud_config': { @@ -694,7 +694,7 @@ def generate_client_and_context_network(self): } } fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } return fake_client, fake_ctx @@ -702,14 +702,14 @@ def test_prepare_network_operation(self): # no rules fake_client, fake_ctx = self.generate_client_and_context_network() with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.prepare_network_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) # rules with default values fake_client, fake_ctx = self.generate_client_and_context_network() @@ -722,13 +722,13 @@ def test_prepare_network_operation(self): }] } with mock.patch( - 'network_plugin.public_nat.ctx', fake_ctx + 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): public_nat.prepare_network_operation( - fake_client, network_plugin.DELETE + fake_client, vcloud_network_plugin.DELETE ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '127.1.1.100 - 127.1.1.200', @@ -776,7 +776,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: 'any' + vcloud_network_plugin.PUBLIC_IP: 'any' } }) with mock.patch( @@ -809,7 +809,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.12.2.1' + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' } }) with mock.patch( @@ -826,7 +826,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.12.2.1' + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' }, 'rules': [{ 'type': 'DNAT', @@ -847,7 +847,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.12.2.1' + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' }, 'rules': [{ 'type': 'DNAT', @@ -870,7 +870,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.12.2.1' + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' }, 'rules': [{ 'type': 'DNAT', @@ -893,7 +893,7 @@ def test_creation_validation(self): }, 'nat': { 'edge_gateway': 'gateway', - network_plugin.PUBLIC_IP: '10.12.2.1' + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' }, 'rules': [{ 'type': 'DNAT', @@ -911,7 +911,7 @@ def test_creation_validation(self): def test_server_disconnect_from_nat(self): fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } fake_ctx._target.node.properties = { 'nat': { @@ -944,7 +944,7 @@ def test_server_disconnect_from_nat(self): def test_server_connect_to_nat(self): fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.instance.runtime_properties = { - network_plugin.PUBLIC_IP: '192.168.1.1' + vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } fake_ctx._source.instance.runtime_properties = { 'gateway_lock': False, diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index a4b67d9..e84e08d 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc from tests.unittests import test_mock_base -from network_plugin import security_group +from vcloud_network_plugin import security_group import vcloud_plugin_common @@ -77,7 +77,7 @@ def check_rule_operation(self, rule_type, rules, vms_networks=None): gateway.delete_fw_rule = mock.MagicMock(return_value=None) # any networks will be routed self.set_network_routed_in_client(fake_client) - with mock.patch('network_plugin.security_group.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.security_group.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): security_group._rule_operation( rule_type, fake_client @@ -96,7 +96,7 @@ def check_rule_operation_fail(self, rule_type, rules): self.set_services_conf_result( fake_client._vdc_gateway, None ) - with mock.patch('network_plugin.security_group.ctx', fake_ctx): + with mock.patch('vcloud_network_plugin.security_group.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertFalse(security_group._rule_operation( rule_type, fake_client diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index fee8368..dc28bb7 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -16,7 +16,7 @@ import unittest from cloudify import exceptions as cfy_exc -from server_plugin import server +from vcloud_server_plugin import server import vcloud_plugin_common from tests.unittests import test_mock_base diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index e4f4e23..c95a35b 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -17,7 +17,7 @@ from cloudify import exceptions as cfy_exc from cloudify import mocks as cfy_mocks -from server_plugin import server +from vcloud_server_plugin import server from tests.unittests import test_mock_base @@ -61,7 +61,7 @@ def test_check_hardware(self): server._check_hardware(1, 512) def test_build_script(self): - with mock.patch('server_plugin.server._get_connected_keypairs', + with mock.patch('vcloud_server_plugin.server._get_connected_keypairs', mock.MagicMock( return_value=[])): self.assertEqual(None, server._build_script({}, [])) @@ -73,7 +73,7 @@ def test_build_script(self): 'key': True }] } - with mock.patch('server_plugin.server._get_connected_keypairs', + with mock.patch('vcloud_server_plugin.server._get_connected_keypairs', mock.MagicMock( return_value=[{'key': 'key'}])): self.assertNotEqual(None, server._build_script(custom, [])) @@ -227,7 +227,7 @@ def test_isDhcpAvailable(self): provider_context={} ) - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( True, server._isDhcpAvailable(client, 'bridged') @@ -276,7 +276,7 @@ def test_create_connections_list(self): } }) fake_client = self.generate_client() - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): connection = server._create_connections_list(fake_client) self.assertEqual( @@ -316,7 +316,7 @@ def test_create_connections_list(self): 'name': 'some_network' } }) - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): connection = server._create_connections_list(fake_client) self.assertEqual( @@ -351,13 +351,13 @@ def test_create_connections_list(self): 'name': 'some_network' } }) - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): server._create_connections_list(fake_client) # only managment node fake_ctx.instance._relationships = [] - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): connection = server._create_connections_list(fake_client) self.assertEqual( @@ -377,7 +377,7 @@ def _generate_fake_client_network(vdc_name, network_name): return None fake_client.get_network = _generate_fake_client_network - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): server._create_connections_list(fake_client) @@ -442,7 +442,7 @@ def test_get_vm_network_connection(self): def test_get_state(self): fake_ctx = self.generate_node_context() - with mock.patch('server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): # connected network_name fake_client = self.generate_client([{ diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py index f52eb19..51c7805 100644 --- a/tests/unittests/test_mock_server_plugin_vdc.py +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -15,7 +15,7 @@ import mock from cloudify import exceptions as cfy_exc -from server_plugin import vdc +from vcloud_server_plugin import vdc import vcloud_plugin_common from tests.unittests import test_mock_base diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 442b877..25be7eb 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -17,10 +17,10 @@ from cloudify import exceptions as cfy_exc from cloudify import mocks as cfy_mocks -from storage_plugin import volume +from vcloud_storage_plugin import volume import vcloud_plugin_common from tests.unittests import test_mock_base -import network_plugin +import vcloud_network_plugin class StoaragePluginVolumeMockTestCase(test_mock_base.TestBase): @@ -289,7 +289,7 @@ def _run_volume_operation(fake_ctx, fake_client, operation): 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'storage_plugin.volume.ctx', fake_ctx + 'vcloud_storage_plugin.volume.ctx', fake_ctx ): volume._volume_operation(fake_client, operation) # use external resource, no disks @@ -371,7 +371,7 @@ def _gen_volume_context_and_client(self): 'resource_id': 'some' } fake_ctx._target.instance.runtime_properties = { - network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME, + vcloud_network_plugin.VCLOUD_VAPP_NAME: self.VAPPNAME, 'ip': "1.2.3.4" } return fake_ctx, fake_client @@ -384,7 +384,7 @@ def test_attach_volume(self): with mock.patch('vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client)): with mock.patch( - 'storage_plugin.volume._wait_for_boot', mock.MagicMock()): + 'vcloud_storage_plugin.volume._wait_for_boot', mock.MagicMock()): volume.attach_volume(ctx=fake_ctx) def test_detach_volume(self): diff --git a/tox.ini b/tox.ini index 20c84e6..7901635 100644 --- a/tox.ini +++ b/tox.ini @@ -16,11 +16,11 @@ commands = nosetests -x -s --tc=ondemand: tests/integration {posargs} commands = nosetests -x -s --tc=subscription: tests/integration {posargs} [testenv:py27-unittests] -commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=network_plugin --cover-package=server_plugin --cover-package=storage_plugin +commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=vcloud_network_plugin --cover-package=vcloud_server_plugin --cover-package=vcloud_storage_plugin [testenv:pep8] commands= - flake8 --ignore=E501 network_plugin server_plugin vcloud_plugin_common tests manager_blueprint/scripts storage_plugin + flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin tests manager_blueprint/scripts ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py diff --git a/network_plugin/__init__.py b/vcloud_network_plugin/__init__.py similarity index 100% rename from network_plugin/__init__.py rename to vcloud_network_plugin/__init__.py diff --git a/network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py similarity index 98% rename from network_plugin/floatingip.py rename to vcloud_network_plugin/floatingip.py index 6f7f806..accfba3 100644 --- a/network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -17,7 +17,7 @@ from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, is_subscription, is_ondemand, get_mandatory) -from network_plugin import (check_ip, CheckAssignedExternalIp, +from vcloud_network_plugin import (check_ip, CheckAssignedExternalIp, CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, CREATE, DELETE, PUBLIC_IP, get_gateway, diff --git a/network_plugin/keypair.py b/vcloud_network_plugin/keypair.py similarity index 100% rename from network_plugin/keypair.py rename to vcloud_network_plugin/keypair.py diff --git a/network_plugin/network.py b/vcloud_network_plugin/network.py similarity index 99% rename from network_plugin/network.py rename to vcloud_network_plugin/network.py index e3815a8..c75e58f 100644 --- a/network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -18,7 +18,7 @@ from vcloud_plugin_common import (with_vca_client, wait_for_task, get_vcloud_config, get_mandatory) import collections -from network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, +from vcloud_network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, is_ips_in_same_subnet, save_gateway_configuration, get_network_name, is_network_exists, get_gateway, set_retry) diff --git a/network_plugin/port.py b/vcloud_network_plugin/port.py similarity index 97% rename from network_plugin/port.py rename to vcloud_network_plugin/port.py index bd85235..d84f8c5 100644 --- a/network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -16,7 +16,7 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import with_vca_client, get_mandatory -from network_plugin import check_ip +from vcloud_network_plugin import check_ip @operation diff --git a/network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py similarity index 99% rename from network_plugin/public_nat.py rename to vcloud_network_plugin/public_nat.py index c35856f..e67446e 100644 --- a/network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -17,12 +17,12 @@ from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, get_mandatory, is_subscription, is_ondemand) -from network_plugin import (check_ip, save_gateway_configuration, +from vcloud_network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, del_ondemand_public_ip, utils, set_retry, lock_gateway) -from network_plugin.network import VCLOUD_NETWORK_NAME +from vcloud_network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP PORT_REPLACEMENT = 'port_replacement' diff --git a/network_plugin/security_group.py b/vcloud_network_plugin/security_group.py similarity index 98% rename from network_plugin/security_group.py rename to vcloud_network_plugin/security_group.py index b6e4a51..cf9080d 100644 --- a/network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -17,7 +17,7 @@ from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) -from network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, +from vcloud_network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, get_gateway, utils, set_retry, lock_gateway) diff --git a/network_plugin/utils.py b/vcloud_network_plugin/utils.py similarity index 100% rename from network_plugin/utils.py rename to vcloud_network_plugin/utils.py diff --git a/server_plugin/__init__.py b/vcloud_server_plugin/__init__.py similarity index 100% rename from server_plugin/__init__.py rename to vcloud_server_plugin/__init__.py diff --git a/server_plugin/server.py b/vcloud_server_plugin/server.py similarity index 99% rename from server_plugin/server.py rename to vcloud_server_plugin/server.py index 352f686..1fc65d1 100644 --- a/server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -24,9 +24,9 @@ with_vca_client, error_response, STATUS_POWERED_ON) -from network_plugin import (get_network_name, get_network, is_network_exists, +from vcloud_network_plugin import (get_network_name, get_network, is_network_exists, get_vapp_name, GATEWAY_TIMEOUT, RETRY_COUNT) -from network_plugin.keypair import PUBLIC_KEY, SSH_KEY +from vcloud_network_plugin.keypair import PUBLIC_KEY, SSH_KEY VCLOUD_VAPP_NAME = 'vcloud_vapp_name' GUEST_CUSTOMIZATION = 'guest_customization' diff --git a/server_plugin/vdc.py b/vcloud_server_plugin/vdc.py similarity index 100% rename from server_plugin/vdc.py rename to vcloud_server_plugin/vdc.py diff --git a/storage_plugin/__init__.py b/vcloud_storage_plugin/__init__.py similarity index 100% rename from storage_plugin/__init__.py rename to vcloud_storage_plugin/__init__.py diff --git a/storage_plugin/storage.py b/vcloud_storage_plugin/storage.py similarity index 100% rename from storage_plugin/storage.py rename to vcloud_storage_plugin/storage.py diff --git a/storage_plugin/volume.py b/vcloud_storage_plugin/volume.py similarity index 98% rename from storage_plugin/volume.py rename to vcloud_storage_plugin/volume.py index d02a076..b7e588b 100644 --- a/storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -19,7 +19,7 @@ from vcloud_plugin_common import (wait_for_task, with_vca_client, get_vcloud_config, get_mandatory, error_response) -from network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT +from vcloud_network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT @operation From 463067d07660bbcee132d80310b3eec7dece7136 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 3 Nov 2015 16:32:35 +0200 Subject: [PATCH 152/228] CFY-3988: fix pep8 --- vcloud_network_plugin/floatingip.py | 12 ++++++------ vcloud_network_plugin/network.py | 6 +++--- vcloud_network_plugin/public_nat.py | 8 ++++---- vcloud_network_plugin/security_group.py | 2 +- vcloud_server_plugin/server.py | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index accfba3..722d630 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -18,12 +18,12 @@ from vcloud_plugin_common import (with_vca_client, get_vcloud_config, is_subscription, is_ondemand, get_mandatory) from vcloud_network_plugin import (check_ip, CheckAssignedExternalIp, - CheckAssignedInternalIp, get_vm_ip, - save_gateway_configuration, getFreeIP, - CREATE, DELETE, PUBLIC_IP, get_gateway, - SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - get_public_ip, del_ondemand_public_ip, - set_retry, lock_gateway) + CheckAssignedInternalIp, get_vm_ip, + save_gateway_configuration, getFreeIP, + CREATE, DELETE, PUBLIC_IP, get_gateway, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, + get_public_ip, del_ondemand_public_ip, + set_retry, lock_gateway) @operation diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index c75e58f..ba95e2c 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -19,9 +19,9 @@ get_vcloud_config, get_mandatory) import collections from vcloud_network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, - is_ips_in_same_subnet, save_gateway_configuration, - get_network_name, is_network_exists, - get_gateway, set_retry) + is_ips_in_same_subnet, save_gateway_configuration, + get_network_name, is_network_exists, + get_gateway, set_retry) VCLOUD_NETWORK_NAME = 'vcloud_network_name' SKIP_CREATE_NETWORK = 'skip_create_network' diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index e67446e..a9f477c 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -18,10 +18,10 @@ from vcloud_plugin_common import (with_vca_client, get_vcloud_config, get_mandatory, is_subscription, is_ondemand) from vcloud_network_plugin import (check_ip, save_gateway_configuration, - get_vm_ip, get_public_ip, - get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, - SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry, lock_gateway) + get_vm_ip, get_public_ip, + get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, + SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, + del_ondemand_public_ip, utils, set_retry, lock_gateway) from vcloud_network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index cf9080d..ab4416e 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -18,7 +18,7 @@ from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) from vcloud_network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, - get_gateway, utils, set_retry, lock_gateway) + get_gateway, utils, set_retry, lock_gateway) CREATE_RULE = 1 diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 1fc65d1..3fc2ddc 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -25,7 +25,7 @@ error_response, STATUS_POWERED_ON) from vcloud_network_plugin import (get_network_name, get_network, is_network_exists, - get_vapp_name, GATEWAY_TIMEOUT, RETRY_COUNT) + get_vapp_name, GATEWAY_TIMEOUT, RETRY_COUNT) from vcloud_network_plugin.keypair import PUBLIC_KEY, SSH_KEY VCLOUD_VAPP_NAME = 'vcloud_vapp_name' From 4bee168a64a79746f20626ad3b44c51b8c0f8ce2 Mon Sep 17 00:00:00 2001 From: Chen Roth Date: Wed, 4 Nov 2015 13:54:42 +0200 Subject: [PATCH 153/228] Update plugin.yaml --- plugin.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin.yaml b/plugin.yaml index 8e03fc0..f3c159d 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2,6 +2,8 @@ plugins: vcloud: executor: central_deployment_agent source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + package_name: cloudify-vcloud-plugin + package_version: 1.3rc1 node_types: cloudify.vcloud.nodes.Server: From eb282292310ad32aa274935d44a8ef38ccfc76bf Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 29 Oct 2015 13:19:10 +0400 Subject: [PATCH 154/228] CFY-3948 Adapt tosca-vcloud-plugin for working with cloudify-proxy-plugin --- vcloud_plugin_common/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index d63b72c..94096bf 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -21,6 +21,7 @@ from pyvcloud import vcloudair from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType +from cloudify.context import ImmutableProperties from cloudify import ctx from cloudify import context @@ -378,6 +379,14 @@ def _private_login(self, url, username, password, token, org_name, return vca +def _update_static_properties(node, kw, element): + if element in kw: + node._node = node._endpoint.get_node(node.id) + props = node._node.get('properties', {}) + props.update(kw[element]) + node._node['properties'] = ImmutableProperties(props) + + def with_vca_client(f): """ add vca client to function params @@ -387,9 +396,12 @@ def wrapper(*args, **kw): config = None prop = None if ctx.type == context.NODE_INSTANCE: + _update_static_properties(ctx.node, kw, 'properties') config = ctx.node.properties.get(VCLOUD_CONFIG) prop = ctx.instance.runtime_properties elif ctx.type == context.RELATIONSHIP_INSTANCE: + _update_static_properties(ctx.source.node, kw, 'source') + _update_static_properties(ctx.target.node, kw, 'target') config = ctx.source.node.properties.get(VCLOUD_CONFIG) if config: prop = ctx.source.instance.runtime_properties From d5ca93e2c76bcb1c1df8b831229b5528ab21ddc5 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 5 Nov 2015 12:27:37 +0400 Subject: [PATCH 155/228] Fix system test handler --- system_tests/vcloud_handler.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 8562842..e57c8a3 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -135,8 +135,11 @@ def before_bootstrap(self): super(VcloudHandler, self).before_bootstrap() vca = login(self.env.cloudify_config) if vca.get_vdc(TEST_VDC): - task = vca.delete_vdc(TEST_VDC) - wait_for_task(vca, task) + status, task = vca.delete_vdc(TEST_VDC) + if status: + wait_for_task(vca, task) + else: + raise RuntimeError("Can't delete test VDC") if vca: task = vca.create_vdc(TEST_VDC) wait_for_task(vca, task) From 2c6df42f54eb099c0115e69979aeb45322931f39 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 5 Nov 2015 12:58:13 +0400 Subject: [PATCH 156/228] Fix properties update. Update integration tests --- .../blueprints/server_use_interface_inputs.yaml | 15 +++++++++++++++ tests/integration/test_server_plugin.py | 6 ++++++ vcloud_plugin_common/__init__.py | 13 ++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/integration/blueprints/server_use_interface_inputs.yaml diff --git a/tests/integration/blueprints/server_use_interface_inputs.yaml b/tests/integration/blueprints/server_use_interface_inputs.yaml new file mode 100644 index 0000000..11217a7 --- /dev/null +++ b/tests/integration/blueprints/server_use_interface_inputs.yaml @@ -0,0 +1,15 @@ + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + template: { get_input: template } + install_agent: false + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + interfaces: + cloudify.interfaces.lifecycle: + create: + inputs: + properties: + management_network: { get_input: network_name } + server: + catalog: { get_input: catalog } \ No newline at end of file diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index 51794c7..7accd42 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -48,6 +48,12 @@ def test_use_external(self): self.vca_client.delete_vapp(self.conf.vdc, self.conf.server_name) self.failed = False + @fail_guard + def test_interface_inputs(self): + self.init('server_use_interface_inputs.yaml') + self.install() + self.uninstall() + @fail_guard def test_connect_to_network(self): self.init('server_to_network.yaml') diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 94096bf..34395dd 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -18,6 +18,7 @@ import os import requests import time +import collections from pyvcloud import vcloudair from pyvcloud.schema.vcd.v1_5.schemas.vcloud import taskType @@ -379,11 +380,21 @@ def _private_login(self, url, username, password, token, org_name, return vca +def _update_nested(d, u): + for k, v in u.iteritems(): + if isinstance(v, collections.Mapping): + r = _update_nested(d.get(k, {}), v) + d[k] = r + else: + d[k] = u[k] + return d + + def _update_static_properties(node, kw, element): if element in kw: node._node = node._endpoint.get_node(node.id) props = node._node.get('properties', {}) - props.update(kw[element]) + _update_nested(props, kw[element]) node._node['properties'] = ImmutableProperties(props) From fd944630023d75d0900e89f345ceb55c8d6258b2 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 5 Nov 2015 12:35:47 +0200 Subject: [PATCH 157/228] SCOR-216: cleanup repository --- manager_blueprint/README.md | 5 + manager_blueprint/inputs.yaml.example | 22 - manager_blueprint/scripts/configure.py | 85 --- manager_blueprint/scripts/configure_docker.py | 35 -- manager_blueprint/scripts/setup_grub.sh | 3 - .../vcloud-manager-blueprint.yaml | 594 ------------------ tests/syntax_check.py | 1 - tox.ini | 2 +- 8 files changed, 6 insertions(+), 741 deletions(-) create mode 100644 manager_blueprint/README.md delete mode 100644 manager_blueprint/inputs.yaml.example delete mode 100644 manager_blueprint/scripts/configure.py delete mode 100644 manager_blueprint/scripts/configure_docker.py delete mode 100644 manager_blueprint/scripts/setup_grub.sh delete mode 100644 manager_blueprint/vcloud-manager-blueprint.yaml diff --git a/manager_blueprint/README.md b/manager_blueprint/README.md new file mode 100644 index 0000000..a3d50aa --- /dev/null +++ b/manager_blueprint/README.md @@ -0,0 +1,5 @@ +Manager blueprint moved to https://github.com/cloudify-cosmo/cloudify-manager-blueprints/ + +Please use as manager blueprint such file: new/vcloud-manager-blueprint.yaml + +Inputs example here: new/vcloud-manager-blueprint-inputs.yaml diff --git a/manager_blueprint/inputs.yaml.example b/manager_blueprint/inputs.yaml.example deleted file mode 100644 index c9b5abe..0000000 --- a/manager_blueprint/inputs.yaml.example +++ /dev/null @@ -1,22 +0,0 @@ -vcloud_username: some_user -vcloud_password: some_password -vcloud_url: https://vca.vmware.com -vcloud_service: VDC -vcloud_org: VDC -vcloud_vdc: VDC -vcloud_service_type: ondemand -vcloud_instance: 00000000-0000-0000-0000-000000000000 -edge_gateway: gateway -manager_server_name: some-server -manager_server_catalog: default-catalog -manager_server_template: Ubuntu Server 12.04 LTS (amd64 20150127) -manager_server_public_ip: -management_network_use_existing: true -management_network_public_nat_use_existing: true -management_network_name: some-net -management_network_public_ip: -manager_private_key_path: ~/.ssh/manager.pem -agent_private_key_path: ~/.ssh/manager.pem -manager_public_key: some_key -agent_public_key: some_key -management_port_ip_allocation_mode: pool diff --git a/manager_blueprint/scripts/configure.py b/manager_blueprint/scripts/configure.py deleted file mode 100644 index 571e69e..0000000 --- a/manager_blueprint/scripts/configure.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import tempfile -import json - -import fabric - -import vcloud_plugin_common -from cloudify import ctx - -PROVIDER_CONTEXT_RUNTIME_PROPERTY = 'provider_context' - - -def configure(vcloud_config): - """ - copy configuration to managment host, - install docker - and save current context to .cloudify/context - For now - we have saved only managment network name - """ - _copy_vsphere_configuration_to_manager(vcloud_config) - _install_docker() - _save_context() - - -def _copy_vsphere_configuration_to_manager(vcloud_config): - """ - Copy current config to remote node - """ - tmp = tempfile.mktemp() - with open(tmp, 'w') as f: - json.dump(vcloud_config, f) - fabric.api.put(tmp, - vcloud_plugin_common.Config.VCLOUD_CONFIG_PATH_DEFAULT) - - -def _install_docker(): - """ - install docker from https://get.docker.com/ - """ - distro = fabric.api.run( - 'python -c "import platform; print platform.dist()[0]"') - kernel_version = fabric.api.run( - 'python -c "import platform; print platform.release()"') - if kernel_version.startswith("3.13") and 'Ubuntu' in distro: - fabric.api.run("curl -sSL https://get.docker.com/ | sudo sh") - - -def _save_context(): - """ - save current managment network for use as default network for - all new nodes - """ - resources = dict() - - node_instances = ctx._endpoint.storage.get_node_instances() - nodes_by_id = \ - {node.id: node for node in ctx._endpoint.storage.get_nodes()} - - for node_instance in node_instances: - props = nodes_by_id[node_instance.node_id].properties - - if "management_network" == node_instance.node_id: - resources['int_network'] = { - "name": props.get('resource_id') - } - - provider = { - 'resources': resources - } - - ctx.instance.runtime_properties[PROVIDER_CONTEXT_RUNTIME_PROPERTY] = \ - provider diff --git a/manager_blueprint/scripts/configure_docker.py b/manager_blueprint/scripts/configure_docker.py deleted file mode 100644 index 7fb147e..0000000 --- a/manager_blueprint/scripts/configure_docker.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import fabric - - -def configure(vcloud_config): - """ - only update container with vcloud specific packages - """ - _update_container() - - -def _update_container(): - """ install some packeges for future deployments creation """ - # update system to last version - fabric.api.run("sudo docker exec -i -t cfy apt-get " - "update -q -y 2>&1") - fabric.api.run("sudo docker exec -i -t cfy apt-get " - "dist-upgrade -q -y 2>&1") - # install: - fabric.api.run("sudo docker exec -i -t cfy apt-get " - "install gcc python-dev libxml2-dev libxslt-dev " - "zlib1g-dev -q -y 2>&1") diff --git a/manager_blueprint/scripts/setup_grub.sh b/manager_blueprint/scripts/setup_grub.sh deleted file mode 100644 index 69fab0c..0000000 --- a/manager_blueprint/scripts/setup_grub.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -e - -sudo grub-install ${device_name} diff --git a/manager_blueprint/vcloud-manager-blueprint.yaml b/manager_blueprint/vcloud-manager-blueprint.yaml deleted file mode 100644 index bd884d5..0000000 --- a/manager_blueprint/vcloud-manager-blueprint.yaml +++ /dev/null @@ -1,594 +0,0 @@ -tosca_definitions_version: cloudify_dsl_1_0 - -imports: - - http://www.getcloudify.org/spec/cloudify/3.3rc1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.3rc1/plugin.yaml -inputs: - vcloud_username: - type: string - description: > - User login for vcloud air - - vcloud_password: - type: string - default: '' - description: > - User password for vcloud air - for login by name + password - - vcloud_token: - type: string - default: '' - description: > - User token for vcloud air - for login by name + token - - vcloud_url: - type: string - description: > - Vcloud url - - vcloud_service: - type: string - description: > - Vcloud service - - vcloud_service_type: - type: string - default: 'subscription' - description: > - Type of service: subscription, ondemand, vcd, private - - vcloud_instance: - type: string - default: '' - description: > - Only required for ondemand service type. - - vcloud_api_version: - type: string - default: '5.6' - description: > - Version of api, for now 5.6 - - vcloud_org_url: - type: string - default: '' - description: > - Only required if using token based login on a private vcloud - director. This can be obtained by following the vcloud API - example docs. If you are unsure of how to obtain this, you will - need to use password based login. - - vcloud_org: - type: string - description: > - Organization uuid - - vcloud_vdc: - type: string - description: > - Virtual data center name - - manager_server_name: - type: string - description: > - Name for server - - manager_server_catalog: - type: string - default: 'Public Catalog' - description: > - Name of catalog, can be 'Public Catalog' - - manager_server_template: - type: string - default: 'Ubuntu Server 12.04 LTS (amd64 20150127)' - description: > - Name of template from catalog, - can be 'Ubuntu Server 12.04 LTS (amd64 20150127)' - - manager_server_cpus: - type: string - default: 2 - description: > - Count cpu on node - - manager_server_memory: - type: string - default: 4096 - description: > - Amount memmory on node - - management_network_use_existing: - type: boolean - default: false - description: > - Use existed network - - management_network_name: - type: string - description: > - Name common network that can be used for nodes as managment - network - - management_port_ip_allocation_mode: - type: string - default: pool - description: > - Ip allocation type for case when you doesn't set public ip - for node and want auto allocate ip - - management_port_ip_address: - type: string - default: '' - description: > - Port public ip - - management_network_public_nat_use_existing: - type: boolean - default: false - description: > - Use already existed nat rules, only for case when you - doesn't want to change nat rules - - management_network_public_ip: - type: string - default: '' - description: > - Manager network public ip (used for SNAT) - - edge_gateway: - type: string - default: gateway - description: > - For 'ondemand' service type, the value of edge_gateway - is always 'gateway' - - manager_server_public_ip: - type: string - default: '' - description: > - For 'ondemand' service type, the value of - floating_ip_public_ip can be empty - - manager_server_ssh_port: - type: string - default: 22 - description: > - SSH port that can be used for installed node - - agents_user: - type: string - default: ubuntu - description: > - User name that will be used for agent - - manager_server_user: - default: ubuntu - type: string - description: > - User name that will be used for login to manager - - manager_private_key_path: - default: ~/.ssh/cloudify-manager-kp.pem - type: string - description: > - Private key for manager - - agent_private_key_path: - default: ~/.ssh/cloudify-agent-kp.pem - type: string - description: > - Private key for agent - - manager_public_key: - type: string - default: '' - description: > - Public key for manager - - agent_public_key: - type: string - default: '' - description: > - Public key for agent - - resources_prefix: - type: string - default: '' - description: > - Prefix for node name - - volume_use_external: - type: boolean - default: false - description: > - Use alredy exised volume - - volume_external_name: - type: string - default: '' - description: > - Volume resource id - - volume_name: - type: string - default: 'manager_disk' - description: > - Volume name - - volume_size_Mb: - type: string - default: 10240 - description: > - Volume size in Mb - -node_types: - vcloud_configuration: - derived_from: cloudify.nodes.Root - properties: - vcloud_config: {} - -node_templates: - - node_security_group: - type: cloudify.vcloud.nodes.SecurityGroup - properties: - security_group: - name: nodevcloud_security_group - edge_gateway: { get_input: edge_gateway } - rules: - - source: internal - destination: internal - destination_port: 22 - action: allow - description: > - ssh between nodes and management node - protocol: TCP - - source: external - destination: internal - destination_port: { get_input: manager_server_ssh_port } - action: allow - description: > - ssh between external net and managment node - protocol: TCP - - source: external - destination: internal - destination_port: 80 - action: allow - description: > - http to management node - protocol: TCP - - source: host - destination: any - action: allow - description: > - backward network connection for host updates - protocol: any - - source: external - destination: internal - action: allow - description: > - Allow ping - protocol: ICMP - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - - management_port: - type: cloudify.vcloud.nodes.Port - properties: - port: - network: { get_input: management_network_name } - ip_allocation_mode: { get_input: management_port_ip_allocation_mode } - ip_address: { get_input: management_port_ip_address } - primary_interface: true - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - relationships: - - target: management_network - type: cloudify.vcloud.port_connected_to_network - - management_network: - type: cloudify.vcloud.nodes.Network - properties: - use_external_resource: { get_input: management_network_use_existing } - resource_id: { get_input: management_network_name } - network: - name: { get_input: management_network_name } - edge_gateway: { get_input: edge_gateway } - static_range: 10.67.79.129-10.67.79.254 - netmask: 255.255.255.0 - gateway_ip: 10.67.79.1 - dns: - - 10.67.79.1 - - 8.8.8.8 - dhcp: - dhcp_range: 10.67.79.2-10.67.79.128 - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - relationships: - - target: management_network_nat - type: cloudify.vcloud.net_connected_to_public_nat - - management_network_nat: - type: cloudify.vcloud.nodes.PublicNAT - properties: - use_external_resource: { get_input: management_network_public_nat_use_existing } - nat: - edge_gateway: { get_input: edge_gateway } - public_ip: { get_input: management_network_public_ip } - rules: - - type: SNAT - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - - management_server_nat: - type: cloudify.vcloud.nodes.PublicNAT - properties: - nat: - edge_gateway: { get_input: edge_gateway } - public_ip: { get_input: manager_server_public_ip } - rules: - - type: DNAT - protocol: tcp - original_port: 80 - translated_port: 80 - - type: DNAT - protocol: tcp - original_port: 8086 - translated_port: 8086 - - type: DNAT - protocol: tcp - original_port: 443 - translated_port: 443 - - type: DNAT - protocol: tcp - original_port: { get_input: manager_server_ssh_port } - translated_port: 22 - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - - vcloud_configuration: - type: vcloud_configuration - properties: - vcloud_config: - username: { get_input: vcloud_username } - password: { get_input: vcloud_password } - token: { get_input: vcloud_token } - url: { get_input: vcloud_url } - service: { get_input: vcloud_service } - org: { get_input: vcloud_org } - vdc: { get_input: vcloud_vdc } - service_type: { get_input: vcloud_service_type } - instance: { get_input: vcloud_instance } - api_version: { get_input: vcloud_api_version } - org_url: { get_input: vcloud_org_url } - edge_gateway: { get_input: edge_gateway } - - manager_keypair: - type: cloudify.vcloud.nodes.KeyPair - properties: - private_key: - path: { get_input: manager_private_key_path } - public_key: - key: { get_input: manager_public_key } - user: { get_input: manager_server_user } - - agent_keypair: - type: cloudify.vcloud.nodes.KeyPair - properties: - private_key: - path: { get_input: agent_private_key_path } - public_key: - key: { get_input: agent_public_key } - user: { get_input: agents_user } - - manager_server: - type: cloudify.vcloud.nodes.Server - properties: - install_agent: false - server: - name: { get_input: manager_server_name } - catalog: { get_input: manager_server_catalog } - template: { get_input: manager_server_template } - guest_customization: - computer_name: { get_input: manager_server_name } - hardware: - cpu: { get_input: manager_server_cpus } - memory: { get_input: manager_server_memory } - management_network: { get_input: management_network_name } - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - relationships: - - target: management_port - type: cloudify.vcloud.server_connected_to_port - - target: management_server_nat - type: cloudify.vcloud.server_connected_to_public_nat - - target: node_security_group - type: cloudify.vcloud.server_connected_to_security_group - - target: agent_keypair - type: cloudify.vcloud.server_connected_to_keypair - - target: manager_keypair - type: cloudify.vcloud.server_connected_to_keypair - - volume: - type: cloudify.vcloud.nodes.Volume - properties: - device_name: /dev/sdb - volume: - name: { get_input: volume_name } - size: { get_input: volume_size_Mb } - use_external_resource: { get_input: volume_use_external } - resource_id: { get_input: volume_external_name } - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - relationships: - - type: cloudify.vcloud.volume_attached_to_server - target: manager_server - - manager_data: - type: cloudify.nodes.FileSystem - properties: - fs_type: ext4 - fs_mount_path: /var/lib/docker - interfaces: - cloudify.interfaces.lifecycle: - configure: - implementation: fabric.fabric_plugin.tasks.run_script - inputs: - script_path: https://raw.githubusercontent.com/cloudify-cosmo/cloudify-manager/master/resources/rest-service/cloudify/fs/mkfs.sh - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - relationships: - - type: cloudify.relationships.file_system_depends_on_volume - target: volume - source_interfaces: - cloudify.interfaces.relationship_lifecycle: - preconfigure: - implementation: fabric.fabric_plugin.tasks.run_script - inputs: - script_path: https://raw.githubusercontent.com/cloudify-cosmo/cloudify-manager/master/resources/rest-service/cloudify/fs/fdisk.sh - device_name: { get_attribute: [TARGET, device_name] } - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - postconfigure: - implementation: fabric.fabric_plugin.tasks.run_script - inputs: - script_path: scripts/setup_grub.sh - device_name: { get_attribute: [TARGET, device_name] } - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - - - - type: cloudify.relationships.file_system_contained_in_compute - target: manager_server - source_interfaces: - cloudify.interfaces.relationship_lifecycle: - establish: - implementation: fabric.fabric_plugin.tasks.run_script - inputs: - script_path: https://raw.githubusercontent.com/cloudify-cosmo/cloudify-manager/master/resources/rest-service/cloudify/fs/mount-docker.sh - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - unlink: - implementation: fabric.fabric_plugin.tasks.run_script - inputs: - script_path: https://raw.githubusercontent.com/cloudify-cosmo/cloudify-manager/master/resources/rest-service/cloudify/fs/unmount.sh - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - - manager: - type: cloudify.nodes.CloudifyManager - properties: - cloudify_packages: - agents: - ubuntu-trusty-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/Ubuntu-trusty-agent_3.3.0-m4-b274.tar.gz - centos-final-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/centos-Final-agent_3.3.0-m4-b274.tar.gz - ubuntu-precise-agent: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/Ubuntu-precise-agent_3.3.0-m4-b274.tar.gz - windows_agent_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/cloudify-windows-agent_3.3.0-m4-b274.exe - docker: - docker_url: http://gigaspaces-repository-eu.s3.amazonaws.com/org/cloudify3/3.3.0/m4-RELEASE/cloudify-docker_3.3.0-m4-b274.tar - - cloudify: - resources_prefix: { get_input: resources_prefix } - - cloudify_agent: - min_workers: 0 - max_workers: 5 - remote_execution_port: 22 - user: { get_input: agents_user } - - workflows: - task_retries: -1 # this means forever - task_retry_interval: 30 - - policy_engine: - start_timeout: 30 - - relationships: - - target: manager_server - type: cloudify.relationships.contained_in - - target: manager_data - type: cloudify.relationships.depends_on - - interfaces: - cloudify.interfaces.lifecycle: - create: - implementation: fabric.fabric_plugin.tasks.run_task - inputs: - tasks_file: scripts/configure.py - task_name: configure - task_properties: - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - configure: - implementation: fabric.fabric_plugin.tasks.run_module_task - inputs: - task_mapping: cloudify_cli.bootstrap.tasks.bootstrap_docker - task_properties: - cloudify_packages: { get_property: [manager, cloudify_packages] } - agent_local_key_path: { get_property: [agent_keypair, private_key, path] } - provider_context: { get_attribute: [manager, provider_context] } - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - start: - implementation: fabric.fabric_plugin.tasks.run_task - inputs: - tasks_file: scripts/configure_docker.py - task_name: configure - task_properties: - vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_input: manager_private_key_path } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - stop: - implementation: fabric.fabric_plugin.tasks.run_module_task - inputs: - task_mapping: cloudify_cli.bootstrap.tasks.stop_manager_container - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_property: [manager_keypair, private_key, path] } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - delete: - implementation: fabric.fabric_plugin.tasks.run_module_task - inputs: - task_mapping: cloudify_cli.bootstrap.tasks.stop_docker_service - fabric_env: - user: { get_input: manager_server_user } - key_filename: { get_property: [manager_keypair, private_key, path] } - host_string: { get_attribute: [management_server_nat, public_ip] } - port: { get_input: manager_server_ssh_port } - cloudify.interfaces.validation: - creation: - implementation: cli.cloudify_cli.bootstrap.tasks.creation_validation - inputs: - cloudify_packages: { get_property: [manager, cloudify_packages] } - - -plugins: - cli: - install: false - executor: central_deployment_agent - - -outputs: - manager_ip: - value: { get_attribute: [management_server_nat, public_ip] } diff --git a/tests/syntax_check.py b/tests/syntax_check.py index 918ef2b..5012b8e 100644 --- a/tests/syntax_check.py +++ b/tests/syntax_check.py @@ -16,7 +16,6 @@ import yaml yaml_files = ['../examples/blueprint.yaml', - '../manager_blueprint/vcloud-manager-blueprint.yaml', '../plugin.yaml'] diff --git a/tox.ini b/tox.ini index 7901635..b42b96b 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --c [testenv:pep8] commands= - flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin tests manager_blueprint/scripts + flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin tests ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py From 183ece0648fd6456ff5776fff1dc3ac47e47c9c4 Mon Sep 17 00:00:00 2001 From: Ran Date: Mon, 9 Nov 2015 20:05:04 +0200 Subject: [PATCH 158/228] parameterized vcloud nodecellar system test catalog and template will now be taken from the handler's properties --- system_tests/manager/nodecellar_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index 841d2e5..6601d4d 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -23,8 +23,8 @@ def test_vcloud_nodecellar(self): def get_inputs(self): return { - 'catalog': 'Public Catalog', - 'template': 'Ubuntu Server 12.04 LTS (amd64 20150127)', + 'catalog': self.env.catalog, + 'template': self.env.ubuntu_precise_template, 'edge_gateway': self.env.edge_gateway, 'management_network_name': self.env.management_network_name, 'agent_public_key': self.env.agent_public_key From 229122aaafd4739d2fefb96d3fec607e92406f6e Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 10 Nov 2015 09:02:05 +0400 Subject: [PATCH 159/228] Update ConfigReader for system test --- system_tests/vcloud_handler.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index e57c8a3..035607b 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -99,16 +99,16 @@ def floating_ip_public_ip(self): return self.config['floating_ip_public_ip'] @property - def manager_private_key_path(self): - return self.config['manager_private_key_path'] + def ssh_key_filename(self): + return self.config['ssh_key_filename'] @property def agent_private_key_path(self): return self.config['agent_private_key_path'] @property - def manager_public_key(self): - return self.config['manager_public_key'] + def user_public_key(self): + return self.config['user_public_key'] @property def agent_public_key(self): From 4c5db6afd29936c1379b4cc0a4094096dc109da1 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 10 Nov 2015 12:54:03 +0400 Subject: [PATCH 160/228] Update system tests --- system_tests/manager/nodecellar_test.py | 2 +- system_tests/vcloud_handler.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index 6601d4d..ef090cd 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -23,7 +23,7 @@ def test_vcloud_nodecellar(self): def get_inputs(self): return { - 'catalog': self.env.catalog, + 'catalog': self.env.public_catalog, 'template': self.env.ubuntu_precise_template, 'edge_gateway': self.env.edge_gateway, 'management_network_name': self.env.management_network_name, diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 035607b..69d5e8b 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -126,6 +126,13 @@ def vcloud_service_type(self): def vcloud_region(self): return self.config['vcloud_region'] + @property + def public_catalog(self): + return 'Public Catalog' + @property + def ubuntu_precise_template(self): + return 'Ubuntu Server 12.04 LTS (amd64 20150127)' + class VcloudHandler(BaseHandler): CleanupContext = VcloudCleanupContext From 63f6c697870c7a6aa7dc5249a5d8a3c8014a5e0f Mon Sep 17 00:00:00 2001 From: Chen Roth Date: Sun, 15 Nov 2015 14:45:27 +0200 Subject: [PATCH 161/228] Update plugin.yaml --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index f3c159d..cb1e87b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -3,7 +3,7 @@ plugins: executor: central_deployment_agent source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip package_name: cloudify-vcloud-plugin - package_version: 1.3rc1 + package_version: '1.3rc1' node_types: cloudify.vcloud.nodes.Server: From f9c164c04dfa3d6c399d0a7eb3541b5bb0d222d7 Mon Sep 17 00:00:00 2001 From: opencm Date: Tue, 17 Nov 2015 15:01:57 +0200 Subject: [PATCH 162/228] Bump version to 1.3 --- dev-requirements.txt | 6 +++--- plugin.yaml | 2 +- setup.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 3eafacf..8e6c254 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ --e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@3.3rc1#egg=cloudify-dsl-parser==3.3rc1 --e git+https://github.com/cloudify-cosmo/cloudify-rest-client@3.3rc1#egg=cloudify-rest-client==3.3rc1 --e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@3.3rc1#egg=cloudify-plugins-common==3.3rc1 +-e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@master#egg=cloudify-dsl-parser==3.3 +-e git+https://github.com/cloudify-cosmo/cloudify-rest-client@master#egg=cloudify-rest-client==3.3 +-e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@master#egg=cloudify-plugins-common==3.3 IPy pyvcloud>=14rc6 pycrypto diff --git a/plugin.yaml b/plugin.yaml index cb1e87b..291c874 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -3,7 +3,7 @@ plugins: executor: central_deployment_agent source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip package_name: cloudify-vcloud-plugin - package_version: '1.3rc1' + package_version: '1.3' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index f5adda1..fa1c0c9 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3rc1', + version='1.3', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3a7', + 'cloudify-plugins-common>=3.3', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From c890778063d21a86ea18ad0dbe924cc3a9677a86 Mon Sep 17 00:00:00 2001 From: opencm Date: Wed, 18 Nov 2015 19:55:29 +0200 Subject: [PATCH 163/228] Bump version to 1.3 --- plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.yaml b/plugin.yaml index 291c874..4992561 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.zip package_name: cloudify-vcloud-plugin package_version: '1.3' From 0f1a637294af9bf794a380bfad5a6b2deba3ec75 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Thu, 19 Nov 2015 14:40:38 +0400 Subject: [PATCH 164/228] Update requirements --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fa1c0c9..c088725 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3', + 'cloudify-plugins-common>=3.3a7', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From 3f91b8795ffb2957e0ccee99e7d721b82fce8cab Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 19 Nov 2015 14:03:49 +0200 Subject: [PATCH 165/228] CFY-4065: fix path to blueprint and input example --- manager_blueprint/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager_blueprint/README.md b/manager_blueprint/README.md index a3d50aa..b8dfae4 100644 --- a/manager_blueprint/README.md +++ b/manager_blueprint/README.md @@ -1,5 +1,5 @@ Manager blueprint moved to https://github.com/cloudify-cosmo/cloudify-manager-blueprints/ -Please use as manager blueprint such file: new/vcloud-manager-blueprint.yaml +Please use as manager blueprint such file: vcloud-manager-blueprint.yaml -Inputs example here: new/vcloud-manager-blueprint-inputs.yaml +Inputs example here: vcloud-manager-blueprint-inputs.yaml From e444b0455e1ab9b04e96f77a7471f626f46f864d Mon Sep 17 00:00:00 2001 From: opencm Date: Thu, 19 Nov 2015 21:15:31 +0200 Subject: [PATCH 166/228] Bump version to 1.3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c088725..fa1c0c9 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3a7', + 'cloudify-plugins-common>=3.3', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From 18a31838c847c394c9401ff1cc0de5c3cb669213 Mon Sep 17 00:00:00 2001 From: Nir Cohen Date: Mon, 23 Nov 2015 11:40:49 +0200 Subject: [PATCH 167/228] Removed unnecessary requirements from dev-requirements --- dev-requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 8e6c254..6658928 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,5 @@ -e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@master#egg=cloudify-dsl-parser==3.3 -e git+https://github.com/cloudify-cosmo/cloudify-rest-client@master#egg=cloudify-rest-client==3.3 -e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@master#egg=cloudify-plugins-common==3.3 -IPy pyvcloud>=14rc6 -pycrypto From d45d6f16b07348ee983cf8c8655274caacd5c3ba Mon Sep 17 00:00:00 2001 From: Nir Cohen Date: Tue, 24 Nov 2015 22:28:07 +0200 Subject: [PATCH 168/228] Update dev-requirements.txt --- dev-requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 6658928..a82c4b5 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ --e git+https://github.com/cloudify-cosmo/cloudify-dsl-parser@master#egg=cloudify-dsl-parser==3.3 --e git+https://github.com/cloudify-cosmo/cloudify-rest-client@master#egg=cloudify-rest-client==3.3 --e git+https://github.com/cloudify-cosmo/cloudify-plugins-common@master#egg=cloudify-plugins-common==3.3 +https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3 +https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3 +https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3 pyvcloud>=14rc6 From ac983d0c073ba9b515671cbde26004f01546eee0 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Fri, 27 Nov 2015 09:03:04 +0400 Subject: [PATCH 169/228] Cleanup system tests handler --- system_tests/vcloud_handler.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 69d5e8b..69c3947 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -23,6 +23,7 @@ TEST_VDC = "systest" + class VcloudCleanupContext(BaseHandler.CleanupContext): def __init__(self, context_name, env): @@ -34,9 +35,7 @@ def clean_all(cls, env): Cleans *all* resources, including resources that were not created by the test """ - import pdb; pdb.set_trace() - super(OpenstackCleanupContext, cls).clean_all(env) - #delete test VDC + super(VcloudCleanupContext, cls).clean_all(env) class CloudifyVcloudInputsConfigReader(BaseCloudifyInputsConfigReader): @@ -129,6 +128,7 @@ def vcloud_region(self): @property def public_catalog(self): return 'Public Catalog' + @property def ubuntu_precise_template(self): return 'Ubuntu Server 12.04 LTS (amd64 20150127)' @@ -158,19 +158,21 @@ def before_bootstrap(self): def login(env): vca = vcloudair.VCA( - host=env['vcloud_url'], - username=env['vcloud_username'], - service_type=env['vcloud_service_type'], - version="5.7", - verify=False) + host=env['vcloud_url'], + username=env['vcloud_username'], + service_type=env['vcloud_service_type'], + version="5.7", + verify=False) logined = (vca.login(env['vcloud_password']) and vca.login_to_instance(env['vcloud_instance'], env['vcloud_password']) and - vca.login_to_instance(env['vcloud_instance'], None, vca.vcloud_session.token, vca.vcloud_session.org_url)) + vca.login_to_instance(env['vcloud_instance'], None, + vca.vcloud_session.token, vca.vcloud_session.org_url)) if logined: return vca else: return None + def wait_for_task(vca_client, task): TASK_RECHECK_TIMEOUT = 5 TASK_STATUS_SUCCESS = 'success' @@ -194,4 +196,3 @@ def wait_for_task(vca_client, task): task = taskType.parseString(response.content, True) status = task.get_status() raise RuntimeError("Wait for task timeout.") - From 47f681b454005e3981ec24a540be1cbdd7b755d3 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 27 Nov 2015 10:53:27 +0200 Subject: [PATCH 170/228] CFY-2841: improve network_plugin coverage --- tests/unittests/test_mock_base.py | 11 +- .../test_mock_network_plugin_floatingip.py | 32 +++++- .../test_mock_network_plugin_network.py | 89 ++++++++++----- .../test_mock_network_plugin_public_nat.py | 101 ++++++++++++++---- ...test_mock_network_plugin_security_group.py | 10 ++ ...est_mock_server_plugin_server_subroutes.py | 27 +++++ vcloud_network_plugin/floatingip.py | 2 +- vcloud_server_plugin/server.py | 8 +- 8 files changed, 231 insertions(+), 49 deletions(-) diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 4c90643..c7feda5 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -96,9 +96,18 @@ def check_retry_realy_called(self, ctx): """ ctx.operation.retry.assert_called_with( message='Waiting for gateway.', - retry_after=30 + retry_after=vcloud_network_plugin.GATEWAY_TIMEOUT ) + def prepere_gatway_busy_retry(self, fake_client, fake_ctx): + """any operation for save gateway settings will return False""" + gateway = fake_client._vdc_gateway + self.set_gateway_busy(gateway) + self.set_services_conf_result( + fake_client._vdc_gateway, None + ) + self.prepare_retry(fake_ctx) + def generate_gateway( self, vdc_name="vdc", vms_networks=None, vdc_networks=None ): diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 110e53a..c8c61a5 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -370,8 +370,7 @@ def test_disconnect_floatingip(self): 'ssh_public_ip': '1.2.3.1' } fake_ctx._source.node.properties = { - 'vcloud_config': - { + 'vcloud_config': { 'edge_gateway': 'gateway', 'vdc': 'vdc' } @@ -382,6 +381,7 @@ def test_disconnect_floatingip(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) + # successfull with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -393,6 +393,23 @@ def test_disconnect_floatingip(self): self.assertFalse( vcloud_network_plugin.PUBLIC_IP in runtime_properties ) + runtime_properties = fake_ctx._source.instance.runtime_properties + self.assertFalse( + vcloud_network_plugin.SSH_PORT in runtime_properties + ) + # with retry + fake_ctx._target.instance.runtime_properties = { + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2' + } + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + floatingip.disconnect_floatingip( + ctx=fake_ctx + ) + self.check_retry_realy_called(fake_ctx) def test_connect_floatingip(self): """ @@ -423,6 +440,7 @@ def test_connect_floatingip(self): fake_client._vdc_gateway.get_nat_rules = mock.MagicMock( return_value=[] ) + # successfull with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -438,6 +456,16 @@ def test_connect_floatingip(self): runtime_properties.get(vcloud_network_plugin.PUBLIC_IP), '10.10.2.3' ) + # with retry + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + floatingip.connect_floatingip( + ctx=fake_ctx + ) + self.check_retry_realy_called(fake_ctx) def test_floatingip_operation_create(self): """ diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 590ec1b..418042a 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -97,7 +97,15 @@ def test_delete(self): fake_client.delete_vdc_network.assert_called_with( 'vdc_name', 'secret_network' ) + # retry in save configuration + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + network.delete(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) # Success in deleted vdc network + self.set_services_conf_result( + fake_client._vdc_gateway, + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) task_delete_vdc = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS ) @@ -105,6 +113,14 @@ def test_delete(self): return_value=(True, task_delete_vdc) ) network.delete(ctx=fake_ctx) + # in use + task_delete_vdc = self.generate_task( + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + fake_client.delete_vdc_network = mock.MagicMock( + return_value=(False, network.CANT_DELETE) + ) + network.delete(ctx=fake_ctx) def test_create(self): fake_client = self.generate_client() @@ -151,7 +167,7 @@ def test_create(self): ) with self.assertRaises(cfy_exc.NonRecoverableError): network.create(ctx=fake_ctx) - # success in create_vdc_network + # retry in save configuration fake_client.create_vdc_network = mock.MagicMock( return_value=( True, self.generate_task( @@ -159,6 +175,12 @@ def test_create(self): ) ) ) + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + network.create(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) + runtime_properties = fake_ctx.instance.runtime_properties + self.assertTrue(runtime_properties[network.SKIP_CREATE_NETWORK]) + # success in create_vdc_network self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -221,6 +243,31 @@ def test_create(self): with self.assertRaises(cfy_exc.NonRecoverableError): network.create(ctx=fake_ctx) + def node_for_check_create_network(self): + return self.generate_node_context( + properties={ + 'network': { + 'dhcp': { + 'dhcp_range': "10.1.1.128-10.1.1.255" + }, + 'static_range': "10.1.1.2-10.1.1.127", + 'gateway_ip': "10.1.1.1", + 'edge_gateway': 'gateway', + 'name': 'secret_network', + "netmask": '255.255.255.0', + "dns": ["8.8.8.8", "4.4.4.4"] + }, + 'vcloud_config': { + 'vdc': 'vdc_name' + }, + 'use_external_resource': False, + 'resource_id': 'secret_network' + }, + runtime_properties={ + 'vcloud_network_name': 'secret_network' + } + ) + def test_create_exist_same_network(self): fake_client = self.generate_client( vdc_networks=['secret_network'] @@ -230,33 +277,27 @@ def test_create_exist_same_network(self): mock.MagicMock(return_value=fake_client) ): # exist same network - fake_ctx = self.generate_node_context( - properties={ - 'network': { - 'dhcp': { - 'dhcp_range': "10.1.1.128-10.1.1.255" - }, - 'static_range': "10.1.1.2-10.1.1.127", - 'gateway_ip': "10.1.1.1", - 'edge_gateway': 'gateway', - 'name': 'secret_network', - "netmask": '255.255.255.0', - "dns": ["8.8.8.8", "4.4.4.4"] - }, - 'vcloud_config': { - 'vdc': 'vdc_name' - }, - 'use_external_resource': False, - 'resource_id': 'secret_network' - }, - runtime_properties={ - 'vcloud_network_name': 'secret_network' - } - ) + fake_ctx = self.node_for_check_create_network() fake_client.get_network = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): network.create(ctx=fake_ctx) + def test_dhcp_operation(self): + fake_ctx = fake_ctx = self.node_for_check_create_network() + fake_client = self.generate_client( + vdc_networks=['secret_network'] + ) + fake_client._vdc_gateway.is_busy = mock.MagicMock( + return_value=True + ) + with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + self.assertFalse( + network._dhcp_operation( + fake_client, 'secret_network', network.DELETE_POOL + ) + ) + def test_creation_validation(self): fake_client = self.generate_client( vdc_networks=['secret_network'] diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 510c70b..49a7e69 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -363,7 +363,12 @@ def _context_for_delete(service_type): gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) fake_ctx._target.instance.runtime_properties = { - vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" + vcloud_network_plugin.PUBLIC_IP: "1.2.3.4", + public_nat.PORT_REPLACEMENT: { + '127.0.0.1:10': '100' + }, + vcloud_network_plugin.SSH_PORT: '23', + vcloud_network_plugin.SSH_PUBLIC_IP: '10.1.1.1' } properties = { 'vcloud_config': { @@ -489,6 +494,16 @@ def _ip_exist_in_runtime(fake_ctx): ) gateway.deallocate_public_ip.assert_called_with("1.2.3.4") self.assertFalse(_ip_exist_in_runtime(fake_ctx)) + runtime_properties = fake_ctx._target.instance.runtime_properties + self.assertFalse( + public_nat.PORT_REPLACEMENT in runtime_properties + ) + self.assertFalse( + vcloud_network_plugin.SSH_PORT in runtime_properties + ) + self.assertFalse( + vcloud_network_plugin.SSH_PUBLIC_IP in runtime_properties + ) def test_nat_network_operation(self): fake_client = self.generate_client() @@ -908,7 +923,7 @@ def test_creation_validation(self): ): public_nat.creation_validation(ctx=fake_ctx) - def test_server_disconnect_from_nat(self): + def _server_disconnect_to_nat_noexternal(self): fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.instance.runtime_properties = { vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' @@ -932,6 +947,11 @@ def test_server_disconnect_from_nat(self): 'gateway_lock': False, 'vcloud_vapp_name': 'vapp' } + return fake_client, fake_ctx + + def test_server_disconnect_from_nat(self): + # successful + fake_client, fake_ctx = self._server_disconnect_to_nat_noexternal() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -940,8 +960,17 @@ def test_server_disconnect_from_nat(self): fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '1.1.1.1', 'any', 'any' ) + # check retry + fake_client, fake_ctx = self._server_disconnect_to_nat_noexternal() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + public_nat.server_disconnect_from_nat(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) - def test_server_connect_to_nat(self): + def _server_connect_to_nat_noexternal(self): fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.instance.runtime_properties = { vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' @@ -969,6 +998,10 @@ def test_server_connect_to_nat(self): fake_client._vdc_gateway.get_public_ips = mock.MagicMock( return_value=['10.18.1.1'] ) + return fake_client, fake_ctx + + def test_server_connect_to_nat(self): + fake_client, fake_ctx = self._server_connect_to_nat_noexternal() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -977,6 +1010,33 @@ def test_server_connect_to_nat(self): fake_client._vdc_gateway.add_nat_rule.assert_called_with( 'DNAT', '10.18.1.1', 'any', '1.1.1.1', 'any', 'any' ) + fake_client, fake_ctx = self._server_connect_to_nat_noexternal() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + public_nat.server_connect_to_nat(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) + + def _net_disconnect_from_nat_noexternal(self): + fake_client, fake_ctx = self.generate_client_and_context_network() + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'DNAT' + }] + } + fake_ctx._source.node.properties = { + 'vcloud_config': + { + 'edge_gateway': 'gateway', + 'vdc': 'vdc' + } + } + return fake_client, fake_ctx def test_net_disconnect_from_nat(self): # use external @@ -1002,23 +1062,7 @@ def test_net_disconnect_from_nat(self): ): public_nat.net_disconnect_from_nat(ctx=fake_ctx) # no external - fake_client, fake_ctx = self.generate_client_and_context_network() - fake_ctx._target.node.properties = { - 'nat': { - 'edge_gateway': 'gateway' - }, - 'rules': [{ - 'type': 'DNAT' - }] - } - fake_ctx._source.node.properties = { - 'vcloud_config': - { - 'edge_gateway': 'gateway', - 'vdc': 'vdc' - } - } - + fake_client, fake_ctx = self._net_disconnect_from_nat_noexternal() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -1028,6 +1072,15 @@ def test_net_disconnect_from_nat(self): 'DNAT', '192.168.1.1', 'any', '127.1.1.100 - 127.1.1.200', 'any', 'any' ) + # retry check + fake_client, fake_ctx = self._net_disconnect_from_nat_noexternal() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + public_nat.net_disconnect_from_nat(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) def test_net_connect_to_nat(self): # use external @@ -1078,6 +1131,14 @@ def test_net_connect_to_nat(self): 'DNAT', '10.18.1.1', 'any', '127.1.1.100 - 127.1.1.200', 'any', 'any' ) + # retry check + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + public_nat.net_connect_to_nat(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) def test_net_connect_to_nat_preconfigure(self): fake_client, fake_ctx = self.generate_client_and_context_network() diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index e84e08d..ebba487 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -355,7 +355,12 @@ def test_create(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): + # success case security_group.create(ctx=fake_ctx) + # with retry + self.prepere_gatway_busy_retry(fake_client, fake_ctx) + security_group.create(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) def test_delete(self): fake_ctx = self.generate_context_for_security_group() @@ -382,7 +387,12 @@ def test_delete(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): + # successful + security_group.delete(ctx=fake_ctx) + # with retry + self.prepere_gatway_busy_retry(fake_client, fake_ctx) security_group.delete(ctx=fake_ctx) + self.check_retry_realy_called(fake_ctx) def check_creation_validation(self, rule): fake_client = self.generate_client() diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index c95a35b..2087f65 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -476,6 +476,33 @@ def test_get_state(self): }]) self.assertTrue(server._get_state(fake_client)) + def test_add_key_script(self): + commands = [] + server._add_key_script(commands, "~A~", "~B~", "~C~", "~D~") + self.assertTrue(commands) + # check create directory .ssh + self.assertTrue("~A~" in commands[0]) + self.assertTrue("~B~" in commands[0]) + self.assertTrue("~C~" in commands[0]) + # inject value to key file + self.assertTrue("~C~" in commands[0]) + self.assertTrue("~D~" in commands[1]) + + def test_get_connected_keypairs(self): + # empty list of relationships + fake_ctx = self.generate_node_context() + fake_ctx.instance._relationships = None + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): + self.assertEqual([], server._get_connected_keypairs()) + # exist some content + relationship = self.generate_relation_context() + runtime_properties = {'public_key': "a"} + relationship.target.instance.runtime_properties = runtime_properties + fake_ctx.instance._relationships = [relationship] + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): + self.assertEqual( + server._get_connected_keypairs(), ["a"] + ) if __name__ == '__main__': unittest.main() diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index 722d630..eea0621 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -128,7 +128,7 @@ def _floatingip_operation(operation, vca_client, ctx): del ctx.target.instance.runtime_properties[PUBLIC_IP] if SSH_PUBLIC_IP in ctx.source.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] - if SSH_PORT in ctx.target.instance.runtime_properties: + if SSH_PORT in ctx.source.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PORT] return True diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 3fc2ddc..9963bef 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -560,17 +560,23 @@ def _build_script(custom, public_keys): def _get_connected_keypairs(): + """ + return public keys connected to node + """ relationships = getattr(ctx.instance, 'relationships', None) if relationships: return [relationship.target.instance.runtime_properties[PUBLIC_KEY] for relationship in relationships - if 'public_key' in + if PUBLIC_KEY in relationship.target.instance.runtime_properties] else: return [] def _add_key_script(commands, user, ssh_dir, keys_file, public_key): + """ + return commands for inject public key to node + """ add_key_template = "echo '{0}\n' >> {1}" test_ssh_dir_template = """ if [ ! -d {1} ];then From d6131f2607be2081d92dad05f53089b6514691ee Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 30 Nov 2015 18:32:02 +0200 Subject: [PATCH 171/228] CFY-2841: add volume and public_nat mock tests --- test-requirements.txt | 3 +- .../test_mock_network_plugin_public_nat.py | 122 +++++++++++++++++- .../test_mock_storage_plugin_volume.py | 53 ++++++++ vcloud_network_plugin/public_nat.py | 7 +- 4 files changed, 175 insertions(+), 10 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index 9bf68a2..a0ca08d 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -5,4 +5,5 @@ nose>=1.3 tox>=1.9 coverage pyflakes -flake8 \ No newline at end of file +flake8 +fabric diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 49a7e69..f94bdc5 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -515,11 +515,14 @@ def test_nat_network_operation(self): "2.3.4.5", "11", "11", "TCP" ) # run correct operation/rule - fake_ctx = self.generate_relation_context() - fake_ctx._target.instance.runtime_properties = { - public_nat.PORT_REPLACEMENT: {}} for operation in [vcloud_network_plugin.DELETE, vcloud_network_plugin.CREATE]: for rule_type in ["SNAT", "DNAT"]: + # cleanup properties + fake_ctx = self.generate_relation_context() + fake_ctx._target.instance.runtime_properties = { + public_nat.PORT_REPLACEMENT: {}} + fake_ctx._source.instance.runtime_properties = {} + # checks with mock.patch( 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): @@ -552,16 +555,47 @@ def test_nat_network_operation(self): 'SNAT', '2.3.4.5', 'any', '1.2.3.4', 'any', 'any' ) + # cleanup properties + fake_ctx = self.generate_relation_context() + fake_ctx._target.instance.runtime_properties = { + public_nat.PORT_REPLACEMENT: {}} + fake_ctx._source.instance.runtime_properties = {} + # save ssh port + with mock.patch( + 'vcloud_network_plugin.public_nat.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + public_nat.nat_network_operation( + fake_client, gateway, vcloud_network_plugin.CREATE, + "DNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" + ) + self.assertEqual( + {'port_replacement': {'1.2.3.4:43': 43}}, + fake_ctx._target.instance.runtime_properties + ) + self.assertEqual( + {'ssh_port': '43', 'ssh_public_ip': '1.2.3.4'}, + fake_ctx._source.instance.runtime_properties + ) + # error with type + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat.nat_network_operation( + fake_client, gateway, vcloud_network_plugin.CREATE, + "QNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" + ) - def generate_client_and_context_server(self): + def generate_client_and_context_server(self, no_vmip=False): """ for test prepare_server_operation based operations """ + vm_ip = '1.1.1.1' if not no_vmip else None fake_client = self.generate_client(vms_networks=[{ 'is_connected': True, 'network_name': 'network_name', 'is_primary': True, - 'ip': '1.1.1.1' + 'ip': vm_ip }]) self.set_network_routed_in_client(fake_client) fake_ctx = self.generate_relation_context() @@ -599,6 +633,59 @@ def test_prepare_server_operation(self): public_nat.prepare_server_operation( fake_client, vcloud_network_plugin.DELETE ) + # public ip equal to None in node properties + fake_client, fake_ctx = self.generate_client_and_context_server() + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': 'TCP', + 'original_port': "11", + 'translated_port': "11" + }] + } + fake_ctx._target.instance.runtime_properties = { + vcloud_network_plugin.PUBLIC_IP: None + } + with mock.patch( + 'vcloud_network_plugin.public_nat.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + self.assertFalse( + public_nat.prepare_server_operation( + fake_client, vcloud_network_plugin.DELETE + ) + ) + # we dont have connected private ip + fake_client, fake_ctx = self.generate_client_and_context_server( + no_vmip=True + ) + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': 'TCP', + 'original_port': "11", + 'translated_port': "11" + }] + } + with mock.patch( + 'vcloud_network_plugin.public_nat.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + self.assertFalse( + public_nat.prepare_server_operation( + fake_client, vcloud_network_plugin.DELETE + ) + ) # with some rules fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.node.properties = { @@ -726,6 +813,31 @@ def test_prepare_network_operation(self): public_nat.prepare_network_operation( fake_client, vcloud_network_plugin.DELETE ) + # public ip equal to None in node properties + fake_client, fake_ctx = self.generate_client_and_context_network() + fake_ctx._target.instance.runtime_properties = { + vcloud_network_plugin.PUBLIC_IP: None + } + fake_ctx._target.node.properties = { + 'nat': { + 'edge_gateway': 'gateway' + }, + 'rules': [{ + 'type': 'DNAT', + + }] + } + with mock.patch( + 'vcloud_network_plugin.public_nat.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + self.assertFalse( + public_nat.prepare_network_operation( + fake_client, vcloud_network_plugin.DELETE + ) + ) # rules with default values fake_client, fake_ctx = self.generate_client_and_context_network() fake_ctx._target.node.properties = { diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 25be7eb..e9279df 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -398,5 +398,58 @@ def test_detach_volume(self): ): volume.detach_volume(ctx=fake_ctx) + def run_wait_boot(self, fabric_settings, fabric_run, sleep_call=True): + sleep_function = mock.MagicMock() + with mock.patch( + 'fabric.api.settings', fabric_settings + ): + with mock.patch( + 'fabric.api.run', fabric_run + ): + with mock.patch( + 'time.sleep', sleep_function + ): + volume._wait_for_boot() + # check for sleep calls + if sleep_call: + sleep_function.assert_called_with(5) + + def test_wait_for_boot(self): + """ + check that machine is alive + """ + fake_ctx = self.generate_relation_context() + fake_ctx._target.instance.runtime_properties['ip'] = 'unknowhost' + fabric_context = mock.MagicMock(return_value=None) + fabric_context.__exit__ = mock.MagicMock(return_value=None) + fabric_context.__enter__ = mock.MagicMock(return_value=None) + fabric_settings = mock.MagicMock(return_value=fabric_context) + fabric_run = mock.MagicMock(return_value=None) + with mock.patch( + 'vcloud_plugin_common.ctx', fake_ctx + ): + with mock.patch( + 'vcloud_storage_plugin.volume.ctx', fake_ctx + ): + # can't connect and run + with self.assertRaises(cfy_exc.NonRecoverableError): + self.run_wait_boot(fabric_settings, fabric_run) + # command successfully finished + + def _sysexit(_): + raise SystemExit + + fabric_run = mock.MagicMock(side_effect=_sysexit) + self.run_wait_boot(fabric_settings, fabric_run, False) + # raised some exception during run + + def _raiseex(_): + raise Exception + + fabric_run = mock.MagicMock(side_effect=_raiseex) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.run_wait_boot(fabric_settings, fabric_run) + + if __name__ == '__main__': unittest.main() diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index a9f477c..63c60b6 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -131,10 +131,8 @@ def prepare_network_operation(vca_client, operation): if not public_ip: ctx.logger.info("We dont have public ip. Retrying...") return False + # if no private ip_range - raised error private_ip = _create_ip_range(vca_client, gateway) - if not private_ip: - ctx.logger.info("We dont have private ip. Retrying...") - return False for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] nat_network_operation( @@ -263,7 +261,8 @@ def _save_configuration(gateway, vca_client, operation, public_ip): def _create_ip_range(vca_client, gateway): """ - return ip range by avaible ranges from gateway and current network + return ip range by avaible ranges from gateway and current network, + on error - raise error, never return None """ network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] vdc_name = get_vcloud_config()['vdc'] From 63cb19a58ad7d4029a123354e411f11e413f2ac2 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 2 Dec 2015 10:06:00 +0200 Subject: [PATCH 172/228] CFY-2841: add test coverage for _is_primary_connection_has_ip --- .../test_mock_network_plugin_keypair.py | 109 ++++++++++++++++-- ...est_mock_server_plugin_server_subroutes.py | 33 ++++++ 2 files changed, 130 insertions(+), 12 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 4f732ff..b8d91de 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -71,34 +71,66 @@ def test_create(self): prop['private_key']['path']) mock.patch.stopall() + def _delete_subfunc(self, fake_ctx): + """run delete and check private/public key properties""" + prop = fake_ctx.instance.runtime_properties + self.assertTrue('path' in prop['private_key']) + keypair.delete(ctx=fake_ctx) + self.assertFalse('private_key' in prop) + self.assertFalse('public_key' in prop) + def test_delete(self): patcher = mock.patch('vcloud_network_plugin.keypair._delete_key_file', mock.MagicMock()) patcher.start() + # autogen keys fake_ctx = self.generate_node_context( properties={'auto_generate': True}, runtime_properties={'private_key': {'path': 'path', 'key': 'private'}, 'public_key': {'key': 'public'}}) prop = fake_ctx.instance.runtime_properties - self.assertTrue('path' in prop['private_key']) self.assertTrue('key' in prop['private_key']) self.assertTrue('key' in prop['public_key']) - keypair.delete(ctx=fake_ctx) - self.assertFalse('private_key' in prop) - self.assertFalse('public_key' in prop) + self._delete_subfunc(fake_ctx) + + # autogen keys with keyfile delete + fake_ctx = self.generate_node_context( + properties={ + 'auto_generate': True, + keypair.PRIVATE_KEY: { + keypair.CREATE_PRIVATE_KEY_FILE: 'something' + } + }, + runtime_properties={'private_key': {'path': 'path', + 'key': 'private'}, + 'public_key': {'key': 'public'}}) + prop = fake_ctx.instance.runtime_properties + self.assertTrue('key' in prop['private_key']) + self.assertTrue('key' in prop['public_key']) + + self._delete_subfunc(fake_ctx) + + # use keys generated by user fake_ctx = self.generate_node_context( properties={'auto_generate': False, - 'private_key': {'key': 'private'}}, + keypair.PRIVATE_KEY: {'key': 'private'}}, runtime_properties={'private_key': {'path': 'path'}, 'public_key': {}}) - prop = fake_ctx.instance.runtime_properties - self.assertTrue('path' in prop['private_key']) - keypair.delete(ctx=fake_ctx) - self.assertFalse('private_key' in prop) - self.assertFalse('public_key' in prop) + self._delete_subfunc(fake_ctx) + + # use keys generated by user with key file delete + fake_ctx = self.generate_node_context( + properties={'auto_generate': False, + keypair.PRIVATE_KEY: { + 'key': 'private', + keypair.CREATE_PRIVATE_KEY_FILE: 'something' + }}, + runtime_properties={'private_key': {'path': 'path'}, + 'public_key': {}}) + self._delete_subfunc(fake_ctx) mock.patch.stopall() @@ -143,9 +175,62 @@ def test_save_key_file(self): handle.write.assert_called_once_with('private') def test_delete_key_file(self): + unlink = mock.MagicMock() with mock.patch( - 'vcloud_network_plugin.keypair.os.unlink'): - keypair._delete_key_file('/path/') + 'vcloud_network_plugin.keypair.os.unlink', unlink): + keypair._delete_key_file({ + keypair.PRIVATE_KEY: { + keypair.PATH: '/path/' + } + }) + unlink.assert_called_with('/path/') + + def test_server_connect_to_keypair(self): + # check copy properties from target to source + fake_ctx = self.generate_relation_context() + fake_ctx.source.instance.runtime_properties = {} + fake_ctx.target.instance.runtime_properties = { + keypair.PRIVATE_KEY: { + keypair.PATH: '/path/', + keypair.KEY: 'key', + }, + keypair.PUBLIC_KEY: { + keypair.USER: 'user' + } + } + keypair.server_connect_to_keypair(ctx=fake_ctx) + self.assertEqual( + fake_ctx.source.instance.runtime_properties, + { + keypair.CLOUDIFY_AGENT: { + keypair.KEY: '/path/' + }, + keypair.SSH_KEY: { + keypair.KEY: 'key', + keypair.PATH: '/path/', + keypair.USER: 'user' + } + } + ) + + def test_server_disconnect_from_keypair(self): + # test drop all keys informations from node + fake_ctx = self.generate_relation_context() + fake_ctx.source.instance.runtime_properties = { + keypair.CLOUDIFY_AGENT: { + keypair.KEY: '/path/' + }, + keypair.SSH_KEY: { + keypair.KEY: 'key', + keypair.PATH: '/path/', + keypair.USER: 'user' + } + } + keypair.server_disconnect_from_keypair(ctx=fake_ctx) + self.assertEqual( + fake_ctx.source.instance.runtime_properties, {} + ) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 2087f65..2d5f571 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -504,5 +504,38 @@ def test_get_connected_keypairs(self): server._get_connected_keypairs(), ["a"] ) + def test_is_primary_connection_has_ip(self): + # no network info at all + vapp = mock.MagicMock() + vapp.get_vms_network_info = mock.MagicMock(return_value=False) + self.assertTrue(server._is_primary_connection_has_ip(vapp)) + # empty list of connections + vapp.get_vms_network_info = mock.MagicMock(return_value=[None]) + self.assertTrue(server._is_primary_connection_has_ip(vapp)) + # exist connection, but without ip + vapp.get_vms_network_info = mock.MagicMock(return_value=[[ + {'is_connected': False} + ]]) + self.assertFalse(server._is_primary_connection_has_ip(vapp)) + # everything connected + vapp.get_vms_network_info = mock.MagicMock(return_value=[[{ + 'is_connected': True, + 'is_primary': True, + 'ip': '127.0.0.1' + }]]) + self.assertTrue(server._is_primary_connection_has_ip(vapp)) + # connected but to different port + vapp.get_vms_network_info = mock.MagicMock(return_value=[[{ + 'is_connected': True, + 'is_primary': False, + 'ip': '127.0.0.1' + }, { + 'is_connected': True, + 'is_primary': True, + 'ip': None + }]]) + self.assertFalse(server._is_primary_connection_has_ip(vapp)) + + if __name__ == '__main__': unittest.main() From 3e419e9cd92d1cb32f7e5d644bd064f2b702a83e Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 7 Dec 2015 15:07:43 +0200 Subject: [PATCH 173/228] CFY-2841: improve coverage for server plugin --- tests/unittests/test_mock_base.py | 10 +- .../test_mock_server_plugin_server.py | 177 +++++++++++++++++- ...est_mock_server_plugin_server_subroutes.py | 46 +++++ 3 files changed, 223 insertions(+), 10 deletions(-) diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index c7feda5..a3e747c 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -90,13 +90,17 @@ def prepare_retry(self, ctx): return_value=None ) - def check_retry_realy_called(self, ctx): + def check_retry_realy_called(self, ctx, message=None, timeout=None): """ check that we really call retry """ + if not message: + message = 'Waiting for gateway.' + if not timeout: + timeout = vcloud_network_plugin.GATEWAY_TIMEOUT ctx.operation.retry.assert_called_with( - message='Waiting for gateway.', - retry_after=vcloud_network_plugin.GATEWAY_TIMEOUT + message=message, + retry_after=timeout ) def prepere_gatway_busy_retry(self, fake_client, fake_ctx): diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index dc28bb7..037fa7e 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -18,6 +18,7 @@ from cloudify import exceptions as cfy_exc from vcloud_server_plugin import server import vcloud_plugin_common +import vcloud_network_plugin from tests.unittests import test_mock_base @@ -219,6 +220,26 @@ def test_start(self): ) self.assertEquals(server.start(ctx=fake_ctx), None) + # use external without any power state changes, run retry + fake_ctx = self.generate_node_context() + fake_ctx.node.properties['use_external_resource'] = True + fake_client = self.generate_client([{ + 'is_connected': True, + 'is_primary': True, + 'network_name': '_management_network', + 'ip': None + }]) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + self.prepare_retry(fake_ctx) + server.start(ctx=fake_ctx) + self.check_retry_realy_called( + fake_ctx, + "Waiting for VM's configuration to complete", 5 + ) + def test_start_external_resource(self): """ start with external resource, as success status used retry @@ -271,10 +292,31 @@ def test_create_default_values(self): server.create(ctx=fake_ctx) self.check_create_call(fake_client, fake_ctx) - def test_create_cpu_mem_values(self): + def test_create_configure_cpu_mem_values(self): """ check custom cpu/memmory with error in task """ + # use existed vm + fake_ctx = self.generate_node_context( + properties={ + 'management_network': '_management_network', + 'vcloud_config': { + 'vdc': 'vdc_name' + }, + 'use_external_resource': True, + 'resource_id': 'some_server' + }, + relation_node_properties={ + "not_test": "not_test" + } + ) + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + server.configure(ctx=fake_ctx) + # can't get vapp fake_ctx = self.generate_node_context( properties={ 'management_network': '_management_network', @@ -287,6 +329,12 @@ def test_create_cpu_mem_values(self): 'hardware': { 'cpu': 1, 'memory': 512 + }, + 'guest_customization': { + 'pre_script': 'pre_script', + 'post_script': 'post_script', + 'admin_password': 'pass', + 'computer_name': 'computer' } } }, @@ -295,11 +343,22 @@ def test_create_cpu_mem_values(self): } ) fake_client = self.generate_client() + fake_client.get_vapp = mock.MagicMock(return_value=None) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + server.configure(ctx=fake_ctx) + # create new vm + fake_client = self.generate_client() self.run_with_statuses( fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( @@ -317,6 +376,7 @@ def test_create_cpu_mem_values(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) + # can't customize cpu with self.assertRaises(cfy_exc.NonRecoverableError): server.configure(ctx=fake_ctx) @@ -333,12 +393,65 @@ def test_create_cpu_mem_values(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) + + # need force customization, successfull customization + fake_client._vapp.customize_on_next_poweron = mock.MagicMock( + return_value=False + ) + server.configure(ctx=fake_ctx) + + # somethin wrong with force_customization + fake_client._vapp.force_customization = mock.MagicMock( + return_value=None + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + server.configure(ctx=fake_ctx) + # everything fine + fake_client._vapp.customize_on_next_poweron = mock.MagicMock( + return_value=True + ) + server.configure(ctx=fake_ctx) server.create(ctx=fake_ctx) fake_client._vapp.modify_vm_name.assert_called_with( 1, 'test' ) + # we dont have connected ip + fake_client._vapp.get_vms_network_info = mock.MagicMock( + return_value=[[{'is_connected': False}]] + ) + fake_client._vapp.me.get_status = mock.MagicMock( + return_value=vcloud_plugin_common.STATUS_POWERED_ON + ) + sleep_mock = mock.MagicMock() + with mock.patch( + 'time.sleep', + sleep_mock + ): + server.configure(ctx=fake_ctx) + sleep_mock.assert_called_with( + vcloud_network_plugin.GATEWAY_TIMEOUT + ) + # after first run we have ip + vapp_with_network = mock.MagicMock() + vapp_with_network.get_vms_network_info = mock.MagicMock( + return_value=[[{ + 'is_connected': True, + 'is_primary': True, + 'network_name': 'network_name', + 'ip': '1.1.1.1' + }]] + ) + fake_client.get_vapp = mock.MagicMock( + side_effect=[fake_client._vapp, vapp_with_network] + ) + with mock.patch( + 'time.sleep', + sleep_mock + ): + server.configure(ctx=fake_ctx) + def check_create_call(self, fake_client, fake_ctx, positive=True): fake_client.create_vapp.assert_called_with( 'vdc_name', 'test', 'template', 'catalog' @@ -351,8 +464,9 @@ def check_create_call(self, fake_client, fake_ctx, positive=True): def run_with_statuses( self, fake_client, fake_ctx, - create_app=None, connect_to_network=None, connect_vms=None, - customize_guest_os=None + create_app=None, modify_vm_name=None, + connect_to_network=None, connect_vms=None, + customize_guest_os=None, force_customization=None ): fake_task = None if create_app: @@ -361,6 +475,13 @@ def run_with_statuses( return_value=fake_task ) + fake_modify_vm_name = None + if modify_vm_name: + fake_modify_vm_name = self.generate_task(modify_vm_name) + fake_client._vapp.modify_vm_name = mock.MagicMock( + return_value=fake_modify_vm_name + ) + fake_task_network = None if connect_to_network: fake_task_network = self.generate_task(connect_to_network) @@ -382,6 +503,13 @@ def run_with_statuses( return_value=fake_task_customize ) + fake_force_customization = None + if force_customization: + fake_force_customization = self.generate_task(force_customization) + fake_client._vapp.force_customization = mock.MagicMock( + return_value=fake_force_customization + ) + def generate_context_for_create(self): return self.generate_node_context( properties={ @@ -459,6 +587,7 @@ def test_create_connection_error(self): self.run_with_statuses( fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_ERROR ) with mock.patch( @@ -469,6 +598,25 @@ def test_create_connection_error(self): server.create(ctx=fake_ctx) self.check_create_call(fake_client, fake_ctx) + def test_create_cant_change_name(self): + """ + test server create with default value and empty task + from change name + """ + fake_ctx = self.generate_context_for_create() + fake_client = self.generate_client() + self.run_with_statuses( + fake_client, fake_ctx, + vcloud_plugin_common.TASK_STATUS_SUCCESS + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + server.create(ctx=fake_ctx) + self.check_create_call(fake_client, fake_ctx) + def test_create_connection_empty_task(self): """ test server create with default value and empty task @@ -478,6 +626,7 @@ def test_create_connection_empty_task(self): fake_client = self.generate_client() self.run_with_statuses( fake_client, fake_ctx, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( @@ -492,6 +641,7 @@ def test_create_cant_get_vapp(self): """ test server create with default value and empty vapp """ + # with create fake_ctx = self.generate_context_for_create() fake_client = self.generate_client() fake_client.get_vapp = mock.MagicMock( @@ -500,6 +650,7 @@ def test_create_cant_get_vapp(self): self.run_with_statuses( fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( @@ -509,6 +660,15 @@ def test_create_cant_get_vapp(self): with self.assertRaises(cfy_exc.NonRecoverableError): server.create(ctx=fake_ctx) self.check_create_call(fake_client, fake_ctx) + # use external resourse + fake_ctx.node.properties['use_external_resource'] = True + fake_ctx.node.properties['resource_id'] = 'someresource' + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + with self.assertRaises(cfy_exc.NonRecoverableError): + server.create(ctx=fake_ctx) def test_create_link_empty(self): """ @@ -519,6 +679,7 @@ def test_create_link_empty(self): self.run_with_statuses( fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( @@ -540,6 +701,7 @@ def test_create_link_error(self): fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_ERROR ) with mock.patch( @@ -560,16 +722,13 @@ def test_create_link_success(self): fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - # can't change vapp_name - with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) - self.check_create_call(fake_client, fake_ctx) fake_client._vapp.modify_vm_name = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -587,6 +746,7 @@ def test_create_customization(self): fake_client, fake_ctx, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( @@ -607,6 +767,7 @@ def test_create_customization_error(self): vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_ERROR ) with mock.patch( @@ -627,6 +788,7 @@ def test_create_customization_un_customized(self): vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) fake_client._vapp.customize_on_next_poweron = mock.MagicMock( @@ -656,6 +818,7 @@ def test_create_customization_customized(self): vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS, + vcloud_plugin_common.TASK_STATUS_SUCCESS, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with mock.patch( diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 2d5f571..fa4c952 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -302,6 +302,43 @@ def test_create_connections_list(self): } ], connection ) + # get network name from first avaible but not primary + fake_ctx = self.generate_node_context(relation_node_properties={ + "not_test": "not_test", + 'port': { + 'network': 'private_network', + 'ip_address': "1.1.1.1", + 'mac_address': "hex", + 'ip_allocation_mode': 'pool', + 'primary_interface': False + } + }) + fake_client = self.generate_client() + fake_ctx.node.properties['management_network'] = None + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + connection = server._create_connections_list(fake_client) + self.assertEqual( + [ + { + 'ip_address': '1.1.1.1', + 'ip_allocation_mode': 'POOL', + 'mac_address': 'hex', + 'network': 'private_network', + 'primary_interface': True + } + ], connection + ) + # no connections + fake_ctx = self.generate_node_context(relation_node_properties={ + "not_test": "not_test" + }) + fake_client = self.generate_client() + fake_ctx.node.properties['management_network'] = None + with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + with self.assertRaises(cfy_exc.NonRecoverableError): + connection = server._create_connections_list(fake_client) # one network same as managment + port fake_ctx = self.generate_node_context(relation_node_properties={ "not_test": "not_test", @@ -536,6 +573,15 @@ def test_is_primary_connection_has_ip(self): }]]) self.assertFalse(server._is_primary_connection_has_ip(vapp)) + def test_remove_key_script(self): + commands = [] + server._remove_key_script( + commands, "super!", ".ssh!", "somekey", "!**! !@^" + ) + self.assertEqual( + commands, [' sed -i /!@^/d somekey'] + ) + if __name__ == '__main__': unittest.main() From 42eab4f271b6a5b7997fe3d7151f223cdd741111 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 7 Dec 2015 15:34:12 +0200 Subject: [PATCH 174/228] CFY-2841: fix typo --- tests/unittests/test_mock_server_plugin_server.py | 2 +- tests/unittests/test_mock_storage_plugin_volume.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 037fa7e..2fbc16d 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -660,7 +660,7 @@ def test_create_cant_get_vapp(self): with self.assertRaises(cfy_exc.NonRecoverableError): server.create(ctx=fake_ctx) self.check_create_call(fake_client, fake_ctx) - # use external resourse + # use external resource fake_ctx.node.properties['use_external_resource'] = True fake_ctx.node.properties['resource_id'] = 'someresource' with mock.patch( diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index e9279df..30aa70b 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -99,7 +99,7 @@ def test_creation_validation_internal(self): with self.assertRaises(cfy_exc.NonRecoverableError): volume.creation_validation(ctx=fake_ctx) fake_client.get_disks.assert_called_with('vdc_name') - # internal resourse wit volume and name, + # internal resource wit volume and name, # but already exist such volume fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', From cf8528be70a59e740cf7c50a1c79607a5d4d069d Mon Sep 17 00:00:00 2001 From: opencm Date: Mon, 14 Dec 2015 13:05:51 +0200 Subject: [PATCH 175/228] Bump version to 1.3.1 --- dev-requirements.txt | 6 +++--- plugin.yaml | 4 ++-- setup.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index a82c4b5..87dffb3 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ -https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3 -https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3 -https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3 +https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3.1 +https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3.1 +https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3.1 pyvcloud>=14rc6 diff --git a/plugin.yaml b/plugin.yaml index 4992561..9c00d4a 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.1.zip package_name: cloudify-vcloud-plugin - package_version: '1.3' + package_version: '1.3.1' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index fa1c0c9..5f56e36 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3', + version='1.3.1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3', + 'cloudify-plugins-common>=3.3.1', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From cc2cd308c060ee2c16a850255122011a01521b53 Mon Sep 17 00:00:00 2001 From: opencm Date: Thu, 24 Dec 2015 22:56:25 +0200 Subject: [PATCH 176/228] Bump version to 1.3.1m1 --- dev-requirements.txt | 6 +++--- plugin.yaml | 4 ++-- setup.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index a82c4b5..744a593 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ -https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3 -https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3 -https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3 +https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.4a1 +https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.4a1 +https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.4a1 pyvcloud>=14rc6 diff --git a/plugin.yaml b/plugin.yaml index 4992561..9c00d4a 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.1.zip package_name: cloudify-vcloud-plugin - package_version: '1.3' + package_version: '1.3.1' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index fa1c0c9..a9d5053 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3', + version='1.3.1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3', + 'cloudify-plugins-common>=3.4a1', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From 602e18a7bfbf23f602e1523e24ee24bc9cf0d43c Mon Sep 17 00:00:00 2001 From: opencm Date: Fri, 25 Dec 2015 01:17:25 +0200 Subject: [PATCH 177/228] Bump version to 1.3.1m1 --- examples/blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index 3a90ebe..f2d0bbf 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: cloudify_dsl_1_2 imports: - - http://www.getcloudify.org/spec/cloudify/3.3rc1/types.yaml + - http://www.getcloudify.org/spec/cloudify/3.3.1/types.yaml - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3rc1/plugin.yaml node_types: From 8392a0f4aa6fd0b7d41a3c2b1fc797101140cbf3 Mon Sep 17 00:00:00 2001 From: opencm Date: Fri, 25 Dec 2015 01:54:29 +0200 Subject: [PATCH 178/228] Bump version to 1.3.1m1 --- dev-requirements.txt | 6 +++--- setup.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 744a593..87dffb3 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ -https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.4a1 -https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.4a1 -https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.4a1 +https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3.1 +https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3.1 +https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3.1 pyvcloud>=14rc6 diff --git a/setup.py b/setup.py index a9d5053..5f56e36 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.4a1', + 'cloudify-plugins-common>=3.3.1', 'pyvcloud>=14rc9', 'requests>=2.4.0', 'IPy==0.81', From 5744d25580eb4be2ba22233fd8a703ef8d894959 Mon Sep 17 00:00:00 2001 From: ran Date: Mon, 4 Jan 2016 12:23:55 +0200 Subject: [PATCH 179/228] CFY-4653 froze vcloud plugin dependencies versions --- dev-requirements.txt | 7 +++++-- setup.py | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 87dffb3..f99fe63 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,8 @@ https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3.1 https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3.1 https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3.1 -pyvcloud>=14rc6 - +pyvcloud==15rc1 +requests==2.7.0 +IPy==0.81 +PyYAML==3.10 +pycrypto==2.6.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 5f56e36..f4c95ac 100644 --- a/setup.py +++ b/setup.py @@ -27,10 +27,10 @@ description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.3.1', - 'pyvcloud>=14rc9', - 'requests>=2.4.0', + 'pyvcloud==15rc1', + 'requests==2.7.0', 'IPy==0.81', 'PyYAML==3.10', - 'pycrypto' + 'pycrypto==2.6.1' ] ) From b14054c3f0a862f8b89a2599d8f77aba87a210c4 Mon Sep 17 00:00:00 2001 From: ran Date: Mon, 4 Jan 2016 12:23:55 +0200 Subject: [PATCH 180/228] CFY-4653 froze vcloud plugin dependencies versions --- dev-requirements.txt | 7 +++++-- setup.py | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 87dffb3..f99fe63 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,8 @@ https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3.1 https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3.1 https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3.1 -pyvcloud>=14rc6 - +pyvcloud==15rc1 +requests==2.7.0 +IPy==0.81 +PyYAML==3.10 +pycrypto==2.6.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 5f56e36..f4c95ac 100644 --- a/setup.py +++ b/setup.py @@ -27,10 +27,10 @@ description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.3.1', - 'pyvcloud>=14rc9', - 'requests>=2.4.0', + 'pyvcloud==15rc1', + 'requests==2.7.0', 'IPy==0.81', 'PyYAML==3.10', - 'pycrypto' + 'pycrypto==2.6.1' ] ) From a5d25e94f722f791b0a74a010bc2d8d677204bf8 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 5 May 2016 16:04:11 +0300 Subject: [PATCH 181/228] CFY-5244 override 'server' node properties by operation inputs --- vcloud_server_plugin/server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 9963bef..0277006 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -107,6 +107,7 @@ def create(vca_client, **kwargs): 'name': ctx.instance.id, } server.update(ctx.node.properties.get('server', {})) + server.update(kwargs.get('server', {})) transform_resource_name(server, ctx) if ctx.node.properties.get('use_external_resource'): @@ -307,6 +308,7 @@ def configure(vca_client, **kwargs): ctx.logger.info("Configure server") server = {'name': ctx.instance.id} server.update(ctx.node.properties.get('server', {})) + server.update(kwargs.get('server', {})) ctx.logger.info("Server properties: {0}" .format(str(server))) vapp_name = server['name'] From 00c2cde0e3baa590abf3627713f8fa2fc09c7363 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 12 May 2016 17:55:14 +0300 Subject: [PATCH 182/228] fix tests for use with 3.4 common plugin code --- setup.py | 4 +- tests/unittests/test_mock_base.py | 38 ++- .../test_mock_network_plugin_floatingip.py | 59 +++-- .../test_mock_network_plugin_keypair.py | 20 +- .../test_mock_network_plugin_network.py | 26 +- .../test_mock_network_plugin_port.py | 12 +- .../test_mock_network_plugin_public_nat.py | 226 ++++++++++-------- ...test_mock_network_plugin_security_group.py | 8 +- .../test_mock_server_plugin_server.py | 44 ++-- ...est_mock_server_plugin_server_subroutes.py | 126 ++++++---- .../unittests/test_mock_server_plugin_vdc.py | 20 +- .../test_mock_storage_plugin_volume.py | 19 +- vcloud_network_plugin/floatingip.py | 4 +- vcloud_network_plugin/public_nat.py | 4 +- vcloud_network_plugin/security_group.py | 4 +- vcloud_plugin_common/workflows.py | 5 +- vcloud_server_plugin/server.py | 4 +- 17 files changed, 349 insertions(+), 274 deletions(-) diff --git a/setup.py b/setup.py index f4c95ac..be5232e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.3.1', + version='1.4a5', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.3.1', + 'cloudify-plugins-common>=3.4a3', 'pyvcloud==15rc1', 'requests==2.7.0', 'IPy==0.81', diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index a3e747c..3255716 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -16,6 +16,7 @@ import unittest from cloudify import mocks as cfy_mocks import vcloud_network_plugin +from cloudify.state import current_ctx vcloud_network_plugin.GATEWAY_TRY_COUNT = 2 vcloud_network_plugin.GATEWAY_TIMEOUT = 1 @@ -42,16 +43,6 @@ def nodes(self): return self._nodes -class MockToscaNodeInstanceContext(cfy_mocks.MockNodeInstanceContext): - """node instance mock for use with tosca""" - - _relationships = None - - @property - def relationships(self): - return self._relationships - - class TestBase(unittest.TestCase): ERROR_PLACE = "ERROR_MESSAGE_PLACE_HOLDER" @@ -388,6 +379,14 @@ def generate_relation_context(self): ) return fake_ctx + def generate_relation_context_with_current_ctx(self): + # generate new relation context with save such context + # to current context that requed by 3.4 cloudify common plugin + # changes + fake_ctx = self.generate_relation_context() + current_ctx.set(fake_ctx) + return fake_ctx + def generate_node_context( self, relation_node_properties=None, properties=None, runtime_properties=None @@ -412,7 +411,7 @@ def generate_node_context( runtime_properties=runtime_properties ) - fake_ctx._instance = MockToscaNodeInstanceContext( + fake_ctx._instance = cfy_mocks.MockNodeInstanceContext( fake_ctx.instance._id, fake_ctx.instance._runtime_properties ) @@ -421,3 +420,20 @@ def generate_node_context( fake_ctx.instance._relationships = [relationship] return fake_ctx + + def generate_node_context_with_current_ctx( + self, relation_node_properties=None, properties=None, + runtime_properties=None + ): + # generate new node context with save such context + # to current context that requed by 3.4 cloudify common plugin + # changes + fake_ctx = self.generate_node_context( + relation_node_properties, properties, + runtime_properties + ) + current_ctx.set(fake_ctx) + return fake_ctx + + def tearDown(self): + current_ctx.clear() diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index c8c61a5..97f8313 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -25,7 +25,8 @@ class NetworkPluginFloatingIpMockTestCase(test_mock_base.TestBase): def test_add_nat_rule_snat(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway._add_nat_rule = mock.MagicMock(return_value=None) @@ -37,7 +38,8 @@ def test_add_nat_rule_snat(self): ) def test_add_nat_rule_dnat(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway._add_nat_rule = mock.MagicMock(return_value=None) @@ -49,7 +51,8 @@ def test_add_nat_rule_dnat(self): ) def test_del_nat_rule_snat(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway.del_nat_rule = mock.MagicMock(return_value=None) @@ -61,7 +64,8 @@ def test_del_nat_rule_snat(self): ) def test_del_nat_rule_dnat(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() + with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): gateway = mock.Mock() gateway.del_nat_rule = mock.MagicMock(return_value=None) @@ -75,7 +79,7 @@ def test_del_nat_rule_dnat(self): def test_creation_validation(self): fake_client = self.generate_client() # no floating_ip - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name' @@ -89,7 +93,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): floatingip.creation_validation(ctx=fake_ctx) # no edge gateway - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name' @@ -106,7 +110,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): floatingip.creation_validation(ctx=fake_ctx) # with edge gateway, but wrong ip - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name' @@ -124,15 +128,17 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): floatingip.creation_validation(ctx=fake_ctx) # with edge gateway, ip from pool - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name' - }, - 'floatingip': { - 'edge_gateway': 'gateway', - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name' + }, + 'floatingip': { + 'edge_gateway': 'gateway', + 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + } } - }) + ) fake_client._vdc_gateway.get_public_ips = mock.MagicMock( return_value=['10.18.1.1'] ) @@ -142,16 +148,18 @@ def test_creation_validation(self): ): floatingip.creation_validation(ctx=fake_ctx) # with some free ip - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name' - }, - 'floatingip': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.10.1.2', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name' + }, + 'floatingip': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.10.1.2', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + } } - }) + ) fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.1.1.1', '10.1.1.2' ]) @@ -184,7 +192,7 @@ def generate_client_and_context_floating_ip( vcloud_plugin_common.TASK_STATUS_SUCCESS ) # ctx - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._source.node.properties = { 'vcloud_config': { 'service_type': service_type, @@ -440,6 +448,7 @@ def test_connect_floatingip(self): fake_client._vdc_gateway.get_nat_rules = mock.MagicMock( return_value=[] ) + # successfull with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index b8d91de..e408951 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -23,14 +23,14 @@ class NetworkPluginKeyPairpMockTestCase(test_mock_base.TestBase): def test_creation_validation(self): # exist keyfile - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'private_key': {'path': __file__} } ) keypair.creation_validation(ctx=fake_ctx) # not exist keyfile - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'private_key': {'path': __file__ + ".not_exist"} } @@ -51,7 +51,7 @@ def test_create(self): patcher2.start() patcher3.start() - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={'auto_generate': True, 'private_key': {'create_file': True}}) keypair.create(ctx=fake_ctx) @@ -61,7 +61,7 @@ def test_create(self): self.assertEqual('private', prop['private_key']['key']) self.assertEqual('public', prop['public_key']['key']) - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={'auto_generate': False, 'private_key': {'key': 'private', 'create_file': True}}) @@ -85,7 +85,7 @@ def test_delete(self): patcher.start() # autogen keys - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={'auto_generate': True}, runtime_properties={'private_key': {'path': 'path', 'key': 'private'}, @@ -97,7 +97,7 @@ def test_delete(self): self._delete_subfunc(fake_ctx) # autogen keys with keyfile delete - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'auto_generate': True, keypair.PRIVATE_KEY: { @@ -114,7 +114,7 @@ def test_delete(self): self._delete_subfunc(fake_ctx) # use keys generated by user - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={'auto_generate': False, keypair.PRIVATE_KEY: {'key': 'private'}}, runtime_properties={'private_key': {'path': 'path'}, @@ -122,7 +122,7 @@ def test_delete(self): self._delete_subfunc(fake_ctx) # use keys generated by user with key file delete - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={'auto_generate': False, keypair.PRIVATE_KEY: { 'key': 'private', @@ -187,7 +187,7 @@ def test_delete_key_file(self): def test_server_connect_to_keypair(self): # check copy properties from target to source - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx.source.instance.runtime_properties = {} fake_ctx.target.instance.runtime_properties = { keypair.PRIVATE_KEY: { @@ -215,7 +215,7 @@ def test_server_connect_to_keypair(self): def test_server_disconnect_from_keypair(self): # test drop all keys informations from node - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx.source.instance.runtime_properties = { keypair.CLOUDIFY_AGENT: { keypair.KEY: '/path/' diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 418042a..ca13c5a 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -29,7 +29,7 @@ def test_delete(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -53,7 +53,7 @@ def test_delete(self): fake_ctx.instance.runtime_properties ) - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -128,7 +128,7 @@ def test_create(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -191,7 +191,7 @@ def test_create(self): with self.assertRaises(cfy_exc.NonRecoverableError): network.create(ctx=fake_ctx) # use external - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -216,7 +216,7 @@ def test_create(self): ) network.create(ctx=fake_ctx) # not extist network - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -244,7 +244,7 @@ def test_create(self): network.create(ctx=fake_ctx) def node_for_check_create_network(self): - return self.generate_node_context( + return self.generate_node_context_with_current_ctx( properties={ 'network': { 'dhcp': { @@ -283,7 +283,7 @@ def test_create_exist_same_network(self): network.create(ctx=fake_ctx) def test_dhcp_operation(self): - fake_ctx = fake_ctx = self.node_for_check_create_network() + fake_ctx = self.node_for_check_create_network() fake_client = self.generate_client( vdc_networks=['secret_network'] ) @@ -307,7 +307,7 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): # network not exist in node properties - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': False, 'resource_id': 'secret_network' @@ -319,7 +319,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): network.creation_validation(ctx=fake_ctx) # network already exist - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': False, 'resource_id': 'secret_network', @@ -349,7 +349,7 @@ def test_creation_validation(self): 'vdc_name', 'secret_network' ) # use external - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True, 'resource_id': 'secret_network', @@ -382,7 +382,7 @@ def test_creation_validation_gateway(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': False, 'network': { @@ -424,7 +424,7 @@ def test_creation_validation_network_mask(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': False, 'network': { @@ -459,7 +459,7 @@ def test_creation_validation_separate_ips(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': False, 'network': { diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index a619417..508d232 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -29,13 +29,13 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): # no port - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={} ) with self.assertRaises(cfy_exc.NonRecoverableError): port.creation_validation(ctx=fake_ctx) # port without allocation - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'port': { 'some_field': 'some_value' @@ -44,7 +44,7 @@ def test_creation_validation(self): ) port.creation_validation(ctx=fake_ctx) # wrong allocation mode - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'port': { 'ip_allocation_mode': 'realy wrong' @@ -55,7 +55,7 @@ def test_creation_validation(self): port.creation_validation(ctx=fake_ctx) # correct allocation for mode in ['manual', 'dhcp', 'pool']: - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'port': { 'ip_allocation_mode': mode @@ -64,7 +64,7 @@ def test_creation_validation(self): ) port.creation_validation(ctx=fake_ctx) # wrong manual ip - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'port': { 'ip_allocation_mode': 'manual', @@ -75,7 +75,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): port.creation_validation(ctx=fake_ctx) # correct manual ip - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'port': { 'ip_allocation_mode': 'manual', diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index f94bdc5..c75228e 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -45,7 +45,7 @@ def test_is_rule_exists(self): def test_get_original_port_for_delete(self): # no replacement - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {}} @@ -57,7 +57,7 @@ def test_get_original_port_for_delete(self): "11" ) # replacement for other - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: { "10.1.1.2:11": '12' @@ -71,7 +71,7 @@ def test_get_original_port_for_delete(self): "11" ) # replacement for other - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: { "10.1.1.2:11": '12' @@ -87,7 +87,7 @@ def test_get_original_port_for_delete(self): def test_get_original_port_for_create(self): gateway = mock.Mock() - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() rule_inlist = self.generate_nat_rule( 'DNAT', 'external', 'any', 'internal', '11', 'TCP') gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) @@ -111,7 +111,7 @@ def test_get_original_port_for_create(self): def test_get_original_port_for_create_with_ctx(self): # with replace, but without replace table - up port +1 - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {} } @@ -197,7 +197,7 @@ def test_get_gateway_ip_range(self): ) def test_obtain_public_ip(self): - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { vcloud_network_plugin.PUBLIC_IP: '192.168.1.1' } @@ -298,7 +298,7 @@ def test_get_network_ip_range(self): def test_create_ip_range(self): # context - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._source.instance.runtime_properties = { vcloud_network_plugin.network.VCLOUD_NETWORK_NAME: "some" } @@ -358,7 +358,7 @@ def _context_for_delete(service_type): """ create correct context for delete """ - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) @@ -396,7 +396,7 @@ def _ip_exist_in_runtime(fake_ctx): gateway, None ) self.set_gateway_busy(gateway) - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() with mock.patch( 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): @@ -405,7 +405,7 @@ def _ip_exist_in_runtime(fake_ctx): )) # operation create - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) @@ -515,10 +515,12 @@ def test_nat_network_operation(self): "2.3.4.5", "11", "11", "TCP" ) # run correct operation/rule - for operation in [vcloud_network_plugin.DELETE, vcloud_network_plugin.CREATE]: + for operation in [ + vcloud_network_plugin.DELETE, vcloud_network_plugin.CREATE + ]: for rule_type in ["SNAT", "DNAT"]: # cleanup properties - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {}} fake_ctx._source.instance.runtime_properties = {} @@ -556,7 +558,7 @@ def test_nat_network_operation(self): 'any' ) # cleanup properties - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {}} fake_ctx._source.instance.runtime_properties = {} @@ -598,7 +600,7 @@ def generate_client_and_context_server(self, no_vmip=False): 'ip': vm_ip }]) self.set_network_routed_in_client(fake_client) - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.node.properties = { 'nat': { 'edge_gateway': 'gateway' @@ -779,7 +781,7 @@ def generate_client_and_context_network(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) # ctx - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._source.instance.runtime_properties = { vcloud_network_plugin.network.VCLOUD_NETWORK_NAME: "some" } @@ -865,7 +867,7 @@ def test_prepare_network_operation(self): def test_creation_validation(self): fake_client = self.generate_client() # no nat - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name' @@ -879,7 +881,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # no gateway - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name' @@ -896,16 +898,18 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # wrong ip - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: 'any' + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: 'any' + } } - }) + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -913,15 +917,17 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # no free ip - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway' + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway' + } } - }) + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -929,16 +935,18 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # no rules - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + } } - }) + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -946,20 +954,22 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # wrong protocol - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' - }, - 'rules': [{ - 'type': 'DNAT', - 'protocol': "some" - }] - }) + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': "some" + }] + } + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -967,21 +977,23 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # wrong original_port - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' - }, - 'rules': [{ - 'type': 'DNAT', - 'protocol': "TCP", - 'original_port': 'some' - }] - }) + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': "TCP", + 'original_port': 'some' + }] + } + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -990,22 +1002,24 @@ def test_creation_validation(self): public_nat.creation_validation(ctx=fake_ctx) # wrong original_port - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' - }, - 'rules': [{ - 'type': 'DNAT', - 'protocol': "TCP", - 'original_port': 11, - 'translated_port': 'some' - }] - }) + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': "TCP", + 'original_port': 11, + 'translated_port': 'some' + }] + } + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -1013,22 +1027,24 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.creation_validation(ctx=fake_ctx) # fine - fake_ctx = self.generate_node_context(properties={ - 'vcloud_config': { - 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE - }, - 'nat': { - 'edge_gateway': 'gateway', - vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' - }, - 'rules': [{ - 'type': 'DNAT', - 'protocol': "TCP", - 'original_port': 11, - 'translated_port': 12 - }] - }) + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name', + 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + }, + 'nat': { + 'edge_gateway': 'gateway', + vcloud_network_plugin.PUBLIC_IP: '10.12.2.1' + }, + 'rules': [{ + 'type': 'DNAT', + 'protocol': "TCP", + 'original_port': 11, + 'translated_port': 12 + }] + } + ) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -1230,7 +1246,6 @@ def test_net_connect_to_nat(self): 'vdc': 'vdc' } } - fake_client._vdc_gateway.get_public_ips = mock.MagicMock(return_value=[ '10.18.1.1' ]) @@ -1292,6 +1307,5 @@ def test_net_connect_to_nat_preconfigure(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) - if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index ebba487..0533736 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -34,7 +34,7 @@ def test_get_gateway_name_from_params(self): ) def test_get_gateway_name_from_ctx(self): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'edge_gateway': 'some_edge_gateway' @@ -50,7 +50,7 @@ def test_get_gateway_name_from_ctx(self): ) def generate_context_for_security_group(self): - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._source.node.properties = { 'vcloud_config': { 'edge_gateway': 'some_edge_gateway', @@ -400,7 +400,7 @@ def check_creation_validation(self, rule): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'edge_gateway': 'some_edge_gateway', @@ -417,7 +417,7 @@ def test_creation_validation(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'edge_gateway': 'some_edge_gateway', diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 2fbc16d..c5f7172 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -25,7 +25,7 @@ class ServerPluginServerMockTestCase(test_mock_base.TestBase): def test_delete_external_resource(self): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True } @@ -42,7 +42,7 @@ def test_delete_external_resource(self): ) def test_delete(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() fake_client = self.generate_client() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -80,7 +80,7 @@ def test_delete(self): ) def test_stop_external_resource(self): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True } @@ -97,7 +97,7 @@ def test_stop_external_resource(self): ) def test_stop(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() fake_client = self.generate_client() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -140,7 +140,7 @@ def check_get_vapp(self, fake_client, vapp_name): ) def test_start(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() fake_client = self.generate_client([{ 'is_connected': True, 'is_primary': True, @@ -221,7 +221,7 @@ def test_start(self): self.assertEquals(server.start(ctx=fake_ctx), None) # use external without any power state changes, run retry - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() fake_ctx.node.properties['use_external_resource'] = True fake_client = self.generate_client([{ 'is_connected': True, @@ -244,7 +244,7 @@ def test_start_external_resource(self): """ start with external resource, as success status used retry """ - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True, 'vcloud_config': { @@ -269,16 +269,18 @@ def test_create_default_values(self): """ test server create with default value and error in request """ - fake_ctx = self.generate_node_context(properties={ - 'management_network': '_management_network', - 'vcloud_config': { - 'vdc': 'vdc_name' - }, - 'server': { - 'template': 'template', - 'catalog': 'catalog' + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'management_network': '_management_network', + 'vcloud_config': { + 'vdc': 'vdc_name' + }, + 'server': { + 'template': 'template', + 'catalog': 'catalog' + } } - }) + ) fake_client = self.generate_client() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -297,7 +299,7 @@ def test_create_configure_cpu_mem_values(self): check custom cpu/memmory with error in task """ # use existed vm - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'management_network': '_management_network', 'vcloud_config': { @@ -317,7 +319,7 @@ def test_create_configure_cpu_mem_values(self): ): server.configure(ctx=fake_ctx) # can't get vapp - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'management_network': '_management_network', 'vcloud_config': { @@ -511,7 +513,7 @@ def run_with_statuses( ) def generate_context_for_create(self): - return self.generate_node_context( + return self.generate_node_context_with_current_ctx( properties={ 'management_network': '_management_network', 'vcloud_config': { @@ -528,7 +530,7 @@ def generate_context_for_create(self): ) def generate_context_for_customization(self): - return self.generate_node_context( + return self.generate_node_context_with_current_ctx( properties={ 'management_network': '_management_network', 'vcloud_config': { @@ -555,7 +557,7 @@ def test_create_external_resource(self): """ must run without any errors """ - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True, 'resource_id': 'ServerName', diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index fa4c952..ddb54b8 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -19,6 +19,7 @@ from cloudify import mocks as cfy_mocks from vcloud_server_plugin import server from tests.unittests import test_mock_base +from cloudify.state import current_ctx class ServerPluginServerSubRoutesMockTestCase(test_mock_base.TestBase): @@ -105,6 +106,7 @@ def test_creation_validation_empty_settings(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient', @@ -127,6 +129,7 @@ def test_creation_validation_external_resource(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient', @@ -144,6 +147,7 @@ def test_creation_validation_external_resource(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient', @@ -163,6 +167,7 @@ def test_creation_validation_settings_wrong_catalog(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -183,6 +188,7 @@ def test_creation_validation_settings_wrong_template(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -203,6 +209,7 @@ def test_creation_validation_settings(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -226,6 +233,7 @@ def test_isDhcpAvailable(self): }, provider_context={} ) + current_ctx.set(fake_ctx) with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): @@ -241,9 +249,11 @@ def test_isDhcpAvailable(self): def test_get_connected(self): - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test" - }) + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test" + } + ) self.assertEqual( server._get_connected(fake_ctx.instance, "test"), [] @@ -262,19 +272,21 @@ def test_get_connected(self): def test_create_connections_list(self): # one connection from port, one from network and # one managment_network - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test", - 'port': { - 'network': 'private_network', - 'ip_address': "1.1.1.1", - 'mac_address': "hex", - 'ip_allocation_mode': 'pool', - 'primary_interface': True - }, - 'network': { - 'name': 'some_network' + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test", + 'port': { + 'network': 'private_network', + 'ip_address': "1.1.1.1", + 'mac_address': "hex", + 'ip_allocation_mode': 'pool', + 'primary_interface': True + }, + 'network': { + 'name': 'some_network' + } } - }) + ) fake_client = self.generate_client() with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): @@ -303,16 +315,18 @@ def test_create_connections_list(self): ], connection ) # get network name from first avaible but not primary - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test", - 'port': { - 'network': 'private_network', - 'ip_address': "1.1.1.1", - 'mac_address': "hex", - 'ip_allocation_mode': 'pool', - 'primary_interface': False + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test", + 'port': { + 'network': 'private_network', + 'ip_address': "1.1.1.1", + 'mac_address': "hex", + 'ip_allocation_mode': 'pool', + 'primary_interface': False + } } - }) + ) fake_client = self.generate_client() fake_ctx.node.properties['management_network'] = None with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): @@ -330,9 +344,11 @@ def test_create_connections_list(self): ], connection ) # no connections - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test" - }) + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test" + } + ) fake_client = self.generate_client() fake_ctx.node.properties['management_network'] = None with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): @@ -340,19 +356,21 @@ def test_create_connections_list(self): with self.assertRaises(cfy_exc.NonRecoverableError): connection = server._create_connections_list(fake_client) # one network same as managment + port - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test", - 'port': { - 'network': '_management_network', - 'ip_address': "1.1.1.1", - 'mac_address': "hex", - 'ip_allocation_mode': 'pool', - 'primary_interface': True - }, - 'network': { - 'name': 'some_network' + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test", + 'port': { + 'network': '_management_network', + 'ip_address': "1.1.1.1", + 'mac_address': "hex", + 'ip_allocation_mode': 'pool', + 'primary_interface': True + }, + 'network': { + 'name': 'some_network' + } } - }) + ) with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): connection = server._create_connections_list(fake_client) @@ -375,19 +393,21 @@ def test_create_connections_list(self): ], connection ) # check dhcp, with no dhcp server - fake_ctx = self.generate_node_context(relation_node_properties={ - "not_test": "not_test", - 'port': { - 'network': '_management_network', - 'ip_address': "1.1.1.1", - 'mac_address': "hex", - 'ip_allocation_mode': 'dhcp', - 'primary_interface': True - }, - 'network': { - 'name': 'some_network' + fake_ctx = self.generate_node_context_with_current_ctx( + relation_node_properties={ + "not_test": "not_test", + 'port': { + 'network': '_management_network', + 'ip_address': "1.1.1.1", + 'mac_address': "hex", + 'ip_allocation_mode': 'dhcp', + 'primary_interface': True + }, + 'network': { + 'name': 'some_network' + } } - }) + ) with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): @@ -478,7 +498,7 @@ def test_get_vm_network_connection(self): self.assertEqual(None, connection) def test_get_state(self): - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): # connected network_name @@ -527,7 +547,7 @@ def test_add_key_script(self): def test_get_connected_keypairs(self): # empty list of relationships - fake_ctx = self.generate_node_context() + fake_ctx = self.generate_node_context_with_current_ctx() fake_ctx.instance._relationships = None with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): self.assertEqual([], server._get_connected_keypairs()) diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py index 51c7805..3e422c1 100644 --- a/tests/unittests/test_mock_server_plugin_vdc.py +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -29,14 +29,14 @@ def test_creation_validation(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={} ) # no vdc name with self.assertRaises(cfy_exc.NonRecoverableError): vdc.creation_validation(ctx=fake_ctx) # name exist but someone already created this vdc - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'name': 'not_existed' } @@ -51,7 +51,7 @@ def test_creation_validation(self): fake_client.get_vdc = mock.MagicMock(return_value=None) vdc.creation_validation(ctx=fake_ctx) # external but without name - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True } @@ -59,7 +59,7 @@ def test_creation_validation(self): with self.assertRaises(cfy_exc.NonRecoverableError): vdc.creation_validation(ctx=fake_ctx) # use unexisted vdc - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'use_external_resource': True, 'resource_id': 'not_existed' @@ -84,7 +84,7 @@ def test_create(self): mock.MagicMock(return_value=fake_client) ): # tried to create new vdc on subscription - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE @@ -95,7 +95,7 @@ def test_create(self): vdc.create(ctx=fake_ctx) # use ondemand # use external resource without vdc - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE @@ -114,7 +114,7 @@ def test_create(self): ) vdc.create(ctx=fake_ctx) # no name for vdc - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE @@ -125,7 +125,7 @@ def test_create(self): with self.assertRaises(cfy_exc.NonRecoverableError): vdc.create(ctx=fake_ctx) # create new vdc for deployment - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE @@ -156,7 +156,7 @@ def test_delete(self): mock.MagicMock(return_value=fake_client) ): # external resorce - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE @@ -170,7 +170,7 @@ def test_delete(self): fake_client.delete_vdc = mock.MagicMock( return_value=(False, None) ) - fake_ctx = self.generate_node_context( + fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 30aa70b..9cf6e42 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -21,9 +21,10 @@ import vcloud_plugin_common from tests.unittests import test_mock_base import vcloud_network_plugin +from cloudify.state import current_ctx -class StoaragePluginVolumeMockTestCase(test_mock_base.TestBase): +class StoragePluginVolumeMockTestCase(test_mock_base.TestBase): # vapp name used for tests VAPPNAME = "some_other" @@ -40,6 +41,7 @@ def test_creation_validation_external_resource(self): } } ) + current_ctx.set(fake_ctx) # use external without resource_id with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', @@ -60,6 +62,7 @@ def test_creation_validation_external_resource(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -92,6 +95,8 @@ def test_creation_validation_internal(self): } } ) + current_ctx.set(fake_ctx) + with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -114,6 +119,7 @@ def test_creation_validation_internal(self): } } ) + current_ctx.set(fake_ctx) fake_client.get_disks = mock.MagicMock(return_value=[ [ self.generate_fake_client_disk('some'), @@ -140,6 +146,7 @@ def test_creation_validation_internal(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -161,6 +168,7 @@ def test_creation_validation_internal(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -180,6 +188,7 @@ def test_delete_volume(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -200,6 +209,7 @@ def test_delete_volume(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -236,6 +246,7 @@ def test_create_volume(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -256,6 +267,7 @@ def test_create_volume(self): } } ) + current_ctx.set(fake_ctx) with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) @@ -292,6 +304,7 @@ def _run_volume_operation(fake_ctx, fake_client, operation): 'vcloud_storage_plugin.volume.ctx', fake_ctx ): volume._volume_operation(fake_client, operation) + # use external resource, no disks _run_volume_operation(fake_ctx, fake_client, 'ATTACH') fake_client.get_diskRefs.assert_called_with( @@ -357,7 +370,7 @@ def _run_volume_operation(fake_ctx, fake_client, operation): def _gen_volume_context_and_client(self): fake_client = self.generate_client() - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.node.properties = { 'use_external_resource': True } @@ -418,7 +431,7 @@ def test_wait_for_boot(self): """ check that machine is alive """ - fake_ctx = self.generate_relation_context() + fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties['ip'] = 'unknowhost' fabric_context = mock.MagicMock(return_value=None) fabric_context.__exit__ = mock.MagicMock(return_value=None) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index eea0621..f41023a 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -86,8 +86,8 @@ def _floatingip_operation(operation, vca_client, ctx): internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None - public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) - or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) + public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or + ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 63c60b6..9bc80e0 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -402,7 +402,9 @@ def _is_rule_exists(nat_rules, rule_type, """ # gatewayNatRule properties may be None or string # convert to str, bacause port can be int - cicmp = lambda t: t[1] and (str(t[0]).lower() == str(t[1]).lower()) + def cicmp(t): + return t[1] and (str(t[0]).lower() == str(t[1]).lower()) + for natRule in nat_rules: gatewayNatRule = natRule.get_GatewayNatRule() if (all(map(cicmp, [ diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index ab4416e..edadead 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -92,8 +92,8 @@ def creation_validation(vca_client, **kwargs): utils.check_protocol(rule.get('protocol')) action = get_mandatory(rule, "action") - if (not isinstance(action, basestring) - or action.lower() not in ACTIONS): + if (not isinstance(action, basestring) or + action.lower() not in ACTIONS): raise cfy_exc.NonRecoverableError( "Action must be on of{0}.".format(ACTIONS)) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index c48a3ad..38c1ad1 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -43,9 +43,8 @@ def _get_all_nodes_instances(ctx, token, org_url): node_instances = set() for node in ctx.nodes: for instance in node.instances: - if (vcloud_plugin_common.VCLOUD_CONFIG in node.properties - and token - and org_url): + if (vcloud_plugin_common.VCLOUD_CONFIG in node.properties and + token and org_url): update(ctx, instance, token, org_url) node_instances.add(instance) return node_instances diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 0277006..40891b9 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -675,8 +675,8 @@ def _create_connections_list(vca_client): # in case when we dont have any primary networks for conn in connections: network_name = conn['network'] - if (conn['ip_allocation_mode'] == 'DHCP' - and not _isDhcpAvailable(vca_client, network_name)): + if (conn['ip_allocation_mode'] == 'DHCP' and + not _isDhcpAvailable(vca_client, network_name)): raise cfy_exc.NonRecoverableError( "DHCP for network {0} is not available" .format(network_name)) From fb1bc7a8f227a07d1315d395248c04bb048a4ee3 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 25 May 2016 14:43:04 +0400 Subject: [PATCH 183/228] User can define port creation order with parameter 'nic_order' --- .../blueprints/server_to_many_ports.yaml | 94 +++++++++++++++++++ tests/integration/test_server_plugin.py | 7 ++ vcloud_server_plugin/server.py | 10 +- 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 tests/integration/blueprints/server_to_many_ports.yaml diff --git a/tests/integration/blueprints/server_to_many_ports.yaml b/tests/integration/blueprints/server_to_many_ports.yaml new file mode 100644 index 0000000..c777909 --- /dev/null +++ b/tests/integration/blueprints/server_to_many_ports.yaml @@ -0,0 +1,94 @@ + test_port1: + type: cloudify.vcloud.nodes.Port + properties: + port: + network: test_network1 + ip_allocation_mode: POOL + primary_interface: true + nic_order: 1 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_network1 + type: cloudify.vcloud.port_connected_to_network + + + test_port2: + type: cloudify.vcloud.nodes.Port + properties: + port: + network: test_network2 + ip_allocation_mode: POOL + primary_interface: false + nic_order: 2 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_network2 + type: cloudify.vcloud.port_connected_to_network + + + test_port3: + type: cloudify.vcloud.nodes.Port + properties: + port: + network: test_network3 + ip_allocation_mode: POOL + primary_interface: false + nic_order: 3 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_network3 + type: cloudify.vcloud.port_connected_to_network + + + test_network1: + type: cloudify.vcloud.nodes.Network + properties: + network: + edge_gateway: { get_input: edge_gateway } + name: test_network1 + static_range: 10.11.199.2-10.11.199.128 + netmask: 255.255.255.0 + gateway_ip: 10.11.199.1 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_network2: + type: cloudify.vcloud.nodes.Network + properties: + network: + edge_gateway: { get_input: edge_gateway } + name: test_network2 + static_range: 10.12.199.2-10.12.199.128 + netmask: 255.255.255.0 + gateway_ip: 10.12.199.1 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_network3: + type: cloudify.vcloud.nodes.Network + properties: + network: + edge_gateway: { get_input: edge_gateway } + name: test_network3 + static_range: 10.13.199.2-10.13.199.128 + netmask: 255.255.255.0 + gateway_ip: 10.13.199.1 + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + + + test_server: + type: cloudify.vcloud.nodes.Server + properties: + server: + catalog: { get_input: catalog } + template: { get_input: template } + install_agent: false + management_network: { get_input: network_name } + vcloud_config: { get_property: [vcloud_configuration, vcloud_config] } + relationships: + - target: test_port1 + type: cloudify.vcloud.server_connected_to_port + - target: test_port2 + type: cloudify.vcloud.server_connected_to_port + - target: test_port3 + type: cloudify.vcloud.server_connected_to_port diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index 7accd42..e136f8a 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -66,6 +66,13 @@ def test_connect_to_port(self): self.install() self.uninstall() + @fail_guard + def test_connect_to_many_ports(self): + self.init('server_to_many_ports.yaml') + self.install() + import pdb; pdb.set_trace() # XXX BREAKPOINT + self.uninstall() + @fail_guard def test_remove_keys(self): self.init('server_remove_keys.yaml') diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 9963bef..a5805e0 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -638,7 +638,8 @@ def _create_connections_list(vca_client): port_properties.get('mac_address'), port_properties.get('ip_allocation_mode', 'POOL').upper(), - port_properties.get('primary_interface', False)) + port_properties.get('primary_interface', False), + port_properties.get('nic_order', 0)) ) for net in networks: @@ -686,7 +687,7 @@ def _create_connections_list(vca_client): "The primary interface has been set to {}".format( network_name)) - return connections + return sorted(connections, key=lambda k: k['nic_order']) def _get_connected(instance, prop): @@ -702,7 +703,7 @@ def _get_connected(instance, prop): def _create_connection(network, ip_address, mac_address, ip_allocation_mode, - primary_interface=False): + primary_interface=False, nic_order=0): """ repack fields to dict """ @@ -710,7 +711,8 @@ def _create_connection(network, ip_address, mac_address, ip_allocation_mode, 'ip_address': ip_address, 'mac_address': mac_address, 'ip_allocation_mode': ip_allocation_mode, - 'primary_interface': primary_interface} + 'primary_interface': primary_interface, + 'nic_order': nic_order} def _isDhcpAvailable(vca_client, network_name): From afacf851d7aeb2078c28536a257861aecb652823 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Wed, 25 May 2016 14:51:23 +0400 Subject: [PATCH 184/228] Update unittests --- tests/integration/test_server_plugin.py | 1 - ...est_mock_server_plugin_server_subroutes.py | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index e136f8a..f4022d3 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -70,7 +70,6 @@ def test_connect_to_port(self): def test_connect_to_many_ports(self): self.init('server_to_many_ports.yaml') self.install() - import pdb; pdb.set_trace() # XXX BREAKPOINT self.uninstall() @fail_guard diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index 2087f65..99ed5d5 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -286,19 +286,22 @@ def test_create_connections_list(self): 'ip_allocation_mode': 'POOL', 'mac_address': 'hex', 'network': 'private_network', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 }, { 'ip_address': None, 'ip_allocation_mode': 'POOL', 'mac_address': None, 'network': 'some_network', - 'primary_interface': False + 'primary_interface': False, + 'nic_order': 0 }, { 'ip_address': None, 'ip_allocation_mode': 'POOL', 'mac_address': None, 'network': '_management_network', - 'primary_interface': False + 'primary_interface': False, + 'nic_order': 0 } ], connection ) @@ -326,14 +329,16 @@ def test_create_connections_list(self): 'ip_allocation_mode': 'POOL', 'mac_address': 'hex', 'network': '_management_network', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 }, { 'ip_address': None, 'ip_allocation_mode': 'POOL', 'mac_address': None, 'network': 'some_network', - 'primary_interface': False + 'primary_interface': False, + 'nic_order': 0 } ], connection ) @@ -345,7 +350,8 @@ def test_create_connections_list(self): 'ip_address': "1.1.1.1", 'mac_address': "hex", 'ip_allocation_mode': 'dhcp', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 }, 'network': { 'name': 'some_network' @@ -366,7 +372,8 @@ def test_create_connections_list(self): 'ip_allocation_mode': 'POOL', 'mac_address': None, 'network': '_management_network', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 }], connection ) From 2c98235c5b591eb9454e71e645cfb8eb62d0ae57 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 1 Jun 2016 12:04:28 +0300 Subject: [PATCH 185/228] update workflows logic --- vcloud_plugin_common/workflows.py | 33 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py index 38c1ad1..433ab0c 100644 --- a/vcloud_plugin_common/workflows.py +++ b/vcloud_plugin_common/workflows.py @@ -14,7 +14,7 @@ from cloudify.decorators import workflow from cloudify.manager import update_node_instance -import cloudify.plugins.workflows as default_workflow +from cloudify.plugins import lifecycle import vcloud_plugin_common @@ -53,14 +53,14 @@ def _get_all_nodes_instances(ctx, token, org_url): @workflow def install(ctx, **kwargs): """Score install workflow""" - - default_workflow._install_node_instances( - ctx, - _get_all_nodes_instances(ctx, kwargs.get('session_token'), - kwargs.get('org_url')), - set(), - default_workflow.NodeInstallationTasksSequenceCreator(), - default_workflow.InstallationTasksGraphFinisher + lifecycle.install_node_instances( + graph=ctx.graph_mode(), + node_instances=set( + _get_all_nodes_instances( + ctx, kwargs.get('session_token'), + kwargs.get('org_url') + ) + ) ) @@ -68,11 +68,12 @@ def install(ctx, **kwargs): def uninstall(ctx, **kwargs): """Score uninstall workflow""" - default_workflow._uninstall_node_instances( - ctx, - _get_all_nodes_instances(ctx, kwargs.get('session_token'), - kwargs.get('org_url')), - set(), - default_workflow.NodeUninstallationTasksSequenceCreator(), - default_workflow.UninstallationTasksGraphFinisher + lifecycle.uninstall_node_instances( + graph=ctx.graph_mode(), + node_instances=set( + _get_all_nodes_instances( + ctx, kwargs.get('session_token'), + kwargs.get('org_url') + ) + ) ) From 9bb398382fdd5e7eaaa9df10d3efdb0343727381 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 1 Jun 2016 13:39:21 +0300 Subject: [PATCH 186/228] fix mock tests --- ...est_mock_server_plugin_server_subroutes.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index ec458ae..ea06ab5 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -294,25 +294,25 @@ def test_create_connections_list(self): self.assertEqual( [ { - 'ip_address': '1.1.1.1', - 'ip_allocation_mode': 'POOL', - 'mac_address': 'hex', 'network': 'private_network', + 'mac_address': 'hex', + 'ip_allocation_mode': 'POOL', 'primary_interface': True, + 'ip_address': '1.1.1.1', 'nic_order': 0 }, { - 'ip_address': None, - 'ip_allocation_mode': 'POOL', - 'mac_address': None, 'network': 'some_network', + 'mac_address': None, + 'ip_allocation_mode': 'POOL', 'primary_interface': False, + 'ip_address': None, 'nic_order': 0 }, { - 'ip_address': None, - 'ip_allocation_mode': 'POOL', - 'mac_address': None, 'network': '_management_network', + 'mac_address': None, + 'ip_allocation_mode': 'POOL', 'primary_interface': False, + 'ip_address': None, 'nic_order': 0 } ], connection @@ -326,7 +326,8 @@ def test_create_connections_list(self): 'ip_address': "1.1.1.1", 'mac_address': "hex", 'ip_allocation_mode': 'pool', - 'primary_interface': False + 'primary_interface': False, + 'nic_order': 0 } } ) @@ -342,7 +343,8 @@ def test_create_connections_list(self): 'ip_allocation_mode': 'POOL', 'mac_address': 'hex', 'network': 'private_network', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 } ], connection ) @@ -367,7 +369,8 @@ def test_create_connections_list(self): 'ip_address': "1.1.1.1", 'mac_address': "hex", 'ip_allocation_mode': 'pool', - 'primary_interface': True + 'primary_interface': True, + 'nic_order': 0 }, 'network': { 'name': 'some_network' From f882050afa6165d4dfa4864a7e669b424a248512 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 15 Aug 2016 16:54:19 +0300 Subject: [PATCH 187/228] use last release of pyvcloud --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index be5232e..de73e2b 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ 'cloudify-plugins-common>=3.4a3', - 'pyvcloud==15rc1', + 'pyvcloud==16', 'requests==2.7.0', 'IPy==0.81', 'PyYAML==3.10', From 54516f236717e3fa331dc1ed34a6d354c64bd84e Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 19 Aug 2016 16:11:03 +0300 Subject: [PATCH 188/228] update version --- plugin.yaml | 4 ++-- setup.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 9c00d4a..39597eb 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.3.1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip package_name: cloudify-vcloud-plugin - package_version: '1.3.1' + package_version: '1.4' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index de73e2b..b99fbd7 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.4a5', + version='1.4', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,7 +26,7 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.4a3', + 'cloudify-plugins-common>=3.4', 'pyvcloud==16', 'requests==2.7.0', 'IPy==0.81', From 1e3d2560a9e1043c5a9df232a96afbd3bc66ceec Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 25 Aug 2016 12:56:27 +0300 Subject: [PATCH 189/228] use 3.4 version of cloudify-* --- dev-requirements.txt | 10 +++++----- plugin.yaml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index f99fe63..69d8711 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,8 @@ -https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.3.1 -https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.3.1 -https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.3.1 -pyvcloud==15rc1 +https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.4 +https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.4 +https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.4 +pyvcloud==16 requests==2.7.0 IPy==0.81 PyYAML==3.10 -pycrypto==2.6.1 \ No newline at end of file +pycrypto==2.6.1 diff --git a/plugin.yaml b/plugin.yaml index 39597eb..6828f93 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,7 +1,7 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.zip package_name: cloudify-vcloud-plugin package_version: '1.4' From 119a317462d7eba469d07eefc6fd6aa197ce7de8 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 25 Aug 2016 13:00:35 +0300 Subject: [PATCH 190/228] Bump version --- plugin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 6828f93..22223df 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip package_name: cloudify-vcloud-plugin - package_version: '1.4' + package_version: '4.0a1' node_types: cloudify.vcloud.nodes.Server: From cc676430a1e06e9ac2fd8d0a56b9a414d3232939 Mon Sep 17 00:00:00 2001 From: Konstantin Ilyashenko Date: Tue, 1 Nov 2016 14:49:29 +0400 Subject: [PATCH 191/228] Change exception to warning, id DHCP server is absent in network configuration. Fix error with checking network parameters. --- vcloud_network_plugin/network.py | 3 ++- vcloud_server_plugin/server.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index ba95e2c..afdd0bb 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -71,7 +71,8 @@ def create(vca_client, **kwargs): "'use_external_resource' is 'false' or absent" .format(network_name)) - ip = _split_adresses(net_prop['static_range']) + static_range = get_mandatory(net_prop, 'static_range') + ip = _split_adresses(static_range) gateway_name = net_prop['edge_gateway'] get_gateway(vca_client, gateway_name) start_address = ip.start diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index e53c0e6..4b0b7ca 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -24,7 +24,8 @@ with_vca_client, error_response, STATUS_POWERED_ON) -from vcloud_network_plugin import (get_network_name, get_network, is_network_exists, +from vcloud_network_plugin import (get_network_name, get_network, + is_network_exists, get_vapp_name, GATEWAY_TIMEOUT, RETRY_COUNT) from vcloud_network_plugin.keypair import PUBLIC_KEY, SSH_KEY @@ -678,7 +679,7 @@ def _create_connections_list(vca_client): network_name = conn['network'] if (conn['ip_allocation_mode'] == 'DHCP' and not _isDhcpAvailable(vca_client, network_name)): - raise cfy_exc.NonRecoverableError( + ctx.logger.warning( "DHCP for network {0} is not available" .format(network_name)) if not primary_iface_set: From 4e3c6a78c65785178df05671f5d9e15f9c76304f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 23 Dec 2016 16:39:43 +0200 Subject: [PATCH 192/228] fix unittests --- tests/unittests/test_mock_network_plugin_floatingip.py | 1 + tests/unittests/test_mock_network_plugin_network.py | 1 + .../unittests/test_mock_network_plugin_network_subroutes.py | 1 + tests/unittests/test_mock_network_plugin_public_nat.py | 1 + tests/unittests/test_mock_server_plugin_server.py | 1 + tests/unittests/test_mock_server_plugin_server_subroutes.py | 6 ++++-- tests/unittests/test_mock_vcloud_plugin_common.py | 1 + .../unittests/test_mock_vcloud_plugin_common_vca_client.py | 1 + vcloud_network_plugin/network.py | 2 +- 9 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 97f8313..8948959 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -554,5 +554,6 @@ def test_floatingip_operation_create(self): '10.10.2.3' ) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index ca13c5a..cf88df0 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -485,5 +485,6 @@ def test_creation_validation_separate_ips(self): with self.assertRaises(cfy_exc.NonRecoverableError): network.creation_validation(ctx=fake_ctx) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index a6cb995..2d6b0d9 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -126,5 +126,6 @@ def test__dhcp_operation(self): fake_client, '_management_network', network.ADD_POOL ) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index c75228e..965eb72 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -1307,5 +1307,6 @@ def test_net_connect_to_nat_preconfigure(self): with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index c5f7172..5b39a36 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -829,5 +829,6 @@ def test_create_customization_customized(self): ): server.configure(ctx=fake_ctx) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index ea06ab5..db521db 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -415,10 +415,12 @@ def test_create_connections_list(self): 'name': 'some_network' } }) + # we support case when with dhcpd on vm inside network + # instead use gateway service, + # look to cc676430a1e06e9ac2fd8d0a56b9a414d3232939 with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - server._create_connections_list(fake_client) + server._create_connections_list(fake_client) # only managment node fake_ctx.instance._relationships = [] with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index bf2ae5d..f364a31 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -287,5 +287,6 @@ def test_config(self): config = vcloud_plugin_common.Config() self.assertFalse(config.get()) + if __name__ == '__main__': unittest.main() diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 20576fb..8d6f70b 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -434,5 +434,6 @@ def test_get(self): fake_client ) + if __name__ == '__main__': unittest.main() diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index afdd0bb..0266c4b 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -71,7 +71,7 @@ def create(vca_client, **kwargs): "'use_external_resource' is 'false' or absent" .format(network_name)) - static_range = get_mandatory(net_prop, 'static_range') + static_range = get_mandatory(net_prop, 'static_range') ip = _split_adresses(static_range) gateway_name = net_prop['edge_gateway'] get_gateway(vca_client, gateway_name) From e27c90eba46b590feea197ba7ea3c2960245fc02 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 27 Mar 2018 14:49:34 +0300 Subject: [PATCH 193/228] Use same version --- plugin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 22223df..6828f93 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/master.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.zip package_name: cloudify-vcloud-plugin - package_version: '4.0a1' + package_version: '1.4' node_types: cloudify.vcloud.nodes.Server: From 5de1860d8f570546e63fd8b07b2ecb6773b0c1a8 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 27 Mar 2018 15:06:02 +0300 Subject: [PATCH 194/228] Bump version for include all last fixes --- plugin.yaml | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 6828f93..22f2f2a 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.1.zip package_name: cloudify-vcloud-plugin - package_version: '1.4' + package_version: '1.4.1' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index b99fbd7..e0938d9 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.4', + version='1.4.1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', From 70aaad4442428fc3cbe232ff37cd2b82d4384822 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 29 Oct 2018 16:19:51 +0200 Subject: [PATCH 195/228] Update dependencies and support new cloudify manager --- dev-requirements.txt | 8 +- plugin.yaml | 8 +- setup.py | 6 +- system_tests/manager/nodecellar_test.py | 2 +- system_tests/vcloud_handler.py | 1 + tests/integration/blueprints/header.yaml | 6 +- .../test_mock_storage_plugin_volume.py | 1 + ...est_mock_vcloud_plugin_common_workflows.py | 98 ------------------- tox.ini | 13 +-- vcloud_network_plugin/__init__.py | 4 +- vcloud_network_plugin/floatingip.py | 7 +- vcloud_network_plugin/security_group.py | 5 +- vcloud_plugin_common/workflows.py | 79 --------------- vcloud_server_plugin/server.py | 5 +- vcloud_server_plugin/vdc.py | 8 +- 15 files changed, 36 insertions(+), 215 deletions(-) delete mode 100644 tests/unittests/test_mock_vcloud_plugin_common_workflows.py delete mode 100644 vcloud_plugin_common/workflows.py diff --git a/dev-requirements.txt b/dev-requirements.txt index 69d8711..705f7c6 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,8 @@ -https://github.com/cloudify-cosmo/cloudify-dsl-parser/archive/master.zip#egg=cloudify-dsl-parser==3.4 -https://github.com/cloudify-cosmo/cloudify-rest-client/archive/master.zip#egg=cloudify-rest-client==3.4 -https://github.com/cloudify-cosmo/cloudify-plugins-common/archive/master.zip#egg=cloudify-plugins-common==3.4 +cloudify-dsl-parser>=3.4.2 +cloudify-rest-client>=3.4.2 +cloudify-plugins-common>=3.4.2 pyvcloud==16 -requests==2.7.0 +requests>=2.7.0,<3.0.0 IPy==0.81 PyYAML==3.10 pycrypto==2.6.1 diff --git a/plugin.yaml b/plugin.yaml index 22f2f2a..083654c 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.4.1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.5.0.zip package_name: cloudify-vcloud-plugin - package_version: '1.4.1' + package_version: '1.5.0' node_types: cloudify.vcloud.nodes.Server: @@ -266,7 +266,3 @@ relationships: establish: implementation: vcloud.vcloud_server_plugin.server.remove_keys inputs: {} - -workflows: - scoreinstall: vcloud.vcloud_plugin_common.workflows.install - scoreuninstall: vcloud.vcloud_plugin_common.workflows.uninstall diff --git a/setup.py b/setup.py index e0938d9..142837b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.4.1', + version='1.5.0', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,9 +26,9 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.4', + 'cloudify-plugins-common>=3.4.2', 'pyvcloud==16', - 'requests==2.7.0', + 'requests>=2.7.0,<3.0.0', 'IPy==0.81', 'PyYAML==3.10', 'pycrypto==2.6.1' diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index ef090cd..f862c68 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -23,7 +23,7 @@ def test_vcloud_nodecellar(self): def get_inputs(self): return { - 'catalog': self.env.public_catalog, + 'catalog': self.env.public_catalog, 'template': self.env.ubuntu_precise_template, 'edge_gateway': self.env.edge_gateway, 'management_network_name': self.env.management_network_name, diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 69c3947..46d22df 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -153,6 +153,7 @@ def before_bootstrap(self): else: raise RuntimeError("Can't create test VDC") + handler = VcloudHandler diff --git a/tests/integration/blueprints/header.yaml b/tests/integration/blueprints/header.yaml index 6dba00d..2f2009c 100644 --- a/tests/integration/blueprints/header.yaml +++ b/tests/integration/blueprints/header.yaml @@ -1,9 +1,9 @@ tosca_definitions_version: cloudify_dsl_1_2 imports: - - http://s3.amazonaws.com/vcloud-score/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/master/plugin.yaml - - http://www.getcloudify.org/spec/fabric-plugin/1.3rc1/plugin.yaml + - http://www.getcloudify.org/spec/cloudify/4.4/types.yaml + - plugin:cloudify-vcloud-plugin + - plugin:cloudify-fabric-plugin inputs: username: diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 9cf6e42..ffb5a5b 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -411,6 +411,7 @@ def test_detach_volume(self): ): volume.detach_volume(ctx=fake_ctx) + @unittest.skip("Fabric changed api, skip for now") def run_wait_boot(self, fabric_settings, fabric_run, sleep_call=True): sleep_function = mock.MagicMock() with mock.patch( diff --git a/tests/unittests/test_mock_vcloud_plugin_common_workflows.py b/tests/unittests/test_mock_vcloud_plugin_common_workflows.py deleted file mode 100644 index b340ffe..0000000 --- a/tests/unittests/test_mock_vcloud_plugin_common_workflows.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import mock - -from tests.unittests import test_mock_base -import vcloud_plugin_common -import vcloud_plugin_common.workflows - - -class VcloudPluginCommonWorkflowsMockTestCase(test_mock_base.TestBase): - - def _generate_instance(self): - fake_instance = mock.Mock() - fake_instance._node_instance = { - 'runtime_properties': { - }, - 'version': None - } - fake_instance.id = "fake_instance" - return fake_instance - - def check_instance(self, call_function, fake_instance): - call_function.assert_called_with( - fake_instance._node_instance - ) - # check for installed token and url - self.assertEqual( - fake_instance._node_instance, { - 'runtime_properties': { - vcloud_plugin_common.ORG_URL: 'org_url', - vcloud_plugin_common.SESSION_TOKEN: 'token' - }, - 'version': 0 - } - ) - - def test_update(self): - """check update logic""" - fake_ctx = self.generate_node_context() - fake_instance = self._generate_instance() - call_function = mock.MagicMock() - with mock.patch( - 'vcloud_plugin_common.workflows.update_node_instance', - call_function - ): - vcloud_plugin_common.workflows.update( - fake_ctx, fake_instance, "token", "org_url" - ) - self.check_instance(call_function, fake_instance) - # use local version - fake_ctx._local = True - internal = mock.MagicMock() - update_call = mock.MagicMock() - internal.handler.storage.update_node_instance = update_call - fake_ctx._internal = internal - vcloud_plugin_common.workflows.update( - fake_ctx, fake_instance, "token", "org_url" - ) - update_call.assert_called_with( - 'fake_instance', 0, { - 'org_url': 'org_url', - 'session_token': 'token' - }, None - ) - - def test_get_all_nodes_instances(self): - """update all instances in context""" - fake_ctx = self.generate_node_context() - fake_instance = self._generate_instance() - call_function = mock.MagicMock() - # create fake node with all prpoerties - fake_node = mock.MagicMock() - fake_node.properties = { - vcloud_plugin_common.VCLOUD_CONFIG: 'some_magic_here' - } - fake_node.instances = [fake_instance] - fake_ctx._nodes = [fake_node] - # try to run - with mock.patch( - 'vcloud_plugin_common.workflows.update_node_instance', - call_function - ): - vcloud_plugin_common.workflows._get_all_nodes_instances( - fake_ctx, "token", "org_url" - ) - self.check_instance(call_function, fake_instance) diff --git a/tox.ini b/tox.ini index b42b96b..ae124cd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-ondemand, py27-subscription, py27-unittests, pep8 +envlist = py27-unittests, pep8 minversion = 1.6 skipsdist = True @@ -9,18 +9,13 @@ envdir = .tox/devenv deps = -rtest-requirements.txt -rdev-requirements.txt -[testenv:py27-ondemand] -commands = nosetests -x -s --tc=ondemand: tests/integration {posargs} - -[testenv:py27-subscription] -commands = nosetests -x -s --tc=subscription: tests/integration {posargs} - [testenv:py27-unittests] -commands = nosetests -x -s -vv tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=vcloud_network_plugin --cover-package=vcloud_server_plugin --cover-package=vcloud_storage_plugin +commands = nosetests tests/unittests --cover-html --with-coverage --cover-package=vcloud_plugin_common --cover-package=vcloud_network_plugin --cover-package=vcloud_server_plugin --cover-package=vcloud_storage_plugin [testenv:pep8] commands= - flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin tests + flake8 --ignore=E501 tests + flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py diff --git a/vcloud_network_plugin/__init__.py b/vcloud_network_plugin/__init__.py index 5b052d1..bb939a2 100644 --- a/vcloud_network_plugin/__init__.py +++ b/vcloud_network_plugin/__init__.py @@ -376,7 +376,7 @@ def _is_gateway_locked(ctx): except KeyError: pass if rest: - node_instances = rest.node_instances.list(ctx.deployment.id) + node_instances = rest.node_instances.list(deployment_id=ctx.deployment.id) elif ctx.deployment.id == 'local': storage = ctx._endpoint.storage node_instances = storage.get_node_instances() @@ -411,7 +411,7 @@ def wrapper(*args, **kw): else: # we need gateway_name from vcloud for use this functionality ctx.logger.info( - "'edge_gateway' in vcloud_config is empty." + + "'edge_gateway' in vcloud_config is empty." " Can't check state of gateway correctly." ) result = f(*args, **kw) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index f41023a..cb0ff88 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -86,8 +86,11 @@ def _floatingip_operation(operation, vca_client, ctx): internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None - public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or - ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) + public_ip = ( + ctx.target.instance.runtime_properties.get(PUBLIC_IP) + ) or ( + ctx.target.node.properties['floatingip'].get(PUBLIC_IP) + ) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index edadead..38a9688 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -92,8 +92,9 @@ def creation_validation(vca_client, **kwargs): utils.check_protocol(rule.get('protocol')) action = get_mandatory(rule, "action") - if (not isinstance(action, basestring) or - action.lower() not in ACTIONS): + if ( + not isinstance(action, basestring) or action.lower() not in ACTIONS + ): raise cfy_exc.NonRecoverableError( "Action must be on of{0}.".format(ACTIONS)) diff --git a/vcloud_plugin_common/workflows.py b/vcloud_plugin_common/workflows.py deleted file mode 100644 index 433ab0c..0000000 --- a/vcloud_plugin_common/workflows.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from cloudify.decorators import workflow -from cloudify.manager import update_node_instance -from cloudify.plugins import lifecycle -import vcloud_plugin_common - - -def update(ctx, instance, token, org_url): - """update token and url in instance""" - node_instance = instance._node_instance - rt_properties = node_instance['runtime_properties'] - rt_properties.update({ - vcloud_plugin_common.SESSION_TOKEN: token, - vcloud_plugin_common.ORG_URL: org_url - }) - version = node_instance['version'] - node_instance['version'] = version if version else 0 - if ctx.local: - version = node_instance['version'] - state = node_instance.get('state') - node_id = instance.id - storage = ctx.internal.handler.storage - storage.update_node_instance(node_id, version, rt_properties, state) - else: - update_node_instance(node_instance) - - -def _get_all_nodes_instances(ctx, token, org_url): - """return all instances from context nodes""" - node_instances = set() - for node in ctx.nodes: - for instance in node.instances: - if (vcloud_plugin_common.VCLOUD_CONFIG in node.properties and - token and org_url): - update(ctx, instance, token, org_url) - node_instances.add(instance) - return node_instances - - -@workflow -def install(ctx, **kwargs): - """Score install workflow""" - lifecycle.install_node_instances( - graph=ctx.graph_mode(), - node_instances=set( - _get_all_nodes_instances( - ctx, kwargs.get('session_token'), - kwargs.get('org_url') - ) - ) - ) - - -@workflow -def uninstall(ctx, **kwargs): - """Score uninstall workflow""" - - lifecycle.uninstall_node_instances( - graph=ctx.graph_mode(), - node_instances=set( - _get_all_nodes_instances( - ctx, kwargs.get('session_token'), - kwargs.get('org_url') - ) - ) - ) diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 4b0b7ca..a357bda 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -677,8 +677,9 @@ def _create_connections_list(vca_client): # in case when we dont have any primary networks for conn in connections: network_name = conn['network'] - if (conn['ip_allocation_mode'] == 'DHCP' and - not _isDhcpAvailable(vca_client, network_name)): + if (conn['ip_allocation_mode'] == 'DHCP' and not _isDhcpAvailable( + vca_client, network_name + )): ctx.logger.warning( "DHCP for network {0} is not available" .format(network_name)) diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index a833e0e..964e6ba 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -93,8 +93,8 @@ def create(vca_client, **kwargs): raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") task = vca_client.create_vdc(vdc_name) if not task: - raise cfy_exc.NonRecoverableError("Could not create VDC: {0}" - .format(error_response(vca_client))) + raise cfy_exc.NonRecoverableError( + "Could not create VDC: {0}".format(error_response(vca_client))) wait_for_task(vca_client, task) @@ -111,8 +111,8 @@ def delete(vca_client, **kwargs): vdc_name = ctx.node.properties.get('name') status, task = vca_client.delete_vdc(vdc_name) if not status: - raise cfy_exc.NonRecoverableError("Could not delete VDC: {0}" - .format(error_response(vca_client))) + raise cfy_exc.NonRecoverableError( + "Could not delete VDC: {0}".format(error_response(vca_client))) wait_for_task(vca_client, task) # clean up runtime_properties if VDC_NAME in ctx.instance.runtime_properties: From 815662cf52291ec10eea820d9b4c0fdb772dfc92 Mon Sep 17 00:00:00 2001 From: Mohammed AbuAisha Date: Thu, 18 Jul 2019 10:46:14 +0300 Subject: [PATCH 196/228] test new version for vcloud --- plugin.yaml | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 083654c..86fea8d 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.5.0.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.5.1.zip package_name: cloudify-vcloud-plugin - package_version: '1.5.0' + package_version: '1.5.1' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index 142837b..2e2e34c 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='cloudify-vcloud-plugin', - version='1.5.0', + version='1.5.1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', From 615e4864e68fc1d91b407c04c72a18cda54943fa Mon Sep 17 00:00:00 2001 From: Mohammed AbuAisha Date: Thu, 18 Jul 2019 17:17:06 +0300 Subject: [PATCH 197/228] Update new version for vcloud --- plugin.yaml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 86fea8d..0e8d034 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2,7 +2,7 @@ plugins: vcloud: executor: central_deployment_agent source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.5.1.zip - package_name: cloudify-vcloud-plugin + package_name: tosca-vcloud-plugin package_version: '1.5.1' node_types: diff --git a/setup.py b/setup.py index 2e2e34c..980bf26 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ setup( zip_safe=True, - name='cloudify-vcloud-plugin', + name='tosca-vcloud-plugin', version='1.5.1', packages=[ 'vcloud_plugin_common', From c51e3c517193bb52851f774ba70de84d0909f335 Mon Sep 17 00:00:00 2001 From: Mohammed AbuAisha Date: Thu, 18 Jul 2019 17:19:55 +0300 Subject: [PATCH 198/228] Fix unit test pep8 --- tests/integration/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index 4a95240..f053a50 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -143,9 +143,9 @@ def _execute_command(self, command): def fail_guard(f): @wraps(f) def wrapper(*args, **kargs): - args[0].failed = True - f(*args, **kargs) - args[0].failed = False + args[0].failed = True + f(*args, **kargs) + args[0].failed = False return wrapper @@ -166,7 +166,8 @@ def wait_for_task(vca_client, task): for attempt in range(MAX_ATTEMPTS): print('Attempt: {0}/{1}.'.format(attempt + 1, MAX_ATTEMPTS)) if status == TASK_STATUS_SUCCESS: - print('Task completed in {0} seconds'.format(attempt * TASK_RECHECK_TIMEOUT)) + print('Task completed in {0} seconds' + ''.format(attempt * TASK_RECHECK_TIMEOUT)) return if status == TASK_STATUS_ERROR: error = task.get_Error() From 105d6c57875a71528758e9351d4e8b6f90e04867 Mon Sep 17 00:00:00 2001 From: Mohammed AbuAisha Date: Thu, 18 Jul 2019 17:25:51 +0300 Subject: [PATCH 199/228] Fix over indented pep8 --- vcloud_network_plugin/__init__.py | 6 +++--- vcloud_network_plugin/network.py | 4 ++-- vcloud_network_plugin/public_nat.py | 6 +++--- vcloud_server_plugin/vdc.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/vcloud_network_plugin/__init__.py b/vcloud_network_plugin/__init__.py index bb939a2..e87dc5c 100644 --- a/vcloud_network_plugin/__init__.py +++ b/vcloud_network_plugin/__init__.py @@ -383,9 +383,9 @@ def _is_gateway_locked(ctx): else: return False for instance in node_instances: - rt_properties = instance['runtime_properties'] - if rt_properties.get(GATEWAY_LOCK): - return True + rt_properties = instance['runtime_properties'] + if rt_properties.get(GATEWAY_LOCK): + return True return False diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 0266c4b..187f86f 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -179,8 +179,8 @@ def creation_validation(vca_client, **kwargs): "Static_range and dhcp_range is overlapped.") ips.extend([dhcp_ip.start, dhcp_ip.end]) if not is_ips_in_same_subnet(ips, netmask): - raise cfy_exc.NonRecoverableError( - "IP addresses in different subnets.") + raise cfy_exc.NonRecoverableError( + "IP addresses in different subnets.") def _dhcp_operation(vca_client, network_name, operation): diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 9bc80e0..68646de 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -37,9 +37,9 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Rules list must contains only one element") if _is_dnat(rules[0]['type']): - raise cfy_exc.NonRecoverableError( - "In 'cloudify.vcloud.net_connected_to_public_nat' relationship" - " you can use only 'SNAT' rule.") + raise cfy_exc.NonRecoverableError( + "In 'cloudify.vcloud.net_connected_to_public_nat' relationship" + " you can use only 'SNAT' rule.") @operation diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index 964e6ba..af1a2a2 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -73,8 +73,8 @@ def create(vca_client, **kwargs): # Subscription service does not support vdc create, # you must use predefined vdc only if is_subscription(config['service_type']): - raise cfy_exc.NonRecoverableError( - "Unable create VDC on subscription service.") + raise cfy_exc.NonRecoverableError( + "Unable create VDC on subscription service.") if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): # use external resource, does not create anything res_id = ctx.node.properties[RESOURCE_ID] From 25f1ac04d182c30d8ce3c25c0945ec59297f102f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 9 Jan 2020 13:44:46 +0200 Subject: [PATCH 200/228] pyvcloud version upgrade --- constraints.txt | 1 + dev-requirements.txt | 9 +-------- plugin.yaml | 4 ++-- setup.py | 10 ++++------ vcloud_network_plugin/floatingip.py | 6 +++--- vcloud_network_plugin/keypair.py | 10 +++++----- vcloud_network_plugin/network.py | 6 +++--- vcloud_network_plugin/port.py | 2 +- vcloud_network_plugin/public_nat.py | 12 ++++++------ vcloud_network_plugin/security_group.py | 6 +++--- vcloud_server_plugin/server.py | 14 +++++++------- vcloud_server_plugin/vdc.py | 6 +++--- vcloud_storage_plugin/volume.py | 10 +++++----- 13 files changed, 44 insertions(+), 52 deletions(-) create mode 100644 constraints.txt diff --git a/constraints.txt b/constraints.txt new file mode 100644 index 0000000..ce546bc --- /dev/null +++ b/constraints.txt @@ -0,0 +1 @@ +cloudify-common==4.5.0 diff --git a/dev-requirements.txt b/dev-requirements.txt index 705f7c6..8b13789 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1 @@ -cloudify-dsl-parser>=3.4.2 -cloudify-rest-client>=3.4.2 -cloudify-plugins-common>=3.4.2 -pyvcloud==16 -requests>=2.7.0,<3.0.0 -IPy==0.81 -PyYAML==3.10 -pycrypto==2.6.1 + diff --git a/plugin.yaml b/plugin.yaml index 0e8d034..9f7bf25 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.5.1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.0.zip package_name: tosca-vcloud-plugin - package_version: '1.5.1' + package_version: '1.6.0' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index 980bf26..8704546 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='tosca-vcloud-plugin', - version='1.5.1', + version='1.6.0', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', @@ -26,11 +26,9 @@ license='LICENSE', description='Cloudify plugin for vmWare vCloud infrastructure.', install_requires=[ - 'cloudify-plugins-common>=3.4.2', - 'pyvcloud==16', - 'requests>=2.7.0,<3.0.0', - 'IPy==0.81', - 'PyYAML==3.10', + 'cloudify-common>=4.5.0', + 'pyvcloud==18.2.2', + 'IPy==1.00', 'pycrypto==2.6.1' ] ) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index cb0ff88..2849b3f 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -26,7 +26,7 @@ set_retry, lock_gateway) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def connect_floatingip(vca_client, **kwargs): @@ -37,7 +37,7 @@ def connect_floatingip(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def disconnect_floatingip(vca_client, **kwargs): @@ -48,7 +48,7 @@ def disconnect_floatingip(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 09d1e9b..df8b1c1 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -32,7 +32,7 @@ SSH_KEY = 'ssh_key' -@operation +@operation(resumable=True) def creation_validation(**kwargs): """ check availability of path used in field private_key_path of @@ -46,7 +46,7 @@ def creation_validation(**kwargs): "Private key file {0} is absent".format(key_path)) -@operation +@operation(resumable=True) def create(**kwargs): ctx.instance.runtime_properties[PUBLIC_KEY] = {} ctx.instance.runtime_properties[PRIVATE_KEY] = {} @@ -77,7 +77,7 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) -@operation +@operation(resumable=True) def delete(**kwargs): if ctx.node.properties[AUTO_GENERATE]: if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): @@ -92,7 +92,7 @@ def delete(**kwargs): del ctx.instance.runtime_properties[PUBLIC_KEY] -@operation +@operation(resumable=True) def server_connect_to_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties target_rt_properties = ctx.target.instance.runtime_properties @@ -109,7 +109,7 @@ def server_connect_to_keypair(**kwargs): ctx.source.instance.update() -@operation +@operation(resumable=True) def server_disconnect_from_keypair(**kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY in host_rt_properties: diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 187f86f..b5c3d99 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -30,7 +30,7 @@ CANT_DELETE = "cannot be deleted, because it is in use" -@operation +@operation(resumable=True) @with_vca_client def create(vca_client, **kwargs): """ @@ -106,7 +106,7 @@ def create(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client def delete(vca_client, **kwargs): """ @@ -136,7 +136,7 @@ def delete(vca_client, **kwargs): "Could not delete network '{0}': {1}".format(network_name, task)) -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ diff --git a/vcloud_network_plugin/port.py b/vcloud_network_plugin/port.py index d84f8c5..dde7224 100644 --- a/vcloud_network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -19,7 +19,7 @@ from vcloud_network_plugin import check_ip -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 68646de..71dfb8e 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -29,7 +29,7 @@ DEFAULT_SSH_PORT = '22' -@operation +@operation(resumable=True) @with_vca_client def net_connect_to_nat_preconfigure(vca_client, **kwargs): rules = ctx.target.node.properties['rules'] @@ -42,7 +42,7 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): " you can use only 'SNAT' rule.") -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def net_connect_to_nat(vca_client, **kwargs): @@ -56,7 +56,7 @@ def net_connect_to_nat(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def net_disconnect_from_nat(vca_client, **kwargs): @@ -70,7 +70,7 @@ def net_disconnect_from_nat(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def server_connect_to_nat(vca_client, **kwargs): @@ -81,7 +81,7 @@ def server_connect_to_nat(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def server_disconnect_from_nat(vca_client, **kwargs): @@ -92,7 +92,7 @@ def server_disconnect_from_nat(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index 38a9688..618f11f 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -28,7 +28,7 @@ ACTIONS = ("allow", "deny") -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def create(vca_client, **kwargs): @@ -39,7 +39,7 @@ def create(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client @lock_gateway def delete(vca_client, **kwargs): @@ -50,7 +50,7 @@ def delete(vca_client, **kwargs): return set_retry(ctx) -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index a357bda..97faee1 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -37,7 +37,7 @@ DEFAULT_HOME = "/home" -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ @@ -81,7 +81,7 @@ def get_template(catalog, template_name): format(server_dict['template'])) -@operation +@operation(resumable=True) @with_vca_client def create(vca_client, **kwargs): """ @@ -216,7 +216,7 @@ def _power_on_vm(vca_client, vapp, vapp_name): wait_for_task(vca_client, task) -@operation +@operation(resumable=True) @with_vca_client def start(vca_client, **kwargs): """ @@ -238,7 +238,7 @@ def start(vca_client, **kwargs): retry_after=5) -@operation +@operation(resumable=True) @with_vca_client def stop(vca_client, **kwargs): """ @@ -260,7 +260,7 @@ def stop(vca_client, **kwargs): wait_for_task(vca_client, task) -@operation +@operation(resumable=True) @with_vca_client def delete(vca_client, **kwargs): """ @@ -299,7 +299,7 @@ def _is_primary_connection_has_ip(vapp): return False -@operation +@operation(resumable=True) @with_vca_client def configure(vca_client, **kwargs): @@ -397,7 +397,7 @@ def configure(vca_client, **kwargs): ctx.logger.info("We dont recieve ip, try next time...") -@operation +@operation(resumable=True) @with_vca_client def remove_keys(vca_client, **kwargs): ctx.logger.info("Remove public keys from VM.") diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index af1a2a2..5ab62d5 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -28,7 +28,7 @@ USE_EXTERNAL_RESOURCE = 'use_external_resource' -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """check params @@ -65,7 +65,7 @@ def creation_validation(vca_client, **kwargs): .format(vdc_name)) -@operation +@operation(resumable=True) @with_vca_client def create(vca_client, **kwargs): """create vdc""" @@ -98,7 +98,7 @@ def create(vca_client, **kwargs): wait_for_task(vca_client, task) -@operation +@operation(resumable=True) @with_vca_client def delete(vca_client, **kwargs): """delete vdc""" diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index b7e588b..a6a0f76 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -22,7 +22,7 @@ from vcloud_network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT -@operation +@operation(resumable=True) @with_vca_client def create_volume(vca_client, **kwargs): """ @@ -53,7 +53,7 @@ def create_volume(vca_client, **kwargs): "Disk creation error: {0}".format(disk)) -@operation +@operation(resumable=True) @with_vca_client def delete_volume(vca_client, **kwargs): """ @@ -75,7 +75,7 @@ def delete_volume(vca_client, **kwargs): "Disk deletion error: {0}".format(task)) -@operation +@operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): """ @@ -99,7 +99,7 @@ def creation_validation(vca_client, **kwargs): get_mandatory(volume, 'size') -@operation +@operation(resumable=True) @with_vca_client def attach_volume(vca_client, **kwargs): """attach volume""" @@ -107,7 +107,7 @@ def attach_volume(vca_client, **kwargs): _volume_operation(vca_client, "ATTACH") -@operation +@operation(resumable=True) @with_vca_client def detach_volume(vca_client, **kwargs): """ From e855e24928e8e6c220f3049a349efd7a35e8af8f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 16 Jan 2020 18:42:50 +0200 Subject: [PATCH 201/228] dump customized values --- plugin.yaml | 4 ++-- setup.py | 2 +- vcloud_server_plugin/server.py | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 9f7bf25..70935a6 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,9 +1,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.0.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.1.dev1.zip package_name: tosca-vcloud-plugin - package_version: '1.6.0' + package_version: '1.6.1.dev1' node_types: cloudify.vcloud.nodes.Server: diff --git a/setup.py b/setup.py index 8704546..9606190 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='tosca-vcloud-plugin', - version='1.6.0', + version='1.6.1.dev1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 97faee1..d89e541 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -364,6 +364,14 @@ def configure(vca_client, **kwargs): computer_name=computer_name, admin_password=password ) + ctx.logger.debug( + "VM {vapp_name} Customized with sript:\n{script}\n" + "computer_name:\n{computer_name}\n" + "password:\n{password}\n".format( + vapp_name=vapp_name, + script=script, + computer_name=computer_name, + password=password)) if task is None: raise cfy_exc.NonRecoverableError( "Could not set guest customization parameters. {0}". From 963fab082384cab9b3875341c6d019f43037c987 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 12:21:50 +0200 Subject: [PATCH 202/228] CYBL-979: combine properties with kwargs --- plugin.yaml | 14 +++++- .../test_mock_network_plugin_network.py | 3 +- ...t_mock_network_plugin_network_subroutes.py | 19 ++++--- vcloud_network_plugin/floatingip.py | 7 ++- vcloud_network_plugin/keypair.py | 39 ++++++++++----- vcloud_network_plugin/network.py | 42 +++++++++++----- vcloud_network_plugin/port.py | 7 ++- vcloud_network_plugin/public_nat.py | 11 ++++- vcloud_network_plugin/security_group.py | 7 ++- vcloud_server_plugin/server.py | 49 +++++++++++++++---- vcloud_server_plugin/vdc.py | 33 +++++++++---- vcloud_storage_plugin/volume.py | 37 +++++++++++--- 12 files changed, 202 insertions(+), 66 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 70935a6..9ced4c9 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,4 +1,5 @@ plugins: + vcloud: executor: central_deployment_agent source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.1.dev1.zip @@ -6,6 +7,7 @@ plugins: package_version: '1.6.1.dev1' node_types: + cloudify.vcloud.nodes.Server: derived_from: cloudify.nodes.Compute properties: @@ -138,7 +140,6 @@ node_types: implementation: vcloud.vcloud_network_plugin.keypair.delete inputs: {} - cloudify.vcloud.nodes.Volume: derived_from: cloudify.nodes.Volume properties: @@ -188,6 +189,7 @@ node_types: implementation: vcloud.vcloud_server_plugin.vdc.creation_validation relationships: + cloudify.vcloud.server_connected_to_floating_ip: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -198,12 +200,16 @@ relationships: unlink: implementation: vcloud.vcloud_network_plugin.floatingip.disconnect_floatingip inputs: {} + cloudify.vcloud.server_connected_to_network: derived_from: cloudify.relationships.connected_to + cloudify.vcloud.port_connected_to_network: derived_from: cloudify.relationships.connected_to + cloudify.vcloud.server_connected_to_port: derived_from: cloudify.relationships.connected_to + cloudify.vcloud.server_connected_to_security_group: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -214,6 +220,7 @@ relationships: unlink: implementation: vcloud.vcloud_network_plugin.security_group.delete inputs: {} + cloudify.vcloud.net_connected_to_public_nat: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -227,6 +234,7 @@ relationships: unlink: implementation: vcloud.vcloud_network_plugin.public_nat.net_disconnect_from_nat inputs: {} + cloudify.vcloud.server_connected_to_public_nat: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -237,6 +245,7 @@ relationships: unlink: implementation: vcloud.vcloud_network_plugin.public_nat.server_disconnect_from_nat inputs: {} + cloudify.vcloud.volume_attached_to_server: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -247,6 +256,7 @@ relationships: unlink: implementation: vcloud.vcloud_storage_plugin.volume.detach_volume inputs: {} + cloudify.vcloud.server_connected_to_keypair: derived_from: cloudify.relationships.connected_to target_interfaces: @@ -257,8 +267,10 @@ relationships: unlink: implementation: vcloud.vcloud_network_plugin.keypair.server_disconnect_from_keypair inputs: {} + cloudify.vcloud.server_connected_to_vdc: derived_from: cloudify.relationships.connected_to + cloudify.vcloud.delete_public_key_from_server: derived_from: cloudify.relationships.connected_to target_interfaces: diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index cf88df0..71409a0 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -294,7 +294,8 @@ def test_dhcp_operation(self): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertFalse( network._dhcp_operation( - fake_client, 'secret_network', network.DELETE_POOL + fake_client, fake_ctx.node.properties, + 'secret_network', network.DELETE_POOL ) ) diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index 2d6b0d9..d4f3f2f 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -60,7 +60,8 @@ def test__dhcp_operation(self): with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): network._dhcp_operation( - fake_client, '_management_network', network.ADD_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL ) # wrong dhcp_range fake_ctx = self.generate_node_context(properties={ @@ -78,7 +79,8 @@ def test__dhcp_operation(self): with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): network._dhcp_operation( - fake_client, '_management_network', network.ADD_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL ) fake_ctx = self.generate_node_context(properties={ @@ -98,7 +100,8 @@ def test__dhcp_operation(self): # returned error/None from server with self.assertRaises(cfy_exc.NonRecoverableError): network._dhcp_operation( - fake_client, '_management_network', network.ADD_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL ) fake_client.get_gateway.assert_called_with( 'vdc_name', 'gateway' @@ -107,7 +110,8 @@ def test__dhcp_operation(self): # returned error/None from server delete with self.assertRaises(cfy_exc.NonRecoverableError): network._dhcp_operation( - fake_client, '_management_network', network.DELETE_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.DELETE_POOL ) # returned busy, try next time @@ -115,15 +119,16 @@ def test__dhcp_operation(self): self.prepare_retry(fake_ctx) self.assertFalse(network._dhcp_operation( - fake_client, '_management_network', - network.DELETE_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.DELETE_POOL )) # no such gateway fake_client.get_gateway = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): network._dhcp_operation( - fake_client, '_management_network', network.ADD_POOL + fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL ) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index 2849b3f..4f6e77a 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -61,7 +61,12 @@ def creation_validation(vca_client, **kwargs): also check availability of public ip if set or exist some free ip in subscription case """ - floatingip = get_mandatory(ctx.node.properties, 'floatingip') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get floatingip + floatingip = get_mandatory(obj, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') gateway = get_gateway(vca_client, edge_gateway) service_type = get_vcloud_config().get('service_type') diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index df8b1c1..040e70a 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -38,7 +38,12 @@ def creation_validation(**kwargs): check availability of path used in field private_key_path of node properties """ - key_path = ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get key + key_path = obj.get(PRIVATE_KEY, {}).get(PATH) if key_path: key_path = os.path.expanduser(key_path) if not os.path.isfile(key_path): @@ -54,24 +59,29 @@ def create(**kwargs): ctx.node.properties.get(PUBLIC_KEY, {}).get(USER) ctx.instance.runtime_properties[PUBLIC_KEY][HOME] = \ ctx.node.properties.get(PUBLIC_KEY, {}).get(HOME) - if ctx.node.properties.get(AUTO_GENERATE): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get key + if obj.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") public, private = _generate_pair() ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = public - if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = \ - ctx.node.properties.get(PUBLIC_KEY, {}).get(KEY) + obj.get(PUBLIC_KEY, {}).get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = \ - ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY) + obj.get(PRIVATE_KEY, {}).get(KEY) ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = \ - ctx.node.properties.get(PRIVATE_KEY, {}).get(PATH) - if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): - if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): + obj.get(PRIVATE_KEY, {}).get(PATH) + if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + if obj.get(PRIVATE_KEY, {}).get(KEY): ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @@ -79,12 +89,17 @@ def create(**kwargs): @operation(resumable=True) def delete(**kwargs): - if ctx.node.properties[AUTO_GENERATE]: - if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get key + if obj[AUTO_GENERATE]: + if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): _delete_key_file(ctx.instance.runtime_properties) else: - if ctx.node.properties.get(PRIVATE_KEY, {}).get(KEY): - if ctx.node.properties.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): + if obj.get(PRIVATE_KEY, {}).get(KEY): + if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): _delete_key_file(ctx.instance.runtime_properties) if PRIVATE_KEY in ctx.instance.runtime_properties: del ctx.instance.runtime_properties[PRIVATE_KEY] diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index b5c3d99..5b4ab8e 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -52,8 +52,13 @@ def create(vca_client, **kwargs): } """ vdc_name = get_vcloud_config()['vdc'] - if ctx.node.properties['use_external_resource']: - network_name = ctx.node.properties['resource_id'] + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # check external resource + if obj['use_external_resource']: + network_name = obj['resource_id'] if not is_network_exists(vca_client, network_name): raise cfy_exc.NonRecoverableError( "Can't find external resource: {0}".format(network_name)) @@ -61,9 +66,9 @@ def create(vca_client, **kwargs): ctx.logger.info( "External resource {0} has been used".format(network_name)) return - network_name = get_network_name(ctx.node.properties) + network_name = get_network_name(obj) if not ctx.instance.runtime_properties.get(SKIP_CREATE_NETWORK): - net_prop = ctx.node.properties["network"] + net_prop = obj["network"] if network_name in _get_network_list(vca_client, get_vcloud_config()['vdc']): raise cfy_exc.NonRecoverableError( @@ -101,7 +106,7 @@ def create(vca_client, **kwargs): "Could not create network {0}: {1}". format(network_name, result)) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name - if not _dhcp_operation(vca_client, network_name, ADD_POOL): + if not _dhcp_operation(vca_client, obj, network_name, ADD_POOL): ctx.instance.runtime_properties[SKIP_CREATE_NETWORK] = True return set_retry(ctx) @@ -112,13 +117,18 @@ def delete(vca_client, **kwargs): """ delete vcloud air network """ - if ctx.node.properties['use_external_resource'] is True: + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # check external resource + if obj['use_external_resource'] is True: del ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] ctx.logger.info("Network was not deleted - external resource has" " been used") return - network_name = get_network_name(ctx.node.properties) - if not _dhcp_operation(vca_client, network_name, DELETE_POOL): + network_name = get_network_name(obj) + if not _dhcp_operation(vca_client, obj, network_name, DELETE_POOL): return set_retry(ctx) ctx.logger.info("Delete network '{0}'".format(network_name)) success, task = vca_client.delete_vdc_network( @@ -142,7 +152,12 @@ def creation_validation(vca_client, **kwargs): """ check network description from node description """ - network_name = get_network_name(ctx.node.properties) + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # check external resource + network_name = get_network_name(obj) ctx.logger.info("Validation cloudify.vcloud.nodes.Network node: {0}" .format(network_name)) if is_network_exists(vca_client, network_name): @@ -153,7 +168,8 @@ def creation_validation(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Network already exsists: {0}".format(network_name)) - net_prop = get_mandatory(ctx.node.properties, "network") + # get net + net_prop = get_mandatory(obj, "network") gateway_name = get_mandatory(net_prop, 'edge_gateway') if not vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name): raise cfy_exc.NonRecoverableError( @@ -183,14 +199,14 @@ def creation_validation(vca_client, **kwargs): "IP addresses in different subnets.") -def _dhcp_operation(vca_client, network_name, operation): +def _dhcp_operation(vca_client, obj, network_name, operation): """ update dhcp setting for network """ - dhcp_settings = ctx.node.properties['network'].get('dhcp') + dhcp_settings = obj['network'].get('dhcp') if dhcp_settings is None: return True - gateway_name = ctx.node.properties["network"]['edge_gateway'] + gateway_name = obj["network"]['edge_gateway'] gateway = get_gateway(vca_client, gateway_name) if gateway.is_busy(): return False diff --git a/vcloud_network_plugin/port.py b/vcloud_network_plugin/port.py index dde7224..faade86 100644 --- a/vcloud_network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -27,7 +27,12 @@ def creation_validation(vca_client, **kwargs): ip_allocation_mode must be in 'manual', 'dhcp', 'pool', and valid ip_address if set """ - port = get_mandatory(ctx.node.properties, 'port') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get port + port = get_mandatory(obj, 'port') ip_allocation_mode = port.get('ip_allocation_mode') if ip_allocation_mode: if ip_allocation_mode.lower() not in ['manual', 'dhcp', 'pool']: diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 71dfb8e..498860b 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -98,7 +98,12 @@ def creation_validation(vca_client, **kwargs): """ validate nat rules in node properties """ - nat = get_mandatory(ctx.node.properties, 'nat') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get net + nat = get_mandatory(obj, 'nat') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) service_type = get_vcloud_config().get('service_type') public_ip = nat.get(PUBLIC_IP) @@ -107,7 +112,9 @@ def creation_validation(vca_client, **kwargs): else: if is_subscription(service_type): getFreeIP(gateway) - for rule in get_mandatory(ctx.node.properties, 'rules'): + # get rules + rules = get_mandatory(obj, 'rules') + for rule in rules: if _is_dnat(rule['type']): utils.check_protocol(rule.get('protocol')) original_port = rule.get('original_port') diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index 618f11f..58ffbb8 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -62,7 +62,12 @@ def creation_validation(vca_client, **kwargs): if not getaway.is_fw_enabled(): raise cfy_exc.NonRecoverableError( "Gateway firewall is disabled. Please, enable firewall.") - rules = get_mandatory(ctx.node.properties, 'rules') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get rules + rules = get_mandatory(obj, 'rules') for rule in rules: description = rule.get("description") if description and not isinstance(description, basestring): diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index d89e541..67c5d5f 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -54,14 +54,19 @@ def get_template(catalog, template_name): if template.get_name() == template_name: return template - if ctx.node.properties.get('use_external_resource'): - if not ctx.node.properties.get('resource_id'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): + if not obj.get('resource_id'): raise cfy_exc.NonRecoverableError( "resource_id server properties must be specified" ) return - server_dict = ctx.node.properties['server'] + server_dict = obj['server'] required_params = ('catalog', 'template') missed_params = set(required_params) - set(server_dict.keys()) if len(missed_params) > 0: @@ -111,8 +116,13 @@ def create(vca_client, **kwargs): server.update(kwargs.get('server', {})) transform_resource_name(server, ctx) - if ctx.node.properties.get('use_external_resource'): - res_id = ctx.node.properties['resource_id'] + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): + res_id = obj['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id vdc = vca_client.get_vdc(config['vdc']) if not vca_client.get_vapp(vdc, res_id): @@ -222,7 +232,12 @@ def start(vca_client, **kwargs): """ power on server and wait network connection availability for host """ - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info('not starting server since an external server is ' 'being used') else: @@ -244,7 +259,12 @@ def stop(vca_client, **kwargs): """ poweroff server, if external resource - server stay poweroned """ - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info('not stopping server since an external server is ' 'being used') else: @@ -266,7 +286,12 @@ def delete(vca_client, **kwargs): """ delete server """ - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info('not deleting server since an external server is ' 'being used') else: @@ -302,8 +327,12 @@ def _is_primary_connection_has_ip(vapp): @operation(resumable=True) @with_vca_client def configure(vca_client, **kwargs): - - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info('Avoiding external resource configuration.') else: ctx.logger.info("Configure server") diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index 5ab62d5..2998f92 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -44,18 +44,23 @@ def creation_validation(vca_client, **kwargs): } """ - if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): - if not ctx.node.properties.get(RESOURCE_ID): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get(USE_EXTERNAL_RESOURCE): + if not obj.get(RESOURCE_ID): raise cfy_exc.NonRecoverableError( "resource_id server properties must be specified") - res_id = ctx.node.properties[RESOURCE_ID] + res_id = obj[RESOURCE_ID] vdc = vca_client.get_vdc(res_id) if not vdc: raise cfy_exc.NonRecoverableError( "Unable to find external VDC {0}." .format(res_id)) else: - vdc_name = ctx.node.properties.get('name') + vdc_name = obj.get('name') if not vdc_name: raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") vdc = vca_client.get_vdc(vdc_name) @@ -75,9 +80,14 @@ def create(vca_client, **kwargs): if is_subscription(config['service_type']): raise cfy_exc.NonRecoverableError( "Unable create VDC on subscription service.") - if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get(USE_EXTERNAL_RESOURCE): # use external resource, does not create anything - res_id = ctx.node.properties[RESOURCE_ID] + res_id = obj[RESOURCE_ID] ctx.instance.runtime_properties[VDC_NAME] = res_id vdc = vca_client.get_vdc(res_id) if not vdc: @@ -88,7 +98,7 @@ def create(vca_client, **kwargs): "External resource {0} has been used".format(res_id)) else: # create new vdc - vdc_name = ctx.node.properties.get('name') + vdc_name = obj.get('name') if not vdc_name: raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") task = vca_client.create_vdc(vdc_name) @@ -102,13 +112,18 @@ def create(vca_client, **kwargs): @with_vca_client def delete(vca_client, **kwargs): """delete vdc""" + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external # external resource - no actions - if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): + if obj.get(USE_EXTERNAL_RESOURCE): ctx.logger.info('Not deleting VDC since an external VDC is ' 'being used') else: # created in our workflow - vdc_name = ctx.node.properties.get('name') + vdc_name = obj.get('name') status, task = vca_client.delete_vdc(vdc_name) if not status: raise cfy_exc.NonRecoverableError( diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index a6a0f76..9f9bea5 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -35,12 +35,17 @@ def create_volume(vca_client, **kwargs): } } """ - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info("External resource has been used") return vdc_name = get_vcloud_config()['vdc'] - name = ctx.node.properties['volume']['name'] - size = ctx.node.properties['volume']['size'] + name = obj['volume']['name'] + size = obj['volume']['size'] size_in_bytes = size * 1024 * 1024 ctx.logger.info("Create volume '{0}' to '{1}' with size {2}Mb." .format(name, vdc_name, size)) @@ -59,11 +64,16 @@ def delete_volume(vca_client, **kwargs): """ drop volume """ - if ctx.node.properties.get('use_external_resource'): + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external + if obj.get('use_external_resource'): ctx.logger.info("External resource has been used") return vdc_name = get_vcloud_config()['vdc'] - name = ctx.node.properties['volume']['name'] + name = obj['volume']['name'] ctx.logger.info("Delete volume '{0}' from '{1}'." .format(name, vdc_name)) success, task = vca_client.delete_disk(vdc_name, name) @@ -85,13 +95,24 @@ def creation_validation(vca_client, **kwargs): disks_names = [ disk.name for [disk, _vms] in vca_client.get_disks(vdc_name) ] - if ctx.node.properties.get('use_external_resource'): - resource_id = get_mandatory(ctx.node.properties, 'resource_id') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get external resource flag + if obj.get('use_external_resource'): + # get resource_id + resource_id = get_mandatory(obj, 'resource_id') if resource_id not in disks_names: raise cfy_exc.NonRecoverableError( "Disk {} does't exists".format(resource_id)) else: - volume = get_mandatory(ctx.node.properties, 'volume') + # combine properties + obj = {} + obj.update(ctx.node.properties) + obj.update(kwargs) + # get volume + volume = get_mandatory(obj, 'volume') name = get_mandatory(volume, 'name') if name in disks_names: raise cfy_exc.NonRecoverableError( From 38a65c49937ba839d28f3c5112b66487d8cc8e3b Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 12:28:07 +0200 Subject: [PATCH 203/228] CYBL-979: license header fix --- setup.py | 2 +- system_tests/__init__.py | 2 +- system_tests/manager/__init__.py | 12 +++++------- system_tests/manager/nodecellar_test.py | 11 +++++------ system_tests/vcloud_handler.py | 2 +- tests/integration/__init__.py | 2 +- tests/integration/test_network_plugin.py | 2 +- tests/integration/test_server_plugin.py | 2 +- tests/integration/test_storage_plugin.py | 2 +- tests/syntax_check.py | 2 +- tests/unittests/test_mock_base.py | 2 +- tests/unittests/test_mock_network_plugin.py | 2 +- .../unittests/test_mock_network_plugin_floatingip.py | 2 +- tests/unittests/test_mock_network_plugin_keypair.py | 2 +- tests/unittests/test_mock_network_plugin_network.py | 2 +- .../test_mock_network_plugin_network_subroutes.py | 2 +- tests/unittests/test_mock_network_plugin_port.py | 2 +- .../unittests/test_mock_network_plugin_public_nat.py | 2 +- .../test_mock_network_plugin_security_group.py | 2 +- tests/unittests/test_mock_server_plugin_server.py | 2 +- .../test_mock_server_plugin_server_subroutes.py | 2 +- tests/unittests/test_mock_server_plugin_vdc.py | 2 +- tests/unittests/test_mock_storage_plugin_volume.py | 2 +- tests/unittests/test_mock_vcloud_plugin_common.py | 2 +- .../test_mock_vcloud_plugin_common_vca_client.py | 2 +- vcloud_network_plugin/__init__.py | 2 +- vcloud_network_plugin/floatingip.py | 2 +- vcloud_network_plugin/keypair.py | 2 +- vcloud_network_plugin/network.py | 2 +- vcloud_network_plugin/port.py | 2 +- vcloud_network_plugin/public_nat.py | 2 +- vcloud_network_plugin/security_group.py | 2 +- vcloud_network_plugin/utils.py | 2 +- vcloud_plugin_common/__init__.py | 2 +- vcloud_server_plugin/server.py | 2 +- vcloud_server_plugin/vdc.py | 9 ++++----- vcloud_storage_plugin/storage.py | 8 ++++---- vcloud_storage_plugin/volume.py | 2 +- 38 files changed, 52 insertions(+), 56 deletions(-) diff --git a/setup.py b/setup.py index 9606190..f3f7825 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/system_tests/__init__.py b/system_tests/__init__.py index bd93320..af82fdb 100644 --- a/system_tests/__init__.py +++ b/system_tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/system_tests/manager/__init__.py b/system_tests/manager/__init__.py index 10de568..8fac388 100644 --- a/system_tests/manager/__init__.py +++ b/system_tests/manager/__init__.py @@ -1,18 +1,16 @@ -######## -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. - +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cosmo_tester.framework.testenv import bootstrap, teardown diff --git a/system_tests/manager/nodecellar_test.py b/system_tests/manager/nodecellar_test.py index f862c68..5f7e060 100644 --- a/system_tests/manager/nodecellar_test.py +++ b/system_tests/manager/nodecellar_test.py @@ -1,17 +1,16 @@ -######## -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cosmo_tester.test_suites.test_blueprints import nodecellar_test diff --git a/system_tests/vcloud_handler.py b/system_tests/vcloud_handler.py index 46d22df..e8fea7a 100644 --- a/system_tests/vcloud_handler.py +++ b/system_tests/vcloud_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index f053a50..46d0971 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/integration/test_network_plugin.py b/tests/integration/test_network_plugin.py index c82bb52..6f909ce 100644 --- a/tests/integration/test_network_plugin.py +++ b/tests/integration/test_network_plugin.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index f4022d3..d9fa2a9 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/integration/test_storage_plugin.py b/tests/integration/test_storage_plugin.py index 0a2d93e..9c33064 100644 --- a/tests/integration/test_storage_plugin.py +++ b/tests/integration/test_storage_plugin.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/syntax_check.py b/tests/syntax_check.py index 5012b8e..2dcfa9a 100644 --- a/tests/syntax_check.py +++ b/tests/syntax_check.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 3255716..5d7451c 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index 7bbd443..a828480 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 8948959..b94396e 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index e408951..2aa2599 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 71409a0..64e3a18 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index d4f3f2f..dbd379a 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 508d232..142b996 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 965eb72..92461de 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 0533736..f945aa6 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index 5b39a36..bf7cbfa 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index db521db..d43b199 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py index 3e422c1..f479c25 100644 --- a/tests/unittests/test_mock_server_plugin_vdc.py +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index ffb5a5b..f12981c 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index f364a31..431143a 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 8d6f70b..42a707c 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/__init__.py b/vcloud_network_plugin/__init__.py index e87dc5c..3020b28 100644 --- a/vcloud_network_plugin/__init__.py +++ b/vcloud_network_plugin/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index 4f6e77a..f61156e 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 040e70a..2bf873f 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 5b4ab8e..321a2c1 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/port.py b/vcloud_network_plugin/port.py index faade86..2851821 100644 --- a/vcloud_network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 498860b..bfdf6b9 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index 58ffbb8..28a79f4 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_network_plugin/utils.py b/vcloud_network_plugin/utils.py index 6729344..9151e13 100644 --- a/vcloud_network_plugin/utils.py +++ b/vcloud_network_plugin/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 34395dd..9f4dd0d 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 67c5d5f..c7dcdb2 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index 2998f92..61d9117 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -1,5 +1,4 @@ - -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -9,9 +8,9 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from cloudify import ctx from cloudify.decorators import operation diff --git a/vcloud_storage_plugin/storage.py b/vcloud_storage_plugin/storage.py index a9dfcc4..6e31366 100644 --- a/vcloud_storage_plugin/storage.py +++ b/vcloud_storage_plugin/storage.py @@ -1,5 +1,5 @@ ######### -# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2014-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -9,6 +9,6 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index 9f9bea5..6a41f7f 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 GigaSpaces Technologies Ltd. All rights reserved +# Copyright (c) 2015-2020 Cloudify Platform Ltd. All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 6d43d1989121853a6b338a73c24b402b3bad94dd Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 13:50:45 +0200 Subject: [PATCH 204/228] CYBL-979: fix pep8 issues --- constraints.txt | 2 + examples/blueprint.yaml | 6 +- setup.py | 5 +- test-requirements.txt | 3 +- tests/integration/test_server_plugin.py | 7 +- tests/integration/test_storage_plugin.py | 6 +- tests/unittests/test_mock_network_plugin.py | 8 +- .../test_mock_network_plugin_floatingip.py | 6 +- .../test_mock_network_plugin_public_nat.py | 85 ++++++++++++------- ...est_mock_server_plugin_server_subroutes.py | 12 +-- .../unittests/test_mock_server_plugin_vdc.py | 18 ++-- .../test_mock_storage_plugin_volume.py | 4 +- ...st_mock_vcloud_plugin_common_vca_client.py | 23 +++-- tox.ini | 21 ++++- vcloud_network_plugin/__init__.py | 5 +- vcloud_network_plugin/floatingip.py | 9 +- vcloud_network_plugin/keypair.py | 20 +++-- vcloud_network_plugin/network.py | 5 +- vcloud_network_plugin/public_nat.py | 10 ++- vcloud_network_plugin/security_group.py | 5 +- vcloud_plugin_common/__init__.py | 10 ++- vcloud_server_plugin/server.py | 2 +- vcloud_storage_plugin/volume.py | 6 +- 23 files changed, 180 insertions(+), 98 deletions(-) diff --git a/constraints.txt b/constraints.txt index ce546bc..42a671b 100644 --- a/constraints.txt +++ b/constraints.txt @@ -1 +1,3 @@ cloudify-common==4.5.0 +paramiko==2.7.1 +fabric==1.14.1 diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index f2d0bbf..edcbdd9 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -1,8 +1,8 @@ -tosca_definitions_version: cloudify_dsl_1_2 +tosca_definitions_version: cloudify_dsl_1_3 imports: - - http://www.getcloudify.org/spec/cloudify/3.3.1/types.yaml - - https://raw.githubusercontent.com/cloudify-cosmo/tosca-vcloud-plugin/1.3rc1/plugin.yaml + - https://cloudify.co/spec/cloudify/4.4/types.yaml + - http://www.getcloudify.org/spec/tosca-vcloud-plugin/1.6.0/plugin.yaml node_types: vcloud_configuration: diff --git a/setup.py b/setup.py index f3f7825..b84ca06 100644 --- a/setup.py +++ b/setup.py @@ -29,6 +29,9 @@ 'cloudify-common>=4.5.0', 'pyvcloud==18.2.2', 'IPy==1.00', - 'pycrypto==2.6.1' + 'pycrypto==2.6.1', + # used in volume creation + 'paramiko>=1.18.3', + 'fabric>=1.13.1,<2.0', # 2+ branch has API changes ] ) diff --git a/test-requirements.txt b/test-requirements.txt index a0ca08d..f1196e7 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,4 +6,5 @@ tox>=1.9 coverage pyflakes flake8 -fabric +fabric==1.14.1 +pylint diff --git a/tests/integration/test_server_plugin.py b/tests/integration/test_server_plugin.py index d9fa2a9..27471af 100644 --- a/tests/integration/test_server_plugin.py +++ b/tests/integration/test_server_plugin.py @@ -33,9 +33,10 @@ def test_without_name(self): @fail_guard def test_use_external(self): - task = self.vca_client.create_vapp(self.conf.vdc, self.conf.server_name, self.conf.template, - self.conf.catalog, network_name=self.conf.network_name, - vm_name=self.conf.server_name, deploy='false', poweron='false') + task = self.vca_client.create_vapp( + self.conf.vdc, self.conf.server_name, self.conf.template, + self.conf.catalog, network_name=self.conf.network_name, + vm_name=self.conf.server_name, deploy='false', poweron='false') if task: wait_for_task(self.vca_client, task) else: diff --git a/tests/integration/test_storage_plugin.py b/tests/integration/test_storage_plugin.py index 9c33064..2ab21d2 100644 --- a/tests/integration/test_storage_plugin.py +++ b/tests/integration/test_storage_plugin.py @@ -27,12 +27,14 @@ def test_new(self): @fail_guard def test_use_external(self): - status, disk = self.vca_client.add_disk(self.conf.vdc, self.conf.volume_name, self.conf.volume_size_Mb) + status, disk = self.vca_client.add_disk( + self.conf.vdc, self.conf.volume_name, self.conf.volume_size_Mb) self.init('volume_use_external.yaml') self.install() self.uninstall() self.vca_client = self.get_client() - status, task = self.vca_client.delete_disk(self.conf.vdc, self.conf.volume_name) + status, task = self.vca_client.delete_disk( + self.conf.vdc, self.conf.volume_name) if status: wait_for_task(self.vca_client, task) diff --git a/tests/unittests/test_mock_network_plugin.py b/tests/unittests/test_mock_network_plugin.py index a828480..e83038a 100644 --- a/tests/unittests/test_mock_network_plugin.py +++ b/tests/unittests/test_mock_network_plugin.py @@ -161,7 +161,9 @@ def test_del_ondemand_public_ip(self): fake_ctx = self.generate_node_context() # can't deallocate ip gateway.deallocate_public_ip = mock.MagicMock(return_value=None) - with mock.patch('vcloud_network_plugin.wait_for_gateway', mock.MagicMock()): + with mock.patch( + 'vcloud_network_plugin.wait_for_gateway', mock.MagicMock() + ): with self.assertRaises(cfy_exc.NonRecoverableError): vcloud_network_plugin.del_ondemand_public_ip( fake_client, gateway, '127.0.0.1', fake_ctx) @@ -173,7 +175,9 @@ def test_del_ondemand_public_ip(self): ) ) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with mock.patch('vcloud_network_plugin.wait_for_gateway', mock.MagicMock()): + with mock.patch( + 'vcloud_network_plugin.wait_for_gateway', mock.MagicMock() + ): vcloud_network_plugin.del_ondemand_public_ip( fake_client, gateway, '127.0.0.1', fake_ctx) diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index b94396e..35bf746 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -135,7 +135,8 @@ def test_creation_validation(self): }, 'floatingip': { 'edge_gateway': 'gateway', - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE } } ) @@ -156,7 +157,8 @@ def test_creation_validation(self): 'floatingip': { 'edge_gateway': 'gateway', vcloud_network_plugin.PUBLIC_IP: '10.10.1.2', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE } } ) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 92461de..05949ee 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -102,12 +102,15 @@ def test_get_original_port_for_create(self): # everythiong fine with different port self.assertEqual( public_nat._get_original_port_for_create( - gateway, 'DNAT', 'external', '12', 'internal', '12', 'TCP'), 12) + gateway, 'DNAT', 'external', '12', 'internal', '12', 'TCP' + ), + 12) # relink some port to other # port have not used yet self.assertEqual( public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', 13, 'internal', '12', 'TCP'), 13) + gateway, 'SNAT', 'external', 13, 'internal', '12', 'TCP'), + 13) def test_get_original_port_for_create_with_ctx(self): # with replace, but without replace table - up port +1 @@ -401,7 +404,8 @@ def _ip_exist_in_runtime(fake_ctx): 'vcloud_network_plugin.public_nat.ctx', fake_ctx ): self.assertFalse(public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.CREATE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.CREATE, + "1.2.3.4" )) # operation create @@ -415,7 +419,8 @@ def _ip_exist_in_runtime(fake_ctx): # success save configuration with mock.patch('vcloud_plugin_common.ctx', fake_ctx): public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.CREATE, "1.2.3.4") + gateway, fake_client, vcloud_network_plugin.CREATE, + "1.2.3.4") self.assertEqual( fake_ctx._target.instance.runtime_properties, { @@ -433,7 +438,8 @@ def _ip_exist_in_runtime(fake_ctx): 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -446,7 +452,8 @@ def _ip_exist_in_runtime(fake_ctx): 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -466,7 +473,8 @@ def _ip_exist_in_runtime(fake_ctx): 'vcloud_plugin_common.ctx', fake_ctx ): public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -490,7 +498,8 @@ def _ip_exist_in_runtime(fake_ctx): ): # import pdb;pdb.set_trace() public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, "1.2.3.4" + gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" ) gateway.deallocate_public_ip.assert_called_with("1.2.3.4") self.assertFalse(_ip_exist_in_runtime(fake_ctx)) @@ -609,7 +618,8 @@ def generate_client_and_context_server(self, no_vmip=False): fake_ctx._source.node.properties = { 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE } } fake_ctx._target.instance.runtime_properties = { @@ -789,7 +799,8 @@ def generate_client_and_context_network(self): 'vcloud_config': { 'org': 'some_org', 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE } } fake_ctx._target.node.properties = { @@ -879,7 +890,7 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # no gateway fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -896,13 +907,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # wrong ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -915,13 +927,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # no free ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway' @@ -933,13 +946,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # no rules fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -952,13 +966,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # wrong protocol fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -975,13 +990,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # wrong original_port fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -999,14 +1015,15 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # wrong original_port fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -1025,13 +1042,14 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) # fine fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { 'vdc': 'vdc_name', - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE }, 'nat': { 'edge_gateway': 'gateway', @@ -1049,7 +1067,7 @@ def test_creation_validation(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.creation_validation(ctx=fake_ctx) + public_nat.creation_validation(ctx=fake_ctx, vca_client=None) def _server_disconnect_to_nat_noexternal(self): fake_client, fake_ctx = self.generate_client_and_context_server() @@ -1228,7 +1246,7 @@ def test_net_connect_to_nat(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.net_connect_to_nat(ctx=fake_ctx) + public_nat.net_connect_to_nat(ctx=fake_ctx, vca_client=None) # no external fake_client, fake_ctx = self.generate_client_and_context_network() fake_ctx._target.node.properties = { @@ -1253,7 +1271,7 @@ def test_net_connect_to_nat(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.net_connect_to_nat(ctx=fake_ctx) + public_nat.net_connect_to_nat(ctx=fake_ctx, vca_client=None) fake_client._vdc_gateway.add_nat_rule.assert_called_with( 'DNAT', '10.18.1.1', 'any', '127.1.1.100 - 127.1.1.200', 'any', 'any' @@ -1264,7 +1282,7 @@ def test_net_connect_to_nat(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - public_nat.net_connect_to_nat(ctx=fake_ctx) + public_nat.net_connect_to_nat(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def test_net_connect_to_nat_preconfigure(self): @@ -1282,7 +1300,8 @@ def test_net_connect_to_nat_preconfigure(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx, + vca_client=None) fake_client, fake_ctx = self.generate_client_and_context_network() fake_ctx._target.node.properties = { @@ -1297,7 +1316,8 @@ def test_net_connect_to_nat_preconfigure(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx, + vca_client=None) # empty rules fake_ctx._target.node.properties.update({'rules': []}) with mock.patch( @@ -1305,7 +1325,8 @@ def test_net_connect_to_nat_preconfigure(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx) + public_nat.net_connect_to_nat_preconfigure(ctx=fake_ctx, + vca_client=None) if __name__ == '__main__': diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index d43b199..fc4adeb 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -113,7 +113,7 @@ def test_creation_validation_empty_settings(self): self.generate_vca() ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_external_resource(self): """ @@ -136,7 +136,7 @@ def test_creation_validation_external_resource(self): self.generate_vca() ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) # with resource_id fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', @@ -153,7 +153,7 @@ def test_creation_validation_external_resource(self): 'vcloud_plugin_common.VcloudAirClient', self.generate_vca() ): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_settings_wrong_catalog(self): fake_ctx = cfy_mocks.MockCloudifyContext( @@ -174,7 +174,7 @@ def test_creation_validation_settings_wrong_catalog(self): self.generate_vca() ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_settings_wrong_template(self): fake_ctx = cfy_mocks.MockCloudifyContext( @@ -195,7 +195,7 @@ def test_creation_validation_settings_wrong_template(self): self.generate_vca() ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_settings(self): fake_ctx = cfy_mocks.MockCloudifyContext( @@ -215,7 +215,7 @@ def test_creation_validation_settings(self): 'vcloud_plugin_common.VcloudAirClient.get', self.generate_vca() ): - server.creation_validation(ctx=fake_ctx) + server.creation_validation(ctx=fake_ctx, vca_client=None) def test_isDhcpAvailable(self): client = self.generate_client() diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py index f479c25..a10d9e7 100644 --- a/tests/unittests/test_mock_server_plugin_vdc.py +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -87,7 +87,8 @@ def test_create(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE } } ) @@ -98,7 +99,8 @@ def test_create(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE }, 'use_external_resource': True, 'resource_id': 'not_existed' @@ -117,7 +119,8 @@ def test_create(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE }, 'use_external_resource': False, } @@ -128,7 +131,8 @@ def test_create(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE }, 'use_external_resource': False, 'name': "something" @@ -159,7 +163,8 @@ def test_delete(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE }, 'use_external_resource': True, 'resource_id': 'not_existed' @@ -173,7 +178,8 @@ def test_delete(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={ 'vcloud_config': { - 'service_type': vcloud_plugin_common.ONDEMAND_SERVICE_TYPE + 'service_type': + vcloud_plugin_common.ONDEMAND_SERVICE_TYPE }, 'use_external_resource': False, 'name': "something" diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index f12981c..81ff981 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -397,7 +397,9 @@ def test_attach_volume(self): with mock.patch('vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client)): with mock.patch( - 'vcloud_storage_plugin.volume._wait_for_boot', mock.MagicMock()): + 'vcloud_storage_plugin.volume._wait_for_boot', + mock.MagicMock() + ): volume.attach_volume(ctx=fake_ctx) def test_detach_volume(self): diff --git a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py index 42a707c..8132c26 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py +++ b/tests/unittests/test_mock_vcloud_plugin_common_vca_client.py @@ -54,10 +54,12 @@ def _run( 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'pyvcloud.vcloudair.VCS', - mock.MagicMock()): - with mock.patch('vcloud_plugin_common.local_session_token', - None): + 'pyvcloud.vcloudair.VCS', mock.MagicMock() + ): + with mock.patch( + 'vcloud_plugin_common.local_session_token', + None + ): return client._subscription_login( url, username, password, token, service, org_name) @@ -129,12 +131,15 @@ def _run( 'vcloud_plugin_common.ctx', fake_ctx ): with mock.patch( - 'pyvcloud.vcloudair.VCS', - mock.MagicMock()): - with mock.patch('vcloud_plugin_common.local_session_token', - None): + 'pyvcloud.vcloudair.VCS', mock.MagicMock() + ): + with mock.patch( + 'vcloud_plugin_common.local_session_token', + None + ): return client._ondemand_login( - url, username, password, token, instance_id) + url, username, password, token, + instance_id) # bad case without instance with self.assertRaises(cfy_exc.NonRecoverableError): _run( diff --git a/tox.ini b/tox.ini index ae124cd..1888787 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-unittests, pep8 +envlist = py27-unittests, pep8, validate minversion = 1.6 skipsdist = True @@ -14,8 +14,23 @@ commands = nosetests tests/unittests --cover-html --with-coverage --cover-packa [testenv:pep8] commands= - flake8 --ignore=E501 tests - flake8 --ignore=E501 vcloud_network_plugin vcloud_server_plugin vcloud_plugin_common vcloud_storage_plugin + flake8 tests + flake8 vcloud_network_plugin + flake8 vcloud_server_plugin + flake8 vcloud_plugin_common + flake8 vcloud_storage_plugin + #pylint -E tests \ + #-E vcloud_network_plugin \ + #-E vcloud_server_plugin \ + #-E vcloud_plugin_common \ + #-E vcloud_storage_plugin ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py + +[testenv:validate] +deps = + cloudify==4.5 + {[testenv]deps} +commands = + cfy blueprint validate examples/blueprint.yaml diff --git a/vcloud_network_plugin/__init__.py b/vcloud_network_plugin/__init__.py index 3020b28..18192cf 100644 --- a/vcloud_network_plugin/__init__.py +++ b/vcloud_network_plugin/__init__.py @@ -242,7 +242,7 @@ def get_network(vca_client, network_name): """ if not network_name: raise cfy_exc.NonRecoverableError( - "Network name is empty".format(network_name)) + "Network name is empty: {0}".format(network_name)) network = vca_client.get_network(get_vcloud_config()['vdc'], network_name) if not network: raise cfy_exc.NonRecoverableError( @@ -376,7 +376,8 @@ def _is_gateway_locked(ctx): except KeyError: pass if rest: - node_instances = rest.node_instances.list(deployment_id=ctx.deployment.id) + node_instances = rest.node_instances.list( + deployment_id=ctx.deployment.id) elif ctx.deployment.id == 'local': storage = ctx._endpoint.storage node_instances = storage.get_node_instances() diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index f61156e..63efbed 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -21,9 +21,10 @@ CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, CREATE, DELETE, PUBLIC_IP, get_gateway, - SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - get_public_ip, del_ondemand_public_ip, - set_retry, lock_gateway) + SSH_PUBLIC_IP, SSH_PORT, + save_ssh_parameters, get_public_ip, + del_ondemand_public_ip, set_retry, + lock_gateway) @operation(resumable=True) @@ -106,7 +107,7 @@ def _floatingip_operation(operation, vca_client, ctx): nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: - ctx.logger.info("Can't get external IP".format(public_ip)) + ctx.logger.info("Can't get external IP {0}".format(public_ip)) return True nat_operation = _del_nat_rule else: diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 2bf873f..cfaa368 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -82,9 +82,11 @@ def create(**kwargs): obj.get(PRIVATE_KEY, {}).get(PATH) if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): if obj.get(PRIVATE_KEY, {}).get(KEY): - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() - _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], - ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) + ctx.instance.runtime_properties[ + PRIVATE_KEY][PATH] = _create_path() + _save_key_file( + ctx.instance.runtime_properties[PRIVATE_KEY][PATH], + ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @operation(resumable=True) @@ -114,13 +116,17 @@ def server_connect_to_keypair(**kwargs): if SSH_KEY not in host_rt_properties: host_rt_properties[SSH_KEY] = {} if PRIVATE_KEY in target_rt_properties: - host_rt_properties[SSH_KEY][PATH] = target_rt_properties[PRIVATE_KEY].get(PATH) - host_rt_properties[SSH_KEY][KEY] = target_rt_properties[PRIVATE_KEY].get(KEY) + host_rt_properties[SSH_KEY][PATH] = target_rt_properties[ + PRIVATE_KEY].get(PATH) + host_rt_properties[SSH_KEY][KEY] = target_rt_properties[ + PRIVATE_KEY].get(KEY) if PUBLIC_KEY in target_rt_properties: - host_rt_properties[SSH_KEY][USER] = target_rt_properties[PUBLIC_KEY].get(USER) + host_rt_properties[SSH_KEY][USER] = target_rt_properties[ + PUBLIC_KEY].get(USER) if target_rt_properties[PRIVATE_KEY].get(PATH): host_rt_properties[CLOUDIFY_AGENT] = {} - host_rt_properties[CLOUDIFY_AGENT][KEY] = target_rt_properties[PRIVATE_KEY].get(PATH) + host_rt_properties[CLOUDIFY_AGENT][KEY] = target_rt_properties[ + PRIVATE_KEY].get(PATH) ctx.source.instance.update() diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 321a2c1..b124a0b 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -18,8 +18,9 @@ from vcloud_plugin_common import (with_vca_client, wait_for_task, get_vcloud_config, get_mandatory) import collections -from vcloud_network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, - is_ips_in_same_subnet, save_gateway_configuration, +from vcloud_network_plugin import (check_ip, is_valid_ip_range, + is_separate_ranges, is_ips_in_same_subnet, + save_gateway_configuration, get_network_name, is_network_exists, get_gateway, set_retry) diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index bfdf6b9..1d860d3 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -16,12 +16,14 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, - get_mandatory, is_subscription, is_ondemand) + get_mandatory, is_subscription, + is_ondemand) from vcloud_network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, - get_gateway, getFreeIP, CREATE, DELETE, PUBLIC_IP, - SSH_PUBLIC_IP, SSH_PORT, save_ssh_parameters, - del_ondemand_public_ip, utils, set_retry, lock_gateway) + get_gateway, getFreeIP, CREATE, DELETE, + PUBLIC_IP, SSH_PUBLIC_IP, SSH_PORT, + save_ssh_parameters, del_ondemand_public_ip, + utils, set_retry, lock_gateway) from vcloud_network_plugin.network import VCLOUD_NETWORK_NAME from IPy import IP diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index 28a79f4..e505d84 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -17,8 +17,9 @@ from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_mandatory, get_vcloud_config) -from vcloud_network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, - get_gateway, utils, set_retry, lock_gateway) +from vcloud_network_plugin import (check_ip, get_vm_ip, + save_gateway_configuration, get_gateway, + utils, set_retry, lock_gateway) CREATE_RULE = 1 diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 9f4dd0d..0416997 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -166,7 +166,9 @@ def connect(self, cfg): api_version = cfg.get('api_version', '5.6') session_token = cfg.get(SESSION_TOKEN) org_url = cfg.get(ORG_URL) - if not (all([url, token]) or all([url, username, password]) or session_token): + if not (all([url, token]) or + all([url, username, password]) + or session_token): raise cfy_exc.NonRecoverableError( "Login credentials must be specified.") if (service_type == SUBSCRIPTION_SERVICE_TYPE and not ( @@ -211,7 +213,8 @@ def _subscription_login(self, url, username, password, token, service, if vca: return vca else: - raise cfy_exc.NonRecoverableError("Invalid session credentials") + raise cfy_exc.NonRecoverableError( + "Invalid session credentials") global local_org_url global local_session_token @@ -276,7 +279,8 @@ def get_instance(vca, instance_id): if vca: return vca else: - raise cfy_exc.NonRecoverableError("Invalid session credentials") + raise cfy_exc.NonRecoverableError( + "Invalid session credentials") global local_org_url global local_session_token diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index c7dcdb2..ae7dc04 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -167,7 +167,7 @@ def _create(vca_client, config, server): task = vapp.modify_vm_name(1, vapp_name) if not task: raise cfy_exc.NonRecoverableError( - "Can't modyfy VM name".format(vapp_name)) + "Can't modyfy VM name: {0}".format(vapp_name)) wait_for_task(vca_client, task) ctx.logger.info("VM '{0}' has been renamed.".format(vapp_name)) diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index 6a41f7f..4ccd28f 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -152,12 +152,14 @@ def _volume_operation(vca_client, operation): for ref in vca_client.get_diskRefs(vdc): if ref.name == volumeName: if operation == 'ATTACH': - ctx.logger.info("Attach volume node '{0}'.".format(volumeName)) + ctx.logger.info("Attach volume node '{0}'." + .format(volumeName)) task = vapp.attach_disk_to_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( - "Volume node '{0}' has been attached".format(volumeName)) + "Volume node '{0}' has been attached" + .format(volumeName)) else: raise cfy_exc.NonRecoverableError( "Can't attach disk: '{0}' with error: {1}". From dad0f40ff9747f0df77a3d13eb0708a35c5ee044 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:29:08 +0200 Subject: [PATCH 205/228] CYBL-979: prepere to recombine properties --- vcloud_plugin_common/__init__.py | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 0416997..7de19cf 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -559,3 +559,49 @@ def login_with_retry(function, arguments, message): ctx.logger.info("{0} successful.".format(message)) return True return False + + +def delete_properties(ctx): + # cleanup runtime properties + # need to convert generaton to list, python 3 + keys = [key for key in ctx.instance.runtime_properties.keys()] + for key in keys: + del ctx.instance.runtime_properties[key] + + +def combine_properties(ctx, kwargs=None, names=None, properties=None): + """combine properties + runtime properties + kwargs""" + if not kwargs: + kwargs = {} + if not properties: + properties = [] + # add default properties names (uncombined things) + properties += ["use_external_resource", "resource_id"] + obj = {} + # use node properties as base + obj.update(ctx.node.properties) + if names: + # update base properties with runtime properties + for name in names: + prop_value = obj.get(name, {}) + prop_value.update(ctx.instance.runtime_properties.get(name, {})) + obj[name] = prop_value + # update base properties with kwargs + for name in names: + prop_value = obj.get(name, {}) + prop_value.update(kwargs.get(name, {})) + obj[name] = prop_value + # combine by priority + for name in ["use_external_resource", "resource_id"]: + obj[name] = kwargs.get( + name, + ctx.instance.runtime_properties.get( + name, + ctx.node.properties.get(name) + ) + ) + # update runtime properties back + for name in obj: + if "vcloud_config" != name: + ctx.instance.runtime_properties[name] = obj[name] + return obj From 3578de444f90f177032e914a229407c2dfb777d1 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:30:16 +0200 Subject: [PATCH 206/228] CYBL-979: combine port properties --- plugin.yaml | 7 +++++++ vcloud_network_plugin/port.py | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 9ced4c9..9d88e22 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -73,6 +73,13 @@ node_types: vcloud_config: default: {} interfaces: + cloudify.interfaces.lifecycle: + create: + implementation: vcloud.vcloud_network_plugin.port.create + inputs: {} + delete: + implementation: vcloud.vcloud_network_plugin.port.delete + inputs: {} cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_network_plugin.port.creation_validation diff --git a/vcloud_network_plugin/port.py b/vcloud_network_plugin/port.py index 2851821..091bbe2 100644 --- a/vcloud_network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -15,7 +15,8 @@ from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation -from vcloud_plugin_common import with_vca_client, get_mandatory +from vcloud_plugin_common import (with_vca_client, get_mandatory, + combine_properties, delete_properties) from vcloud_network_plugin import check_ip @@ -28,9 +29,7 @@ def creation_validation(vca_client, **kwargs): and valid ip_address if set """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['port']) # get port port = get_mandatory(obj, 'port') ip_allocation_mode = port.get('ip_allocation_mode') @@ -41,3 +40,15 @@ def creation_validation(vca_client, **kwargs): ip_address = port.get('ip_address') if ip_address: check_ip(ip_address) + + +@operation(resumable=True) +@with_vca_client +def create(vca_client, **kwargs): + combine_properties(ctx, kwargs=kwargs, names=['port']) + + +@operation(resumable=True) +@with_vca_client +def delete(vca_client, **kwargs): + delete_properties(ctx) From c8c9729dd505d93ae3057b5827899638e39e71a4 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:31:13 +0200 Subject: [PATCH 207/228] CYBL-979: combine network properties --- vcloud_network_plugin/network.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index b124a0b..2686ac7 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -16,7 +16,8 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, wait_for_task, - get_vcloud_config, get_mandatory) + get_vcloud_config, get_mandatory, + delete_properties, combine_properties) import collections from vcloud_network_plugin import (check_ip, is_valid_ip_range, is_separate_ranges, is_ips_in_same_subnet, @@ -53,10 +54,7 @@ def create(vca_client, **kwargs): } """ vdc_name = get_vcloud_config()['vdc'] - # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['network']) # check external resource if obj['use_external_resource']: network_name = obj['resource_id'] @@ -145,6 +143,7 @@ def delete(vca_client, **kwargs): return raise cfy_exc.NonRecoverableError( "Could not delete network '{0}': {1}".format(network_name, task)) + delete_properties(ctx) @operation(resumable=True) From 32c11d2eb1bb483a38b5910d0a58539022013c5a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:31:29 +0200 Subject: [PATCH 208/228] CYBL-979: combine server properties --- vcloud_server_plugin/server.py | 50 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index ae7dc04..313aa61 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -23,6 +23,8 @@ wait_for_task, with_vca_client, error_response, + combine_properties, + delete_properties, STATUS_POWERED_ON) from vcloud_network_plugin import (get_network_name, get_network, is_network_exists, @@ -55,9 +57,9 @@ def get_template(catalog, template_name): return template # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) # get external if obj.get('use_external_resource'): if not obj.get('resource_id'): @@ -112,14 +114,12 @@ def create(vca_client, **kwargs): server = { 'name': ctx.instance.id, } - server.update(ctx.node.properties.get('server', {})) - server.update(kwargs.get('server', {})) - transform_resource_name(server, ctx) - # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) + server.update(obj.get('server', {})) + transform_resource_name(server, ctx) # get external if obj.get('use_external_resource'): res_id = obj['resource_id'] @@ -233,9 +233,9 @@ def start(vca_client, **kwargs): power on server and wait network connection availability for host """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) # get external if obj.get('use_external_resource'): ctx.logger.info('not starting server since an external server is ' @@ -260,9 +260,9 @@ def stop(vca_client, **kwargs): poweroff server, if external resource - server stay poweroned """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) # get external if obj.get('use_external_resource'): ctx.logger.info('not stopping server since an external server is ' @@ -287,9 +287,9 @@ def delete(vca_client, **kwargs): delete server """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) # get external if obj.get('use_external_resource'): ctx.logger.info('not deleting server since an external server is ' @@ -306,7 +306,7 @@ def delete(vca_client, **kwargs): format(error_response(vapp))) wait_for_task(vca_client, task) - del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] + delete_properties(ctx) def _is_primary_connection_has_ip(vapp): @@ -328,9 +328,9 @@ def _is_primary_connection_has_ip(vapp): @with_vca_client def configure(vca_client, **kwargs): # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['server'], + properties=[VCLOUD_VAPP_NAME, 'management_network']) # get external if obj.get('use_external_resource'): ctx.logger.info('Avoiding external resource configuration.') @@ -671,7 +671,8 @@ def _create_connections_list(vca_client): management_network_name = ctx.node.properties.get('management_network') for port in ports: - port_properties = port.node.properties['port'] + obj = combine_properties(port, names=['port']) + port_properties = obj['port'] connections.append( _create_connection(port_properties['network'], port_properties.get('ip_address'), @@ -683,6 +684,7 @@ def _create_connections_list(vca_client): ) for net in networks: + obj = combine_properties(net, names=['network']) connections.append( _create_connection(get_network_name(net.node.properties), None, None, 'POOL')) From 28ca266b6689691c0368143f0440c4aa03116750 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:31:49 +0200 Subject: [PATCH 209/228] CYBL-979: combine volume properties --- vcloud_storage_plugin/volume.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index 4ccd28f..64e0cb8 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -18,6 +18,7 @@ from cloudify.decorators import operation from vcloud_plugin_common import (wait_for_task, with_vca_client, get_vcloud_config, get_mandatory, + combine_properties, delete_properties, error_response) from vcloud_network_plugin import get_vapp_name, SSH_PUBLIC_IP, SSH_PORT @@ -36,9 +37,8 @@ def create_volume(vca_client, **kwargs): } """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['volume'], + properties=['device_name']) # get external if obj.get('use_external_resource'): ctx.logger.info("External resource has been used") @@ -65,9 +65,8 @@ def delete_volume(vca_client, **kwargs): drop volume """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['volume'], + properties=['device_name']) # get external if obj.get('use_external_resource'): ctx.logger.info("External resource has been used") @@ -83,6 +82,7 @@ def delete_volume(vca_client, **kwargs): else: raise cfy_exc.NonRecoverableError( "Disk deletion error: {0}".format(task)) + delete_properties(ctx) @operation(resumable=True) @@ -96,9 +96,8 @@ def creation_validation(vca_client, **kwargs): disk.name for [disk, _vms] in vca_client.get_disks(vdc_name) ] # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['volume'], + properties=['device_name']) # get external resource flag if obj.get('use_external_resource'): # get resource_id @@ -107,10 +106,6 @@ def creation_validation(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Disk {} does't exists".format(resource_id)) else: - # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) # get volume volume = get_mandatory(obj, 'volume') name = get_mandatory(volume, 'name') From aaf45407ff0eb030c968cabdf48bab6b52df07ef Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:32:04 +0200 Subject: [PATCH 210/228] CYBL-979: combine vdc properties --- vcloud_server_plugin/vdc.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index 61d9117..733c533 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -20,6 +20,8 @@ wait_for_task, with_vca_client, is_subscription, + combine_properties, + delete_properties, error_response) VDC_NAME = 'vdc_name' @@ -44,9 +46,7 @@ def creation_validation(vca_client, **kwargs): """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, properties=['name']) # get external if obj.get(USE_EXTERNAL_RESOURCE): if not obj.get(RESOURCE_ID): @@ -80,9 +80,7 @@ def create(vca_client, **kwargs): raise cfy_exc.NonRecoverableError( "Unable create VDC on subscription service.") # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, properties=['name']) # get external if obj.get(USE_EXTERNAL_RESOURCE): # use external resource, does not create anything @@ -112,9 +110,7 @@ def create(vca_client, **kwargs): def delete(vca_client, **kwargs): """delete vdc""" # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, properties=['name']) # get external # external resource - no actions if obj.get(USE_EXTERNAL_RESOURCE): @@ -129,5 +125,4 @@ def delete(vca_client, **kwargs): "Could not delete VDC: {0}".format(error_response(vca_client))) wait_for_task(vca_client, task) # clean up runtime_properties - if VDC_NAME in ctx.instance.runtime_properties: - del ctx.instance.runtime_properties[VDC_NAME] + delete_properties(ctx) From 6492991fe3d635e8963ed297c1f032f9eb72c12f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:55:26 +0200 Subject: [PATCH 211/228] CYBL-979: combine security group properties --- plugin.yaml | 4 +++ .../test_mock_network_plugin_port.py | 24 +++++++++++++ ...test_mock_network_plugin_security_group.py | 16 +++++++++ vcloud_network_plugin/security_group.py | 34 ++++++++++++++----- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 9d88e22..c9a0404 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -122,6 +122,10 @@ node_types: vcloud_config: default: {} interfaces: + cloudify.interfaces.lifecycle: + create: + implementation: vcloud.vcloud_network_plugin.security_group.create_node + inputs: {} cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_network_plugin.security_group.creation_validation diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 142b996..b379b6c 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -22,6 +22,30 @@ class NetworkPluginPortMockTestCase(test_mock_base.TestBase): + def test_create(self): + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + # no port + fake_ctx = self.generate_node_context_with_current_ctx( + properties={} + ) + port.create(ctx=fake_ctx) + + def test_delete(self): + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + # no port + fake_ctx = self.generate_node_context_with_current_ctx( + properties={} + ) + port.delete(ctx=fake_ctx) + def test_creation_validation(self): fake_client = self.generate_client() with mock.patch( diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index f945aa6..c9e6ba5 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -411,6 +411,22 @@ def check_creation_validation(self, rule): ) security_group.creation_validation(ctx=fake_ctx) + def test_create_node(self): + fake_client = self.generate_client() + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'edge_gateway': 'some_edge_gateway', + 'vdc': 'vdc_name' + } + } + ) + security_group.create_node(ctx=fake_ctx) + def test_creation_validation(self): fake_client = self.generate_client() with mock.patch( diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index e505d84..c004c3d 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -16,6 +16,7 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_mandatory, + combine_properties, delete_properties, get_vcloud_config) from vcloud_network_plugin import (check_ip, get_vm_ip, save_gateway_configuration, get_gateway, @@ -29,6 +30,18 @@ ACTIONS = ("allow", "deny") +@operation(resumable=True) +@with_vca_client +def create_node(vca_client, **kwargs): + """ + save properties on create step + """ + # combine properties + combine_properties( + ctx, kwargs=kwargs, names=['security_group'], + properties=['rules']) + + @operation(resumable=True) @with_vca_client @lock_gateway @@ -36,7 +49,7 @@ def create(vca_client, **kwargs): """ create firewall rules for node """ - if not _rule_operation(CREATE_RULE, vca_client): + if not _rule_operation(CREATE_RULE, vca_client, kwargs=kwargs): return set_retry(ctx) @@ -47,8 +60,9 @@ def delete(vca_client, **kwargs): """ drop firewall rules for node """ - if not _rule_operation(DELETE_RULE, vca_client): + if not _rule_operation(DELETE_RULE, vca_client, kwargs=kwargs): return set_retry(ctx) + delete_properties(ctx.target) @operation(resumable=True) @@ -57,16 +71,16 @@ def creation_validation(vca_client, **kwargs): """ validate firewall rules for node """ + # combine properties + obj = combine_properties( + ctx, kwargs=kwargs, names=['security_group'], + properties=['rules']) getaway = get_gateway( vca_client, _get_gateway_name(ctx.node.properties) ) if not getaway.is_fw_enabled(): raise cfy_exc.NonRecoverableError( "Gateway firewall is disabled. Please, enable firewall.") - # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) # get rules rules = get_mandatory(obj, 'rules') for rule in rules: @@ -110,13 +124,17 @@ def creation_validation(vca_client, **kwargs): "Parameter 'log_traffic' must be boolean.") -def _rule_operation(operation, vca_client): +def _rule_operation(operation, vca_client, kwargs=None): """ create/delete firewall rules in gateway for current node """ gateway_name = _get_gateway_name(ctx.target.node.properties) gateway = get_gateway(vca_client, gateway_name) - for rule in ctx.target.node.properties['rules']: + # combine properties + obj = combine_properties( + ctx.target, kwargs=kwargs, names=['security_group'], + properties=['rules']) + for rule in obj['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") if not _is_literal_ip(source_ip): From 9957efaf2b62d82f8f3abc1b7fb478dbd72ced28 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 17:57:55 +0200 Subject: [PATCH 212/228] CYBL-979: combine public nat properties --- .../test_mock_network_plugin_public_nat.py | 16 ++++++++ vcloud_network_plugin/public_nat.py | 40 ++++++++++++++----- vcloud_network_plugin/security_group.py | 9 ++--- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 05949ee..d814646 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -875,6 +875,22 @@ def test_prepare_network_operation(self): 'any', 'any' ) + def test_create(self): + fake_client = self.generate_client() + # no nat + fake_ctx = self.generate_node_context_with_current_ctx( + properties={ + 'vcloud_config': { + 'vdc': 'vdc_name' + } + } + ) + with mock.patch( + 'vcloud_plugin_common.VcloudAirClient.get', + mock.MagicMock(return_value=fake_client) + ): + public_nat.create_node(ctx=fake_ctx, vca_client=None) + def test_creation_validation(self): fake_client = self.generate_client() # no nat diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index 1d860d3..b219f75 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -17,7 +17,7 @@ from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, get_mandatory, is_subscription, - is_ondemand) + combine_properties, is_ondemand) from vcloud_network_plugin import (check_ip, save_gateway_configuration, get_vm_ip, get_public_ip, get_gateway, getFreeIP, CREATE, DELETE, @@ -34,7 +34,10 @@ @operation(resumable=True) @with_vca_client def net_connect_to_nat_preconfigure(vca_client, **kwargs): - rules = ctx.target.node.properties['rules'] + # combine properties + obj = combine_properties( + ctx.target, names=['nat'], properties=['rules']) + rules = obj['rules'] if not rules or len(rules) != 1: raise cfy_exc.NonRecoverableError( "Rules list must contains only one element") @@ -51,7 +54,10 @@ def net_connect_to_nat(vca_client, **kwargs): """ create nat rule for current node """ - if ctx.target.node.properties.get('use_external_resource', False): + # combine properties + obj = combine_properties( + ctx.target, names=['nat'], properties=['rules']) + if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return if not prepare_network_operation(vca_client, CREATE): @@ -65,7 +71,10 @@ def net_disconnect_from_nat(vca_client, **kwargs): """ drop nat rule for current node """ - if ctx.target.node.properties.get('use_external_resource', False): + # combine properties + obj = combine_properties( + ctx.target, names=['nat'], properties=['rules']) + if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return if not prepare_network_operation(vca_client, DELETE): @@ -94,6 +103,17 @@ def server_disconnect_from_nat(vca_client, **kwargs): return set_retry(ctx) +@operation(resumable=True) +@with_vca_client +def create_node(vca_client, **kwargs): + """ + save properties on create step + """ + # combine properties + combine_properties( + ctx, kwargs=kwargs, names=['nat'], properties=['rules']) + + @operation(resumable=True) @with_vca_client def creation_validation(vca_client, **kwargs): @@ -101,9 +121,8 @@ def creation_validation(vca_client, **kwargs): validate nat rules in node properties """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties( + ctx, kwargs=kwargs, names=['nat'], properties=['rules']) # get net nat = get_mandatory(obj, 'nat') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) @@ -160,8 +179,11 @@ def prepare_server_operation(vca_client, operation): generate nat rules by current list of rules in node """ try: + # combine properties + obj = combine_properties( + ctx.target, names=['nat'], properties=['rules']) gateway = get_gateway( - vca_client, ctx.target.node.properties['nat']['edge_gateway']) + vca_client, obj['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) if not public_ip: ctx.logger.info("We dont have public ip. Retrying...") @@ -171,7 +193,7 @@ def prepare_server_operation(vca_client, operation): ctx.logger.info("We dont have private ip. Retrying...") return False has_snat = False - for rule in ctx.target.node.properties['rules']: + for rule in obj['rules']: rule_type = rule['type'] if has_snat and _is_snat(rule_type): ctx.logger.info("Rules list must contains only one SNAT rule.") diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index c004c3d..f34099e 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -49,7 +49,7 @@ def create(vca_client, **kwargs): """ create firewall rules for node """ - if not _rule_operation(CREATE_RULE, vca_client, kwargs=kwargs): + if not _rule_operation(CREATE_RULE, vca_client): return set_retry(ctx) @@ -60,7 +60,7 @@ def delete(vca_client, **kwargs): """ drop firewall rules for node """ - if not _rule_operation(DELETE_RULE, vca_client, kwargs=kwargs): + if not _rule_operation(DELETE_RULE, vca_client): return set_retry(ctx) delete_properties(ctx.target) @@ -124,7 +124,7 @@ def creation_validation(vca_client, **kwargs): "Parameter 'log_traffic' must be boolean.") -def _rule_operation(operation, vca_client, kwargs=None): +def _rule_operation(operation, vca_client): """ create/delete firewall rules in gateway for current node """ @@ -132,8 +132,7 @@ def _rule_operation(operation, vca_client, kwargs=None): gateway = get_gateway(vca_client, gateway_name) # combine properties obj = combine_properties( - ctx.target, kwargs=kwargs, names=['security_group'], - properties=['rules']) + ctx.target, names=['security_group'], properties=['rules']) for rule in obj['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") From 15d1ef952e58c716d6d00e138ce8024503b679b4 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 18:12:20 +0200 Subject: [PATCH 213/228] CYBL-979: combine floatingip properties --- vcloud_network_plugin/floatingip.py | 16 +++++++++------- vcloud_network_plugin/network.py | 9 +++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index 63efbed..eb64c47 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -16,7 +16,8 @@ from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, - is_subscription, is_ondemand, get_mandatory) + is_subscription, is_ondemand, get_mandatory, + combine_properties) from vcloud_network_plugin import (check_ip, CheckAssignedExternalIp, CheckAssignedInternalIp, get_vm_ip, save_gateway_configuration, getFreeIP, @@ -63,9 +64,7 @@ def creation_validation(vca_client, **kwargs): ip in subscription case """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['floatingip']) # get floatingip floatingip = get_mandatory(obj, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') @@ -87,15 +86,18 @@ def _floatingip_operation(operation, vca_client, ctx): save selected public_ip in runtime properties """ service_type = get_vcloud_config().get('service_type') + # combine properties + obj = combine_properties(ctx.target, names=['floatingip']) + gateway = get_gateway( - vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) + vca_client, obj['floatingip']['edge_gateway']) internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = ( ctx.target.instance.runtime_properties.get(PUBLIC_IP) ) or ( - ctx.target.node.properties['floatingip'].get(PUBLIC_IP) + obj['floatingip'].get(PUBLIC_IP) ) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) @@ -127,7 +129,7 @@ def _floatingip_operation(operation, vca_client, ctx): save_ssh_parameters(ctx, '22', external_ip) else: if is_ondemand(service_type): - if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): + if not obj['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 2686ac7..76590b5 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -54,6 +54,7 @@ def create(vca_client, **kwargs): } """ vdc_name = get_vcloud_config()['vdc'] + # combine properties obj = combine_properties(ctx, kwargs=kwargs, names=['network']) # check external resource if obj['use_external_resource']: @@ -117,9 +118,7 @@ def delete(vca_client, **kwargs): delete vcloud air network """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['network']) # check external resource if obj['use_external_resource'] is True: del ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] @@ -153,9 +152,7 @@ def creation_validation(vca_client, **kwargs): check network description from node description """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, names=['network']) # check external resource network_name = get_network_name(obj) ctx.logger.info("Validation cloudify.vcloud.nodes.Network node: {0}" From cbad04e274fb5591b347e71061d08cc763a342df Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 30 Jan 2020 18:12:32 +0200 Subject: [PATCH 214/228] CYBL-979: combine keypair properties --- vcloud_network_plugin/keypair.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index cfaa368..6be24b0 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -15,6 +15,7 @@ from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation +from vcloud_plugin_common import (combine_properties, delete_properties) import os.path from os import chmod from Crypto.PublicKey import RSA @@ -39,9 +40,9 @@ def creation_validation(**kwargs): node properties """ # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, + names=[PRIVATE_KEY, PUBLIC_KEY], + properties=['auto_generate']) # get key key_path = obj.get(PRIVATE_KEY, {}).get(PATH) if key_path: @@ -60,9 +61,9 @@ def create(**kwargs): ctx.instance.runtime_properties[PUBLIC_KEY][HOME] = \ ctx.node.properties.get(PUBLIC_KEY, {}).get(HOME) # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, + names=[PRIVATE_KEY, PUBLIC_KEY], + properties=['auto_generate']) # get key if obj.get(AUTO_GENERATE): ctx.logger.info("Generating ssh keypair") @@ -92,9 +93,9 @@ def create(**kwargs): @operation(resumable=True) def delete(**kwargs): # combine properties - obj = {} - obj.update(ctx.node.properties) - obj.update(kwargs) + obj = combine_properties(ctx, kwargs=kwargs, + names=[PRIVATE_KEY, PUBLIC_KEY], + properties=['auto_generate']) # get key if obj[AUTO_GENERATE]: if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): @@ -107,6 +108,7 @@ def delete(**kwargs): del ctx.instance.runtime_properties[PRIVATE_KEY] if PUBLIC_KEY in ctx.instance.runtime_properties: del ctx.instance.runtime_properties[PUBLIC_KEY] + delete_properties(ctx) @operation(resumable=True) From e2054724365ccc55c74e71e088da0b2d6df7717b Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 14:33:36 +0200 Subject: [PATCH 215/228] CYBL-979: Storage: get rid of use static ctx --- tests/unittests/test_mock_base.py | 2 +- .../test_mock_network_plugin_public_nat.py | 17 +++++--- ...test_mock_network_plugin_security_group.py | 22 ++++++---- .../test_mock_storage_plugin_volume.py | 43 +++++++++---------- tox.ini | 10 ++--- vcloud_storage_plugin/volume.py | 21 +++++---- 6 files changed, 59 insertions(+), 56 deletions(-) diff --git a/tests/unittests/test_mock_base.py b/tests/unittests/test_mock_base.py index 5d7451c..148dfc7 100644 --- a/tests/unittests/test_mock_base.py +++ b/tests/unittests/test_mock_base.py @@ -412,7 +412,7 @@ def generate_node_context( ) fake_ctx._instance = cfy_mocks.MockNodeInstanceContext( - fake_ctx.instance._id, fake_ctx.instance._runtime_properties + fake_ctx.instance.id, fake_ctx.instance.runtime_properties ) relationship = self.generate_relation_context() diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index d814646..22aaa41 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -1118,7 +1118,8 @@ def test_server_disconnect_from_nat(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.server_disconnect_from_nat(ctx=fake_ctx) + public_nat.server_disconnect_from_nat(ctx=fake_ctx, + vca_client=None) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '1.1.1.1', 'any', 'any' ) @@ -1129,7 +1130,8 @@ def test_server_disconnect_from_nat(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - public_nat.server_disconnect_from_nat(ctx=fake_ctx) + public_nat.server_disconnect_from_nat(ctx=fake_ctx, + vca_client=None) self.check_retry_realy_called(fake_ctx) def _server_connect_to_nat_noexternal(self): @@ -1168,7 +1170,7 @@ def test_server_connect_to_nat(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.server_connect_to_nat(ctx=fake_ctx) + public_nat.server_connect_to_nat(ctx=fake_ctx, vca_client=None) fake_client._vdc_gateway.add_nat_rule.assert_called_with( 'DNAT', '10.18.1.1', 'any', '1.1.1.1', 'any', 'any' ) @@ -1178,7 +1180,7 @@ def test_server_connect_to_nat(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - public_nat.server_connect_to_nat(ctx=fake_ctx) + public_nat.server_connect_to_nat(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def _net_disconnect_from_nat_noexternal(self): @@ -1222,14 +1224,15 @@ def test_net_disconnect_from_nat(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.net_disconnect_from_nat(ctx=fake_ctx) + public_nat.net_disconnect_from_nat(ctx=fake_ctx, + vca_client=fake_client) # no external fake_client, fake_ctx = self._net_disconnect_from_nat_noexternal() with mock.patch( 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - public_nat.net_disconnect_from_nat(ctx=fake_ctx) + public_nat.net_disconnect_from_nat(ctx=fake_ctx, vca_client=None) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '127.1.1.100 - 127.1.1.200', 'any', 'any' @@ -1241,7 +1244,7 @@ def test_net_disconnect_from_nat(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - public_nat.net_disconnect_from_nat(ctx=fake_ctx) + public_nat.net_disconnect_from_nat(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def test_net_connect_to_nat(self): diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index c9e6ba5..6c44e20 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -356,10 +356,10 @@ def test_create(self): mock.MagicMock(return_value=fake_client) ): # success case - security_group.create(ctx=fake_ctx) + security_group.create(ctx=fake_ctx, vca_client=None) # with retry self.prepere_gatway_busy_retry(fake_client, fake_ctx) - security_group.create(ctx=fake_ctx) + security_group.create(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def test_delete(self): @@ -388,10 +388,10 @@ def test_delete(self): mock.MagicMock(return_value=fake_client) ): # successful - security_group.delete(ctx=fake_ctx) + security_group.delete(ctx=fake_ctx, vca_client=None) # with retry self.prepere_gatway_busy_retry(fake_client, fake_ctx) - security_group.delete(ctx=fake_ctx) + security_group.delete(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def check_creation_validation(self, rule): @@ -409,7 +409,8 @@ def check_creation_validation(self, rule): 'rules': [rule] } ) - security_group.creation_validation(ctx=fake_ctx) + security_group.creation_validation(ctx=fake_ctx, + vca_client=None) def test_create_node(self): fake_client = self.generate_client() @@ -425,7 +426,7 @@ def test_create_node(self): } } ) - security_group.create_node(ctx=fake_ctx) + security_group.create_node(ctx=fake_ctx, vca_client=None) def test_creation_validation(self): fake_client = self.generate_client() @@ -446,13 +447,15 @@ def test_creation_validation(self): ) # Gateway firewall is disabled with self.assertRaises(cfy_exc.NonRecoverableError): - security_group.creation_validation(ctx=fake_ctx) + security_group.creation_validation(ctx=fake_ctx, + vca_client=None) fake_client._vdc_gateway.is_fw_enabled = mock.MagicMock( return_value=True ) # no rules with self.assertRaises(cfy_exc.NonRecoverableError): - security_group.creation_validation(ctx=fake_ctx) + security_group.creation_validation(ctx=fake_ctx, + vca_client=None) # wrong description with self.assertRaises(cfy_exc.NonRecoverableError): self.check_creation_validation({ @@ -465,7 +468,8 @@ def test_creation_validation(self): "source": 11 }) with self.assertRaises(cfy_exc.NonRecoverableError): - security_group.creation_validation(ctx=fake_ctx) + security_group.creation_validation(ctx=fake_ctx, + vca_client=None) # wrong ip with self.assertRaises(cfy_exc.NonRecoverableError): self.check_creation_validation({ diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index 81ff981..fae6bad 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -300,10 +300,7 @@ def _run_volume_operation(fake_ctx, fake_client, operation): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_storage_plugin.volume.ctx', fake_ctx - ): - volume._volume_operation(fake_client, operation) + volume._volume_operation(fake_ctx, fake_client, operation) # use external resource, no disks _run_volume_operation(fake_ctx, fake_client, 'ATTACH') @@ -414,7 +411,7 @@ def test_detach_volume(self): volume.detach_volume(ctx=fake_ctx) @unittest.skip("Fabric changed api, skip for now") - def run_wait_boot(self, fabric_settings, fabric_run, sleep_call=True): + def run_wait_boot(self, fabric_settings, fabric_run, ctx, sleep_call=True): sleep_function = mock.MagicMock() with mock.patch( 'fabric.api.settings', fabric_settings @@ -425,7 +422,7 @@ def run_wait_boot(self, fabric_settings, fabric_run, sleep_call=True): with mock.patch( 'time.sleep', sleep_function ): - volume._wait_for_boot() + volume._wait_for_boot(ctx) # check for sleep calls if sleep_call: sleep_function.assert_called_with(5) @@ -444,27 +441,27 @@ def test_wait_for_boot(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_storage_plugin.volume.ctx', fake_ctx - ): - # can't connect and run - with self.assertRaises(cfy_exc.NonRecoverableError): - self.run_wait_boot(fabric_settings, fabric_run) - # command successfully finished + # can't connect and run + with self.assertRaises(cfy_exc.NonRecoverableError): + self.run_wait_boot(fabric_settings, fabric_run, + ctx=fake_ctx) + # command successfully finished - def _sysexit(_): - raise SystemExit + def _sysexit(_): + raise SystemExit - fabric_run = mock.MagicMock(side_effect=_sysexit) - self.run_wait_boot(fabric_settings, fabric_run, False) - # raised some exception during run + fabric_run = mock.MagicMock(side_effect=_sysexit) + self.run_wait_boot(fabric_settings, fabric_run, + sleep_call=False, ctx=fake_ctx) + # raised some exception during run - def _raiseex(_): - raise Exception + def _raiseex(_): + raise Exception - fabric_run = mock.MagicMock(side_effect=_raiseex) - with self.assertRaises(cfy_exc.NonRecoverableError): - self.run_wait_boot(fabric_settings, fabric_run) + fabric_run = mock.MagicMock(side_effect=_raiseex) + with self.assertRaises(cfy_exc.NonRecoverableError): + self.run_wait_boot(fabric_settings, fabric_run, + ctx=fake_ctx) if __name__ == '__main__': diff --git a/tox.ini b/tox.ini index 1888787..69fd006 100644 --- a/tox.ini +++ b/tox.ini @@ -19,11 +19,11 @@ commands= flake8 vcloud_server_plugin flake8 vcloud_plugin_common flake8 vcloud_storage_plugin - #pylint -E tests \ - #-E vcloud_network_plugin \ - #-E vcloud_server_plugin \ - #-E vcloud_plugin_common \ - #-E vcloud_storage_plugin + pylint -E tests.unittests \ + -E vcloud_network_plugin \ + -E vcloud_server_plugin \ + -E vcloud_plugin_common \ + -E vcloud_storage_plugin ignore = exclude=.venv,.tox,dist,*egg,etc,build filename=*.py diff --git a/vcloud_storage_plugin/volume.py b/vcloud_storage_plugin/volume.py index 64e0cb8..75e18ea 100644 --- a/vcloud_storage_plugin/volume.py +++ b/vcloud_storage_plugin/volume.py @@ -13,7 +13,6 @@ # limitations under the License. import time -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (wait_for_task, with_vca_client, @@ -25,7 +24,7 @@ @operation(resumable=True) @with_vca_client -def create_volume(vca_client, **kwargs): +def create_volume(ctx, vca_client, **kwargs): """ create new volume, e.g.: { @@ -60,7 +59,7 @@ def create_volume(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def delete_volume(vca_client, **kwargs): +def delete_volume(ctx, vca_client, **kwargs): """ drop volume """ @@ -87,7 +86,7 @@ def delete_volume(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ check volume description """ @@ -117,22 +116,22 @@ def creation_validation(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def attach_volume(vca_client, **kwargs): +def attach_volume(ctx, vca_client, **kwargs): """attach volume""" - _wait_for_boot() - _volume_operation(vca_client, "ATTACH") + _wait_for_boot(ctx) + _volume_operation(ctx, vca_client, "ATTACH") @operation(resumable=True) @with_vca_client -def detach_volume(vca_client, **kwargs): +def detach_volume(ctx, vca_client, **kwargs): """ detach volume """ - _volume_operation(vca_client, "DETACH") + _volume_operation(ctx, vca_client, "DETACH") -def _volume_operation(vca_client, operation): +def _volume_operation(ctx, vca_client, operation): """ attach/detach volume """ @@ -177,7 +176,7 @@ def _volume_operation(vca_client, operation): "Unknown operation '{0}'".format(operation)) -def _wait_for_boot(): +def _wait_for_boot(ctx): """ Whait for loading os. This function just check if sshd is available. From f604301286f9738a16f3347f86b0db8e49b7517c Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 14:34:11 +0200 Subject: [PATCH 216/228] CYBL-979: SecurityGroup: get rid of use static ctx --- plugin.yaml | 5 +- .../test_mock_network_plugin_floatingip.py | 26 ++---- .../test_mock_network_plugin_network.py | 44 +++++----- ...test_mock_network_plugin_security_group.py | 34 ++------ .../test_mock_server_plugin_server.py | 82 ++++++++++--------- .../test_mock_vcloud_plugin_common.py | 2 +- vcloud_network_plugin/security_group.py | 25 ++---- 7 files changed, 90 insertions(+), 128 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index c9a0404..ff78137 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -124,11 +124,8 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.vcloud_network_plugin.security_group.create_node - inputs: {} - cloudify.interfaces.validation: - creation: implementation: vcloud.vcloud_network_plugin.security_group.creation_validation + inputs: {} cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 35bf746..26ae4d3 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -91,7 +91,7 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip.creation_validation(ctx=fake_ctx) + floatingip.creation_validation(ctx=fake_ctx, vca_client=None) # no edge gateway fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -108,7 +108,7 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip.creation_validation(ctx=fake_ctx) + floatingip.creation_validation(ctx=fake_ctx, vca_client=None) # with edge gateway, but wrong ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -126,7 +126,7 @@ def test_creation_validation(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip.creation_validation(ctx=fake_ctx) + floatingip.creation_validation(ctx=fake_ctx, vca_client=None) # with edge gateway, ip from pool fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -147,7 +147,7 @@ def test_creation_validation(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - floatingip.creation_validation(ctx=fake_ctx) + floatingip.creation_validation(ctx=fake_ctx, vca_client=None) # with some free ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -175,7 +175,7 @@ def test_creation_validation(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - floatingip.creation_validation(ctx=fake_ctx) + floatingip.creation_validation(ctx=fake_ctx, vca_client=None) def generate_client_and_context_floating_ip( self, service_type=vcloud_plugin_common.ONDEMAND_SERVICE_TYPE @@ -396,9 +396,7 @@ def test_disconnect_floatingip(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - floatingip.disconnect_floatingip( - ctx=fake_ctx - ) + floatingip.disconnect_floatingip(ctx=fake_ctx, vca_client=None) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( vcloud_network_plugin.PUBLIC_IP in runtime_properties @@ -416,9 +414,7 @@ def test_disconnect_floatingip(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - floatingip.disconnect_floatingip( - ctx=fake_ctx - ) + floatingip.disconnect_floatingip(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def test_connect_floatingip(self): @@ -456,9 +452,7 @@ def test_connect_floatingip(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - floatingip.connect_floatingip( - ctx=fake_ctx - ) + floatingip.connect_floatingip(ctx=fake_ctx, vca_client=None) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( vcloud_network_plugin.PUBLIC_IP in runtime_properties @@ -473,9 +467,7 @@ def test_connect_floatingip(self): mock.MagicMock(return_value=fake_client) ): self.prepere_gatway_busy_retry(fake_client, fake_ctx) - floatingip.connect_floatingip( - ctx=fake_ctx - ) + floatingip.connect_floatingip(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) def test_floatingip_operation_create(self): diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 64e3a18..5d72e8e 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -47,7 +47,7 @@ def test_delete(self): } ) - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) self.assertFalse( network.VCLOUD_NETWORK_NAME in fake_ctx.instance.runtime_properties @@ -77,14 +77,14 @@ def test_delete(self): vcloud_plugin_common.TASK_STATUS_ERROR ) with self.assertRaises(cfy_exc.NonRecoverableError): - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) # None in deleted vdc network self.set_services_conf_result( fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) with self.assertRaises(cfy_exc.NonRecoverableError): - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) # Error in deleted vdc network task_delete_vdc = self.generate_task( vcloud_plugin_common.TASK_STATUS_ERROR @@ -93,13 +93,13 @@ def test_delete(self): return_value=(True, task_delete_vdc) ) with self.assertRaises(cfy_exc.NonRecoverableError): - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) fake_client.delete_vdc_network.assert_called_with( 'vdc_name', 'secret_network' ) # retry in save configuration self.prepere_gatway_busy_retry(fake_client, fake_ctx) - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) # Success in deleted vdc network self.set_services_conf_result( @@ -112,7 +112,7 @@ def test_delete(self): fake_client.delete_vdc_network = mock.MagicMock( return_value=(True, task_delete_vdc) ) - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) # in use task_delete_vdc = self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS @@ -120,7 +120,7 @@ def test_delete(self): fake_client.delete_vdc_network = mock.MagicMock( return_value=(False, network.CANT_DELETE) ) - network.delete(ctx=fake_ctx) + network.delete(ctx=fake_ctx, vca_client=None) def test_create(self): fake_client = self.generate_client() @@ -152,7 +152,7 @@ def test_create(self): ) # error in create_vdc_network with self.assertRaises(cfy_exc.NonRecoverableError): - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) fake_client.create_vdc_network.assert_called_with( 'vdc_name', 'secret_network', 'gateway', '10.1.1.2', '10.1.1.127', '10.1.1.1', '255.255.255.0', '8.8.8.8', @@ -166,7 +166,7 @@ def test_create(self): return_value=(True, task) ) with self.assertRaises(cfy_exc.NonRecoverableError): - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) # retry in save configuration fake_client.create_vdc_network = mock.MagicMock( return_value=( @@ -176,7 +176,7 @@ def test_create(self): ) ) self.prepere_gatway_busy_retry(fake_client, fake_ctx) - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called(fake_ctx) runtime_properties = fake_ctx.instance.runtime_properties self.assertTrue(runtime_properties[network.SKIP_CREATE_NETWORK]) @@ -185,11 +185,11 @@ def test_create(self): fake_client._vdc_gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) # error in get gateway fake_client.get_gateway = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) # use external fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -214,7 +214,7 @@ def test_create(self): 'vcloud_network_name': 'secret_network' } ) - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) # not extist network fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -241,7 +241,7 @@ def test_create(self): ) fake_client.get_network = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) def node_for_check_create_network(self): return self.generate_node_context_with_current_ctx( @@ -280,7 +280,7 @@ def test_create_exist_same_network(self): fake_ctx = self.node_for_check_create_network() fake_client.get_network = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.create(ctx=fake_ctx) + network.create(ctx=fake_ctx, vca_client=None) def test_dhcp_operation(self): fake_ctx = self.node_for_check_create_network() @@ -318,7 +318,7 @@ def test_creation_validation(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) # network already exist fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -345,7 +345,7 @@ def test_creation_validation(self): ) fake_client.get_network = mock.MagicMock(return_value=True) with self.assertRaises(cfy_exc.NonRecoverableError): - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_network.assert_called_with( 'vdc_name', 'secret_network' ) @@ -373,7 +373,7 @@ def test_creation_validation(self): 'vcloud_network_name': 'secret_network' } ) - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_gateway(self): fake_client = self.generate_client( @@ -406,7 +406,7 @@ def test_creation_validation_gateway(self): } ) fake_client.get_network = mock.MagicMock(return_value=None) - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_gateway.assert_called_with( 'vdc_name', 'gateway' ) @@ -414,7 +414,7 @@ def test_creation_validation_gateway(self): # no gateway fake_client.get_gateway = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_network_mask(self): # test network mask @@ -449,7 +449,7 @@ def test_creation_validation_network_mask(self): ) fake_client.get_network = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_separate_ips(self): # test separate ips @@ -484,7 +484,7 @@ def test_creation_validation_separate_ips(self): ) fake_client.get_network = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - network.creation_validation(ctx=fake_ctx) + network.creation_validation(ctx=fake_ctx, vca_client=None) if __name__ == '__main__': diff --git a/tests/unittests/test_mock_network_plugin_security_group.py b/tests/unittests/test_mock_network_plugin_security_group.py index 6c44e20..2588906 100644 --- a/tests/unittests/test_mock_network_plugin_security_group.py +++ b/tests/unittests/test_mock_network_plugin_security_group.py @@ -77,11 +77,10 @@ def check_rule_operation(self, rule_type, rules, vms_networks=None): gateway.delete_fw_rule = mock.MagicMock(return_value=None) # any networks will be routed self.set_network_routed_in_client(fake_client) - with mock.patch('vcloud_network_plugin.security_group.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - security_group._rule_operation( - rule_type, fake_client - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + security_group._rule_operation( + fake_ctx, rule_type, fake_client + ) return gateway def check_rule_operation_fail(self, rule_type, rules): @@ -96,11 +95,10 @@ def check_rule_operation_fail(self, rule_type, rules): self.set_services_conf_result( fake_client._vdc_gateway, None ) - with mock.patch('vcloud_network_plugin.security_group.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - self.assertFalse(security_group._rule_operation( - rule_type, fake_client - )) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + self.assertFalse(security_group._rule_operation( + fake_ctx, rule_type, fake_client + )) def test_rule_operation_empty_rule(self): for rule_type in [ @@ -412,22 +410,6 @@ def check_creation_validation(self, rule): security_group.creation_validation(ctx=fake_ctx, vca_client=None) - def test_create_node(self): - fake_client = self.generate_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - fake_ctx = self.generate_node_context_with_current_ctx( - properties={ - 'vcloud_config': { - 'edge_gateway': 'some_edge_gateway', - 'vdc': 'vdc_name' - } - } - ) - security_group.create_node(ctx=fake_ctx, vca_client=None) - def test_creation_validation(self): fake_client = self.generate_client() with mock.patch( diff --git a/tests/unittests/test_mock_server_plugin_server.py b/tests/unittests/test_mock_server_plugin_server.py index bf7cbfa..e46adeb 100644 --- a/tests/unittests/test_mock_server_plugin_server.py +++ b/tests/unittests/test_mock_server_plugin_server.py @@ -35,7 +35,7 @@ def test_delete_external_resource(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - server.delete(ctx=fake_ctx) + server.delete(ctx=fake_ctx, vca_client=None) self.assertFalse( server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties @@ -53,7 +53,7 @@ def test_delete(self): return_value=None ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.delete(ctx=fake_ctx) + server.delete(ctx=fake_ctx, vca_client=None) fake_client._vapp.delete.assert_called_with() self.check_get_vapp(fake_client, 'vapp_name') @@ -65,7 +65,7 @@ def test_delete(self): return_value=fake_task ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.delete(ctx=fake_ctx) + server.delete(ctx=fake_ctx, vca_client=None) # success fake_task = self.generate_task( @@ -74,7 +74,7 @@ def test_delete(self): fake_client._vapp.delete = mock.MagicMock( return_value=fake_task ) - server.delete(ctx=fake_ctx) + server.delete(ctx=fake_ctx, vca_client=None) self.assertFalse( server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties ) @@ -90,7 +90,7 @@ def test_stop_external_resource(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - server.stop(ctx=fake_ctx) + server.stop(ctx=fake_ctx, vca_client=None) self.assertTrue( server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties @@ -107,7 +107,7 @@ def test_stop(self): return_value=None ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.stop(ctx=fake_ctx) + server.stop(ctx=fake_ctx, vca_client=None) fake_client._vapp.undeploy.assert_called_with() self.check_get_vapp(fake_client, 'vapp_name') @@ -119,7 +119,7 @@ def test_stop(self): return_value=fake_task ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.stop(ctx=fake_ctx) + server.stop(ctx=fake_ctx, vca_client=None) # success fake_task = self.generate_task( @@ -128,7 +128,7 @@ def test_stop(self): fake_client._vapp.undeploy = mock.MagicMock( return_value=fake_task ) - server.stop(ctx=fake_ctx) + server.stop(ctx=fake_ctx, vca_client=None) self.assertTrue( server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties ) @@ -159,7 +159,7 @@ def test_start(self): return_value=None ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.start(ctx=fake_ctx) + server.start(ctx=fake_ctx, vca_client=None) fake_client._vapp.poweron.assert_called_with() self.check_get_vapp(fake_client, 'vapp_name') @@ -174,7 +174,7 @@ def test_start(self): return_value=fake_task ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.start(ctx=fake_ctx) + server.start(ctx=fake_ctx, vca_client=None) fake_client = self.generate_client([{ 'is_connected': False, @@ -196,13 +196,15 @@ def test_start(self): fake_client._vapp.poweron = mock.MagicMock( return_value=fake_task ) - self.assertEquals(server.start(ctx=fake_ctx), None) + self.assertEquals( + server.start(ctx=fake_ctx, vca_client=None), None) # poweron with success in task but not connected fake_client._vapp.me.get_status = mock.MagicMock( return_value=vcloud_plugin_common.STATUS_POWERED_OFF ) - self.assertEquals(server.start(ctx=fake_ctx), None) + self.assertEquals( + server.start(ctx=fake_ctx, vca_client=None), None) fake_client = self.generate_client([{ 'is_connected': True, @@ -218,7 +220,8 @@ def test_start(self): fake_client._vapp.me.get_status = mock.MagicMock( return_value=vcloud_plugin_common.STATUS_POWERED_ON ) - self.assertEquals(server.start(ctx=fake_ctx), None) + self.assertEquals( + server.start(ctx=fake_ctx, vca_client=None), None) # use external without any power state changes, run retry fake_ctx = self.generate_node_context_with_current_ctx() @@ -234,7 +237,7 @@ def test_start(self): mock.MagicMock(return_value=fake_client) ): self.prepare_retry(fake_ctx) - server.start(ctx=fake_ctx) + server.start(ctx=fake_ctx, vca_client=None) self.check_retry_realy_called( fake_ctx, "Waiting for VM's configuration to complete", 5 @@ -263,7 +266,8 @@ def test_start_external_resource(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - self.assertEquals(server.start(ctx=fake_ctx), None) + self.assertEquals( + server.start(ctx=fake_ctx, vca_client=None), None) def test_create_default_values(self): """ @@ -291,7 +295,7 @@ def test_create_default_values(self): ) fake_ctx.instance._relationships = None with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_configure_cpu_mem_values(self): @@ -317,7 +321,7 @@ def test_create_configure_cpu_mem_values(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) # can't get vapp fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -351,7 +355,7 @@ def test_create_configure_cpu_mem_values(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) # create new vm fake_client = self.generate_client() self.run_with_statuses( @@ -369,7 +373,7 @@ def test_create_configure_cpu_mem_values(self): ): # can't customize memory with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) fake_client._vapp.modify_vm_memory.assert_called_with( 'test', 512 ) @@ -381,7 +385,7 @@ def test_create_configure_cpu_mem_values(self): # can't customize cpu with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) fake_client._vapp.modify_vm_cpu.assert_called_with( 'test', 1 ) @@ -400,21 +404,21 @@ def test_create_configure_cpu_mem_values(self): fake_client._vapp.customize_on_next_poweron = mock.MagicMock( return_value=False ) - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) # somethin wrong with force_customization fake_client._vapp.force_customization = mock.MagicMock( return_value=None ) with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) # everything fine fake_client._vapp.customize_on_next_poweron = mock.MagicMock( return_value=True ) - server.configure(ctx=fake_ctx) - server.create(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) + server.create(ctx=fake_ctx, vca_client=None) fake_client._vapp.modify_vm_name.assert_called_with( 1, 'test' ) @@ -431,7 +435,7 @@ def test_create_configure_cpu_mem_values(self): 'time.sleep', sleep_mock ): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) sleep_mock.assert_called_with( vcloud_network_plugin.GATEWAY_TIMEOUT ) @@ -452,7 +456,7 @@ def test_create_configure_cpu_mem_values(self): 'time.sleep', sleep_mock ): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) def check_create_call(self, fake_client, fake_ctx, positive=True): fake_client.create_vapp.assert_called_with( @@ -571,7 +575,7 @@ def test_create_external_resource(self): 'vcloud_plugin_common.VcloudAirClient', self.generate_vca() ): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.assertTrue( server.VCLOUD_VAPP_NAME in fake_ctx.instance.runtime_properties ) @@ -597,7 +601,7 @@ def test_create_connection_error(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_cant_change_name(self): @@ -616,7 +620,7 @@ def test_create_cant_change_name(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_connection_empty_task(self): @@ -636,7 +640,7 @@ def test_create_connection_empty_task(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_cant_get_vapp(self): @@ -660,7 +664,7 @@ def test_create_cant_get_vapp(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) # use external resource fake_ctx.node.properties['use_external_resource'] = True @@ -670,7 +674,7 @@ def test_create_cant_get_vapp(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) def test_create_link_empty(self): """ @@ -690,7 +694,7 @@ def test_create_link_empty(self): ): # link empty with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_link_error(self): @@ -711,7 +715,7 @@ def test_create_link_error(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) self.check_create_call(fake_client, fake_ctx) def test_create_link_success(self): @@ -736,7 +740,7 @@ def test_create_link_success(self): vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) - server.create(ctx=fake_ctx) + server.create(ctx=fake_ctx, vca_client=None) def test_create_customization(self): """ @@ -756,7 +760,7 @@ def test_create_customization(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) def test_create_customization_error(self): """ @@ -777,7 +781,7 @@ def test_create_customization_error(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) def test_create_customization_un_customized(self): """ @@ -804,7 +808,7 @@ def test_create_customization_un_customized(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) def test_create_customization_customized(self): """ @@ -827,7 +831,7 @@ def test_create_customization_customized(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - server.configure(ctx=fake_ctx) + server.configure(ctx=fake_ctx, vca_client=None) if __name__ == '__main__': diff --git a/tests/unittests/test_mock_vcloud_plugin_common.py b/tests/unittests/test_mock_vcloud_plugin_common.py index 431143a..d7a21ef 100644 --- a/tests/unittests/test_mock_vcloud_plugin_common.py +++ b/tests/unittests/test_mock_vcloud_plugin_common.py @@ -240,7 +240,7 @@ def _some_function(vca_client, **kwargs): return vca_client self.assertEqual( - _some_function(ctx=fake_ctx), + _some_function(ctx=fake_ctx, vca_client=None), fake_client ) # context.DEPLOYMENT diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index f34099e..b6ec2de 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_mandatory, @@ -30,44 +29,32 @@ ACTIONS = ("allow", "deny") -@operation(resumable=True) -@with_vca_client -def create_node(vca_client, **kwargs): - """ - save properties on create step - """ - # combine properties - combine_properties( - ctx, kwargs=kwargs, names=['security_group'], - properties=['rules']) - - @operation(resumable=True) @with_vca_client @lock_gateway -def create(vca_client, **kwargs): +def create(ctx, vca_client, **kwargs): """ create firewall rules for node """ - if not _rule_operation(CREATE_RULE, vca_client): + if not _rule_operation(ctx, CREATE_RULE, vca_client): return set_retry(ctx) @operation(resumable=True) @with_vca_client @lock_gateway -def delete(vca_client, **kwargs): +def delete(ctx, vca_client, **kwargs): """ drop firewall rules for node """ - if not _rule_operation(DELETE_RULE, vca_client): + if not _rule_operation(ctx, DELETE_RULE, vca_client): return set_retry(ctx) delete_properties(ctx.target) @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ validate firewall rules for node """ @@ -124,7 +111,7 @@ def creation_validation(vca_client, **kwargs): "Parameter 'log_traffic' must be boolean.") -def _rule_operation(operation, vca_client): +def _rule_operation(ctx, operation, vca_client): """ create/delete firewall rules in gateway for current node """ From 884abbff89d155d032012b52078259a5e9277dd5 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 14:55:32 +0200 Subject: [PATCH 217/228] CYBL-979: Server: get rid of use static ctx --- ...est_mock_server_plugin_server_subroutes.py | 284 +++++++++--------- vcloud_server_plugin/server.py | 37 ++- 2 files changed, 160 insertions(+), 161 deletions(-) diff --git a/tests/unittests/test_mock_server_plugin_server_subroutes.py b/tests/unittests/test_mock_server_plugin_server_subroutes.py index fc4adeb..5f0b7cf 100644 --- a/tests/unittests/test_mock_server_plugin_server_subroutes.py +++ b/tests/unittests/test_mock_server_plugin_server_subroutes.py @@ -235,17 +235,16 @@ def test_isDhcpAvailable(self): ) current_ctx.set(fake_ctx) - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - self.assertEqual( - True, server._isDhcpAvailable(client, 'bridged') - ) - self.assertEqual( - False, server._isDhcpAvailable(client, 'local') - ) - self.assertEqual( - True, server._isDhcpAvailable(client, 'vdc_name') - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + self.assertEqual( + True, server._isDhcpAvailable(client, 'bridged') + ) + self.assertEqual( + False, server._isDhcpAvailable(client, 'local') + ) + self.assertEqual( + True, server._isDhcpAvailable(client, 'vdc_name') + ) def test_get_connected(self): @@ -288,35 +287,35 @@ def test_create_connections_list(self): } ) fake_client = self.generate_client() - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - connection = server._create_connections_list(fake_client) - self.assertEqual( - [ - { - 'network': 'private_network', - 'mac_address': 'hex', - 'ip_allocation_mode': 'POOL', - 'primary_interface': True, - 'ip_address': '1.1.1.1', - 'nic_order': 0 - }, { - 'network': 'some_network', - 'mac_address': None, - 'ip_allocation_mode': 'POOL', - 'primary_interface': False, - 'ip_address': None, - 'nic_order': 0 - }, { - 'network': '_management_network', - 'mac_address': None, - 'ip_allocation_mode': 'POOL', - 'primary_interface': False, - 'ip_address': None, - 'nic_order': 0 - } - ], connection - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + connection = server._create_connections_list( + ctx=fake_ctx, vca_client=fake_client) + self.assertEqual( + [ + { + 'network': 'private_network', + 'mac_address': 'hex', + 'ip_allocation_mode': 'POOL', + 'primary_interface': True, + 'ip_address': '1.1.1.1', + 'nic_order': 0 + }, { + 'network': 'some_network', + 'mac_address': None, + 'ip_allocation_mode': 'POOL', + 'primary_interface': False, + 'ip_address': None, + 'nic_order': 0 + }, { + 'network': '_management_network', + 'mac_address': None, + 'ip_allocation_mode': 'POOL', + 'primary_interface': False, + 'ip_address': None, + 'nic_order': 0 + } + ], connection + ) # get network name from first avaible but not primary fake_ctx = self.generate_node_context_with_current_ctx( relation_node_properties={ @@ -333,21 +332,21 @@ def test_create_connections_list(self): ) fake_client = self.generate_client() fake_ctx.node.properties['management_network'] = None - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - connection = server._create_connections_list(fake_client) - self.assertEqual( - [ - { - 'ip_address': '1.1.1.1', - 'ip_allocation_mode': 'POOL', - 'mac_address': 'hex', - 'network': 'private_network', - 'primary_interface': True, - 'nic_order': 0 - } - ], connection - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + connection = server._create_connections_list( + ctx=fake_ctx, vca_client=fake_client) + self.assertEqual( + [ + { + 'ip_address': '1.1.1.1', + 'ip_allocation_mode': 'POOL', + 'mac_address': 'hex', + 'network': 'private_network', + 'primary_interface': True, + 'nic_order': 0 + } + ], connection + ) # no connections fake_ctx = self.generate_node_context_with_current_ctx( relation_node_properties={ @@ -356,10 +355,10 @@ def test_create_connections_list(self): ) fake_client = self.generate_client() fake_ctx.node.properties['management_network'] = None - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - connection = server._create_connections_list(fake_client) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + with self.assertRaises(cfy_exc.NonRecoverableError): + server._create_connections_list(ctx=fake_ctx, + vca_client=fake_client) # one network same as managment + port fake_ctx = self.generate_node_context_with_current_ctx( relation_node_properties={ @@ -377,29 +376,29 @@ def test_create_connections_list(self): } } ) - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - connection = server._create_connections_list(fake_client) - self.assertEqual( - [ - { - 'ip_address': '1.1.1.1', - 'ip_allocation_mode': 'POOL', - 'mac_address': 'hex', - 'network': '_management_network', - 'primary_interface': True, - 'nic_order': 0 - }, - { - 'ip_address': None, - 'ip_allocation_mode': 'POOL', - 'mac_address': None, - 'network': 'some_network', - 'primary_interface': False, - 'nic_order': 0 - } - ], connection - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + connection = server._create_connections_list( + ctx=fake_ctx, vca_client=fake_client) + self.assertEqual( + [ + { + 'ip_address': '1.1.1.1', + 'ip_allocation_mode': 'POOL', + 'mac_address': 'hex', + 'network': '_management_network', + 'primary_interface': True, + 'nic_order': 0 + }, + { + 'ip_address': None, + 'ip_allocation_mode': 'POOL', + 'mac_address': None, + 'network': 'some_network', + 'primary_interface': False, + 'nic_order': 0 + } + ], connection + ) # check dhcp, with no dhcp server fake_ctx = self.generate_node_context(relation_node_properties={ "not_test": "not_test", @@ -418,25 +417,25 @@ def test_create_connections_list(self): # we support case when with dhcpd on vm inside network # instead use gateway service, # look to cc676430a1e06e9ac2fd8d0a56b9a414d3232939 - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - server._create_connections_list(fake_client) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + server._create_connections_list(ctx=fake_ctx, + vca_client=fake_client) # only managment node fake_ctx.instance._relationships = [] - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - connection = server._create_connections_list(fake_client) - self.assertEqual( - [{ - 'ip_address': None, - 'ip_allocation_mode': 'POOL', - 'mac_address': None, - 'network': '_management_network', - 'primary_interface': True, - 'nic_order': 0 - }], - connection - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + connection = server._create_connections_list( + ctx=fake_ctx, vca_client=fake_client) + self.assertEqual( + [{ + 'ip_address': None, + 'ip_allocation_mode': 'POOL', + 'mac_address': None, + 'network': '_management_network', + 'primary_interface': True, + 'nic_order': 0 + }], + connection + ) # no networks fake_ctx.instance._relationships = [] @@ -444,10 +443,10 @@ def _generate_fake_client_network(vdc_name, network_name): return None fake_client.get_network = _generate_fake_client_network - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - server._create_connections_list(fake_client) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + with self.assertRaises(cfy_exc.NonRecoverableError): + server._create_connections_list(ctx=fake_ctx, + vca_client=fake_client) def test_get_vm_network_connections(self): # one connection from port, one from network and @@ -509,39 +508,42 @@ def test_get_vm_network_connection(self): def test_get_state(self): fake_ctx = self.generate_node_context_with_current_ctx() - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - # connected network_name - fake_client = self.generate_client([{ - 'is_connected': True, - 'is_primary': False, - 'network_name': 'network_name', - 'ip': '1.1.1.1' - }]) - self.assertFalse(server._get_state(fake_client)) - # not connected network_name - fake_client = self.generate_client([{ - 'is_connected': False, - 'network_name': 'network_name', - 'ip': '1.1.1.1' - }]) - self.assertTrue(server._get_state(fake_client)) - # not ip in connected network_name - fake_client = self.generate_client([{ - 'is_connected': True, - 'is_primary': False, - 'network_name': 'network_name', - 'ip': None - }]) - self.assertFalse(server._get_state(fake_client)) - # with managment_network - fake_client = self.generate_client([{ - 'is_connected': True, - 'is_primary': True, - 'network_name': '_management_network', - 'ip': '1.1.1.1' - }]) - self.assertTrue(server._get_state(fake_client)) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + # connected network_name + fake_client = self.generate_client([{ + 'is_connected': True, + 'is_primary': False, + 'network_name': 'network_name', + 'ip': '1.1.1.1' + }]) + self.assertFalse(server._get_state(ctx=fake_ctx, + vca_client=fake_client)) + # not connected network_name + fake_client = self.generate_client([{ + 'is_connected': False, + 'network_name': 'network_name', + 'ip': '1.1.1.1' + }]) + self.assertTrue(server._get_state(ctx=fake_ctx, + vca_client=fake_client)) + # not ip in connected network_name + fake_client = self.generate_client([{ + 'is_connected': True, + 'is_primary': False, + 'network_name': 'network_name', + 'ip': None + }]) + self.assertFalse(server._get_state(ctx=fake_ctx, + vca_client=fake_client)) + # with managment_network + fake_client = self.generate_client([{ + 'is_connected': True, + 'is_primary': True, + 'network_name': '_management_network', + 'ip': '1.1.1.1' + }]) + self.assertTrue(server._get_state(ctx=fake_ctx, + vca_client=fake_client)) def test_add_key_script(self): commands = [] @@ -559,17 +561,15 @@ def test_get_connected_keypairs(self): # empty list of relationships fake_ctx = self.generate_node_context_with_current_ctx() fake_ctx.instance._relationships = None - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - self.assertEqual([], server._get_connected_keypairs()) + self.assertEqual([], server._get_connected_keypairs(ctx=fake_ctx)) # exist some content relationship = self.generate_relation_context() runtime_properties = {'public_key': "a"} relationship.target.instance.runtime_properties = runtime_properties fake_ctx.instance._relationships = [relationship] - with mock.patch('vcloud_server_plugin.server.ctx', fake_ctx): - self.assertEqual( - server._get_connected_keypairs(), ["a"] - ) + self.assertEqual( + server._get_connected_keypairs(ctx=fake_ctx), ["a"] + ) def test_is_primary_connection_has_ip(self): # no network info at all diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 313aa61..0abb47e 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -14,7 +14,6 @@ import time -from cloudify import ctx from cloudify.decorators import operation from cloudify import exceptions as cfy_exc @@ -41,7 +40,7 @@ @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ validate server settings, look to template in catalog """ @@ -90,7 +89,7 @@ def get_template(catalog, template_name): @operation(resumable=True) @with_vca_client -def create(vca_client, **kwargs): +def create(ctx, vca_client, **kwargs): """ create server by template, if external_resource set return without creation, @@ -133,10 +132,10 @@ def create(vca_client, **kwargs): ctx.logger.info( "External resource {0} has been used".format(res_id)) else: - _create(vca_client, config, server) + _create(ctx, vca_client, config, server) -def _create(vca_client, config, server): +def _create(ctx, vca_client, config, server): """ create server by template, customize: @@ -147,7 +146,7 @@ def _create(vca_client, config, server): vapp_name = server['name'] vapp_template = server['template'] vapp_catalog = server['catalog'] - connections = _create_connections_list(vca_client) + connections = _create_connections_list(ctx, vca_client) ctx.logger.info("Creating VApp with parameters: {0}".format(server)) task = vca_client.create_vapp(config['vdc'], vapp_name, @@ -214,7 +213,7 @@ def _create(vca_client, config, server): wait_for_task(vca_client, task) -def _power_on_vm(vca_client, vapp, vapp_name): +def _power_on_vm(ctx, vca_client, vapp, vapp_name): """Poweron VM""" if _vapp_is_on(vapp) is False: ctx.logger.info("Power-on VApp {0}".format(vapp_name)) @@ -228,7 +227,7 @@ def _power_on_vm(vca_client, vapp, vapp_name): @operation(resumable=True) @with_vca_client -def start(vca_client, **kwargs): +def start(ctx, vca_client, **kwargs): """ power on server and wait network connection availability for host """ @@ -245,9 +244,9 @@ def start(vca_client, **kwargs): config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) - _power_on_vm(vca_client, vapp, vapp_name) + _power_on_vm(ctx, vca_client, vapp, vapp_name) - if not _get_state(vca_client): + if not _get_state(ctx=ctx, vca_client=vca_client): return ctx.operation.retry( message="Waiting for VM's configuration to complete", retry_after=5) @@ -255,7 +254,7 @@ def start(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def stop(vca_client, **kwargs): +def stop(ctx, vca_client, **kwargs): """ poweroff server, if external resource - server stay poweroned """ @@ -282,7 +281,7 @@ def stop(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def delete(vca_client, **kwargs): +def delete(ctx, vca_client, **kwargs): """ delete server """ @@ -326,7 +325,7 @@ def _is_primary_connection_has_ip(vapp): @operation(resumable=True) @with_vca_client -def configure(vca_client, **kwargs): +def configure(ctx, vca_client, **kwargs): # combine properties obj = combine_properties( ctx, kwargs=kwargs, names=['server'], @@ -344,7 +343,7 @@ def configure(vca_client, **kwargs): vapp_name = server['name'] config = get_vcloud_config() custom = server.get(GUEST_CUSTOMIZATION, {}) - public_keys = _get_connected_keypairs() + public_keys = _get_connected_keypairs(ctx) vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) @@ -421,7 +420,7 @@ def configure(vca_client, **kwargs): if not _is_primary_connection_has_ip(vapp): ctx.logger.info("Power on server for get dhcp ip.") # we have to start vapp before continue - _power_on_vm(vca_client, vapp, vapp_name) + _power_on_vm(ctx, vca_client, vapp, vapp_name) for attempt in xrange(RETRY_COUNT): vapp = vca_client.get_vapp(vdc, vapp_name) if _is_primary_connection_has_ip(vapp): @@ -436,7 +435,7 @@ def configure(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def remove_keys(vca_client, **kwargs): +def remove_keys(ctx, vca_client, **kwargs): ctx.logger.info("Remove public keys from VM.") relationships = getattr(ctx.target.instance, 'relationships', None) if relationships: @@ -506,7 +505,7 @@ def _remove_key_script(commands, user, ssh_dir, keys_file, public_key): ) -def _get_state(vca_client): +def _get_state(ctx, vca_client): """ check network connection availability for host """ @@ -599,7 +598,7 @@ def _build_script(custom, public_keys): return script -def _get_connected_keypairs(): +def _get_connected_keypairs(ctx): """ return public keys connected to node """ @@ -660,7 +659,7 @@ def _build_public_keys_script(public_keys, script_function): return "\n".join(key_commands) -def _create_connections_list(vca_client): +def _create_connections_list(ctx, vca_client): """ return full list connections for node """ From 649a123a4c163ee211b64bc379fd8576bcebf80a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 15:11:45 +0200 Subject: [PATCH 218/228] CYBL-979: Port: get rid of use static ctx --- plugin.yaml | 20 +++++++++++-------- .../test_mock_network_plugin_port.py | 12 ----------- vcloud_network_plugin/port.py | 11 ++-------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index ff78137..0edda64 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -41,6 +41,7 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_server_plugin.server.creation_validation + inputs: {} cloudify.vcloud.nodes.Network: derived_from: cloudify.nodes.Network @@ -64,6 +65,7 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_network_plugin.network.creation_validation + inputs: {} cloudify.vcloud.nodes.Port: derived_from: cloudify.nodes.Port @@ -75,14 +77,11 @@ node_types: interfaces: cloudify.interfaces.lifecycle: create: - implementation: vcloud.vcloud_network_plugin.port.create + implementation: vcloud.vcloud_network_plugin.port.creation_validation inputs: {} delete: implementation: vcloud.vcloud_network_plugin.port.delete inputs: {} - cloudify.interfaces.validation: - creation: - implementation: vcloud.vcloud_network_plugin.port.creation_validation cloudify.vcloud.nodes.FloatingIP: derived_from: cloudify.nodes.VirtualIP @@ -92,9 +91,10 @@ node_types: vcloud_config: default: {} interfaces: - cloudify.interfaces.validation: - creation: + cloudify.interfaces.lifecycle: + create: implementation: vcloud.vcloud_network_plugin.floatingip.creation_validation + inputs: {} cloudify.vcloud.nodes.PublicNAT: derived_from: cloudify.nodes.VirtualIP @@ -108,9 +108,10 @@ node_types: vcloud_config: default: {} interfaces: - cloudify.interfaces.validation: - creation: + cloudify.interfaces.lifecycle: + create: implementation: vcloud.vcloud_network_plugin.public_nat.creation_validation + inputs: {} cloudify.vcloud.nodes.SecurityGroup: derived_from: cloudify.nodes.SecurityGroup @@ -140,6 +141,7 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_network_plugin.keypair.creation_validation + inputs: {} cloudify.interfaces.lifecycle: create: implementation: vcloud.vcloud_network_plugin.keypair.create @@ -172,6 +174,7 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_storage_plugin.volume.creation_validation + inputs: {} cloudify.vcloud.nodes.VDC: derived_from: cloudify.nodes.Root @@ -195,6 +198,7 @@ node_types: cloudify.interfaces.validation: creation: implementation: vcloud.vcloud_server_plugin.vdc.creation_validation + inputs: {} relationships: diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index b379b6c..6e15d50 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -22,18 +22,6 @@ class NetworkPluginPortMockTestCase(test_mock_base.TestBase): - def test_create(self): - fake_client = self.generate_client() - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - # no port - fake_ctx = self.generate_node_context_with_current_ctx( - properties={} - ) - port.create(ctx=fake_ctx) - def test_delete(self): fake_client = self.generate_client() with mock.patch( diff --git a/vcloud_network_plugin/port.py b/vcloud_network_plugin/port.py index 091bbe2..470e1aa 100644 --- a/vcloud_network_plugin/port.py +++ b/vcloud_network_plugin/port.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_mandatory, @@ -22,7 +21,7 @@ @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ validate port settings, ip_allocation_mode must be in 'manual', 'dhcp', 'pool', @@ -44,11 +43,5 @@ def creation_validation(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def create(vca_client, **kwargs): - combine_properties(ctx, kwargs=kwargs, names=['port']) - - -@operation(resumable=True) -@with_vca_client -def delete(vca_client, **kwargs): +def delete(ctx, vca_client, **kwargs): delete_properties(ctx) From 90cb93e154b2cb20bc49e6b63f73be6d12a26069 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 15:49:10 +0200 Subject: [PATCH 219/228] CYBL-979: FloatingIP: get rid of use static ctx --- .../test_mock_network_plugin_floatingip.py | 142 +++++++----------- .../test_mock_network_plugin_port.py | 14 +- .../unittests/test_mock_server_plugin_vdc.py | 30 ++-- .../test_mock_storage_plugin_volume.py | 30 ++-- vcloud_network_plugin/floatingip.py | 15 +- 5 files changed, 101 insertions(+), 130 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_floatingip.py b/tests/unittests/test_mock_network_plugin_floatingip.py index 26ae4d3..7aa338c 100644 --- a/tests/unittests/test_mock_network_plugin_floatingip.py +++ b/tests/unittests/test_mock_network_plugin_floatingip.py @@ -27,54 +27,50 @@ class NetworkPluginFloatingIpMockTestCase(test_mock_base.TestBase): def test_add_nat_rule_snat(self): fake_ctx = self.generate_node_context_with_current_ctx() - with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): - gateway = mock.Mock() - gateway._add_nat_rule = mock.MagicMock(return_value=None) - floatingip._add_nat_rule( - gateway, 'SNAT', 'internal', 'external' - ) - gateway.add_nat_rule.assert_called_with( - 'SNAT', 'internal', 'any', 'external', 'any', 'any' - ) + gateway = mock.Mock() + gateway._add_nat_rule = mock.MagicMock(return_value=None) + floatingip._add_nat_rule( + fake_ctx, gateway, 'SNAT', 'internal', 'external' + ) + gateway.add_nat_rule.assert_called_with( + 'SNAT', 'internal', 'any', 'external', 'any', 'any' + ) def test_add_nat_rule_dnat(self): fake_ctx = self.generate_node_context_with_current_ctx() - with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): - gateway = mock.Mock() - gateway._add_nat_rule = mock.MagicMock(return_value=None) - floatingip._add_nat_rule( - gateway, 'DNAT', 'internal', 'external' - ) - gateway.add_nat_rule.assert_called_with( - 'DNAT', 'internal', 'any', 'external', 'any', 'any' - ) + gateway = mock.Mock() + gateway._add_nat_rule = mock.MagicMock(return_value=None) + floatingip._add_nat_rule( + fake_ctx, gateway, 'DNAT', 'internal', 'external' + ) + gateway.add_nat_rule.assert_called_with( + 'DNAT', 'internal', 'any', 'external', 'any', 'any' + ) def test_del_nat_rule_snat(self): fake_ctx = self.generate_node_context_with_current_ctx() - with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): - gateway = mock.Mock() - gateway.del_nat_rule = mock.MagicMock(return_value=None) - floatingip._del_nat_rule( - gateway, 'SNAT', 'internal', 'external' - ) - gateway.del_nat_rule.assert_called_with( - 'SNAT', 'internal', 'any', 'external', 'any', 'any' - ) + gateway = mock.Mock() + gateway.del_nat_rule = mock.MagicMock(return_value=None) + floatingip._del_nat_rule( + fake_ctx, gateway, 'SNAT', 'internal', 'external' + ) + gateway.del_nat_rule.assert_called_with( + 'SNAT', 'internal', 'any', 'external', 'any', 'any' + ) def test_del_nat_rule_dnat(self): fake_ctx = self.generate_node_context_with_current_ctx() - with mock.patch('vcloud_network_plugin.floatingip.ctx', fake_ctx): - gateway = mock.Mock() - gateway.del_nat_rule = mock.MagicMock(return_value=None) - floatingip._del_nat_rule( - gateway, 'DNAT', 'internal', 'external' - ) - gateway.del_nat_rule.assert_called_with( - 'DNAT', 'internal', 'any', 'external', 'any', 'any' - ) + gateway = mock.Mock() + gateway.del_nat_rule = mock.MagicMock(return_value=None) + floatingip._del_nat_rule( + fake_ctx, gateway, 'DNAT', 'internal', 'external' + ) + gateway.del_nat_rule.assert_called_with( + 'DNAT', 'internal', 'any', 'external', 'any', 'any' + ) def test_creation_validation(self): fake_client = self.generate_client() @@ -224,12 +220,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - floatingip._floatingip_operation( - vcloud_network_plugin.DELETE, fake_client, fake_ctx - ) + floatingip._floatingip_operation( + vcloud_network_plugin.DELETE, fake_client, ctx=fake_ctx + ) # busy in save with ip in node_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() self.set_services_conf_result( @@ -246,12 +239,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - self.assertFalse(floatingip._floatingip_operation( - vcloud_network_plugin.DELETE, fake_client, fake_ctx - )) + self.assertFalse(floatingip._floatingip_operation( + vcloud_network_plugin.DELETE, fake_client, ctx=fake_ctx + )) # busy in save with ip in runtime_properties fake_client, fake_ctx = self.generate_client_and_context_floating_ip() self.set_services_conf_result( @@ -270,12 +260,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - self.assertFalse(floatingip._floatingip_operation( - vcloud_network_plugin.DELETE, fake_client, fake_ctx - )) + self.assertFalse(floatingip._floatingip_operation( + vcloud_network_plugin.DELETE, fake_client, ctx=fake_ctx + )) # unknow operation fake_client, fake_ctx = self.generate_client_and_context_floating_ip() fake_ctx._target.node.properties = { @@ -287,13 +274,10 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - floatingip._floatingip_operation( - "unknow", fake_client, fake_ctx - ) + with self.assertRaises(cfy_exc.NonRecoverableError): + floatingip._floatingip_operation( + "unknow", fake_client, ctx=fake_ctx + ) # delete to end, ondemand fake_client, fake_ctx = self.generate_client_and_context_floating_ip() fake_ctx._target.node.properties = { @@ -318,12 +302,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - floatingip._floatingip_operation( - vcloud_network_plugin.DELETE, fake_client, fake_ctx - ) + floatingip._floatingip_operation( + vcloud_network_plugin.DELETE, fake_client, ctx=fake_ctx + ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( vcloud_network_plugin.PUBLIC_IP in runtime_properties @@ -353,12 +334,9 @@ def test_floatingip_operation_delete(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - floatingip._floatingip_operation( - vcloud_network_plugin.DELETE, fake_client, fake_ctx - ) + floatingip._floatingip_operation( + vcloud_network_plugin.DELETE, fake_client, ctx=fake_ctx + ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertFalse( vcloud_network_plugin.PUBLIC_IP in runtime_properties @@ -496,12 +474,9 @@ def test_floatingip_operation_create(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - floatingip._floatingip_operation( - vcloud_network_plugin.CREATE, fake_client, fake_ctx - ) + floatingip._floatingip_operation( + vcloud_network_plugin.CREATE, fake_client, ctx=fake_ctx + ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( vcloud_network_plugin.PUBLIC_IP in runtime_properties @@ -533,12 +508,9 @@ def test_floatingip_operation_create(self): with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_network_plugin.floatingip.ctx', fake_ctx - ): - floatingip._floatingip_operation( - vcloud_network_plugin.CREATE, fake_client, fake_ctx - ) + floatingip._floatingip_operation( + vcloud_network_plugin.CREATE, fake_client, ctx=fake_ctx + ) runtime_properties = fake_ctx._target.instance.runtime_properties self.assertTrue( vcloud_network_plugin.PUBLIC_IP in runtime_properties diff --git a/tests/unittests/test_mock_network_plugin_port.py b/tests/unittests/test_mock_network_plugin_port.py index 6e15d50..8040aca 100644 --- a/tests/unittests/test_mock_network_plugin_port.py +++ b/tests/unittests/test_mock_network_plugin_port.py @@ -32,7 +32,7 @@ def test_delete(self): fake_ctx = self.generate_node_context_with_current_ctx( properties={} ) - port.delete(ctx=fake_ctx) + port.delete(ctx=fake_ctx, vca_client=None) def test_creation_validation(self): fake_client = self.generate_client() @@ -45,7 +45,7 @@ def test_creation_validation(self): properties={} ) with self.assertRaises(cfy_exc.NonRecoverableError): - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) # port without allocation fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -54,7 +54,7 @@ def test_creation_validation(self): } } ) - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) # wrong allocation mode fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -64,7 +64,7 @@ def test_creation_validation(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) # correct allocation for mode in ['manual', 'dhcp', 'pool']: fake_ctx = self.generate_node_context_with_current_ctx( @@ -74,7 +74,7 @@ def test_creation_validation(self): } } ) - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) # wrong manual ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -85,7 +85,7 @@ def test_creation_validation(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) # correct manual ip fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -95,7 +95,7 @@ def test_creation_validation(self): } } ) - port.creation_validation(ctx=fake_ctx) + port.creation_validation(ctx=fake_ctx, vca_client=None) if __name__ == '__main__': diff --git a/tests/unittests/test_mock_server_plugin_vdc.py b/tests/unittests/test_mock_server_plugin_vdc.py index a10d9e7..ea70a63 100644 --- a/tests/unittests/test_mock_server_plugin_vdc.py +++ b/tests/unittests/test_mock_server_plugin_vdc.py @@ -34,7 +34,7 @@ def test_creation_validation(self): ) # no vdc name with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) # name exist but someone already created this vdc fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -45,11 +45,11 @@ def test_creation_validation(self): return_value=mock.MagicMock() ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_vdc.assert_called_with('not_existed') # everthing fine fake_client.get_vdc = mock.MagicMock(return_value=None) - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) # external but without name fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -57,7 +57,7 @@ def test_creation_validation(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) # use unexisted vdc fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -67,13 +67,13 @@ def test_creation_validation(self): ) fake_client.get_vdc = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_vdc.assert_called_with('not_existed') # exist everything fake_client.get_vdc = mock.MagicMock( return_value=mock.MagicMock() ) - vdc.creation_validation(ctx=fake_ctx) + vdc.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_vdc.assert_called_with('not_existed') def test_create(self): @@ -93,7 +93,7 @@ def test_create(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) # use ondemand # use external resource without vdc fake_ctx = self.generate_node_context_with_current_ctx( @@ -108,13 +108,13 @@ def test_create(self): ) fake_client.get_vdc = mock.MagicMock(return_value=None) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) fake_client.get_vdc.assert_called_with('not_existed') # successful for create on external resource fake_client.get_vdc = mock.MagicMock( return_value=mock.MagicMock() ) - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) # no name for vdc fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -126,7 +126,7 @@ def test_create(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) # create new vdc for deployment fake_ctx = self.generate_node_context_with_current_ctx( properties={ @@ -143,14 +143,14 @@ def test_create(self): return_value=None ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) # everything fine fake_client.create_vdc = mock.MagicMock( return_value=self.generate_task( vcloud_plugin_common.TASK_STATUS_SUCCESS ) ) - vdc.create(ctx=fake_ctx) + vdc.create(ctx=fake_ctx, vca_client=None) def test_delete(self): """check vdc deletion operation""" @@ -170,7 +170,7 @@ def test_delete(self): 'resource_id': 'not_existed' } ) - vdc.delete(ctx=fake_ctx) + vdc.delete(ctx=fake_ctx, vca_client=None) # return fail from delete vdc fake_client.delete_vdc = mock.MagicMock( return_value=(False, None) @@ -189,7 +189,7 @@ def test_delete(self): } ) with self.assertRaises(cfy_exc.NonRecoverableError): - vdc.delete(ctx=fake_ctx) + vdc.delete(ctx=fake_ctx, vca_client=None) fake_client.delete_vdc.assert_called_with("something") self.assertTrue( vdc.VDC_NAME in fake_ctx.instance.runtime_properties @@ -200,7 +200,7 @@ def test_delete(self): vcloud_plugin_common.TASK_STATUS_SUCCESS )) ) - vdc.delete(ctx=fake_ctx) + vdc.delete(ctx=fake_ctx, vca_client=None) self.assertFalse( vdc.VDC_NAME in fake_ctx.instance.runtime_properties ) diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index fae6bad..f077d5d 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -48,7 +48,7 @@ def test_creation_validation_external_resource(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_disks.assert_called_with('vdc_name') # with resource id, but without disks(no disks for this client) fake_ctx = cfy_mocks.MockCloudifyContext( @@ -68,7 +68,7 @@ def test_creation_validation_external_resource(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) # good case for external resource fake_client.get_disks = mock.MagicMock(return_value=[ [ @@ -80,7 +80,7 @@ def test_creation_validation_external_resource(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) def test_creation_validation_internal(self): fake_client = self.generate_client() @@ -102,7 +102,7 @@ def test_creation_validation_internal(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) fake_client.get_disks.assert_called_with('vdc_name') # internal resource wit volume and name, # but already exist such volume @@ -131,7 +131,7 @@ def test_creation_validation_internal(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) # correct name but without size fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', @@ -152,7 +152,7 @@ def test_creation_validation_internal(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) # good case fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', @@ -173,7 +173,7 @@ def test_creation_validation_internal(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.creation_validation(ctx=fake_ctx) + volume.creation_validation(ctx=fake_ctx, vca_client=None) def test_delete_volume(self): fake_client = self.generate_client() @@ -193,7 +193,7 @@ def test_delete_volume(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.delete_volume(ctx=fake_ctx) + volume.delete_volume(ctx=fake_ctx, vca_client=None) # cant't add disk fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', @@ -215,7 +215,7 @@ def test_delete_volume(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.delete_volume(ctx=fake_ctx) + volume.delete_volume(ctx=fake_ctx, vca_client=None) fake_client.delete_disk.assert_called_with( 'vdc_name', 'some-other' ) @@ -231,7 +231,7 @@ def test_delete_volume(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.delete_volume(ctx=fake_ctx) + volume.delete_volume(ctx=fake_ctx, vca_client=None) def test_create_volume(self): fake_client = self.generate_client() @@ -251,7 +251,7 @@ def test_create_volume(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.create_volume(ctx=fake_ctx) + volume.create_volume(ctx=fake_ctx, vca_client=None) # fail on create volume fake_ctx = cfy_mocks.MockCloudifyContext( node_id='test', @@ -273,7 +273,7 @@ def test_create_volume(self): mock.MagicMock(return_value=fake_client) ): with self.assertRaises(cfy_exc.NonRecoverableError): - volume.create_volume(ctx=fake_ctx) + volume.create_volume(ctx=fake_ctx, vca_client=None) fake_client.add_disk.assert_called_with( 'vdc_name', 'some-other', 11534336 ) @@ -291,7 +291,7 @@ def test_create_volume(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.create_volume(ctx=fake_ctx) + volume.create_volume(ctx=fake_ctx, vca_client=None) def test_volume_operation(self): fake_ctx, fake_client = self._gen_volume_context_and_client() @@ -397,7 +397,7 @@ def test_attach_volume(self): 'vcloud_storage_plugin.volume._wait_for_boot', mock.MagicMock() ): - volume.attach_volume(ctx=fake_ctx) + volume.attach_volume(ctx=fake_ctx, vca_client=None) def test_detach_volume(self): """ @@ -408,7 +408,7 @@ def test_detach_volume(self): 'vcloud_plugin_common.VcloudAirClient.get', mock.MagicMock(return_value=fake_client) ): - volume.detach_volume(ctx=fake_ctx) + volume.detach_volume(ctx=fake_ctx, vca_client=None) @unittest.skip("Fabric changed api, skip for now") def run_wait_boot(self, fabric_settings, fabric_run, ctx, sleep_call=True): diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index eb64c47..916537a 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, @@ -31,7 +30,7 @@ @operation(resumable=True) @with_vca_client @lock_gateway -def connect_floatingip(vca_client, **kwargs): +def connect_floatingip(ctx, vca_client, **kwargs): """ create new floating ip for node """ @@ -42,7 +41,7 @@ def connect_floatingip(vca_client, **kwargs): @operation(resumable=True) @with_vca_client @lock_gateway -def disconnect_floatingip(vca_client, **kwargs): +def disconnect_floatingip(ctx, vca_client, **kwargs): """ release floating ip """ @@ -52,7 +51,7 @@ def disconnect_floatingip(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ validate node context, fields from floatingip dict: @@ -119,8 +118,8 @@ def _floatingip_operation(operation, vca_client, ctx): external_ip = check_ip(public_ip) - nat_operation(gateway, "SNAT", internal_ip, external_ip) - nat_operation(gateway, "DNAT", external_ip, internal_ip) + nat_operation(ctx, gateway, "SNAT", internal_ip, external_ip) + nat_operation(ctx, gateway, "DNAT", external_ip, internal_ip) success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False @@ -144,7 +143,7 @@ def _floatingip_operation(operation, vca_client, ctx): return True -def _add_nat_rule(gateway, rule_type, original_ip, translated_ip): +def _add_nat_rule(ctx, gateway, rule_type, original_ip, translated_ip): """ add nat rule with enable any types of trafic from translated_ip to origin_ip @@ -159,7 +158,7 @@ def _add_nat_rule(gateway, rule_type, original_ip, translated_ip): rule_type, original_ip, any_type, translated_ip, any_type, any_type) -def _del_nat_rule(gateway, rule_type, original_ip, translated_ip): +def _del_nat_rule(ctx, gateway, rule_type, original_ip, translated_ip): """ drop rule created by add_nat_rule """ From a18a69433b2d4de73ad1fa0f977113d5c5b0c1c1 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 16:32:50 +0200 Subject: [PATCH 220/228] CYBL-979: PublicNat: get rid of use static ctx --- .../test_mock_network_plugin_public_nat.py | 480 ++++++++---------- vcloud_network_plugin/public_nat.py | 55 +- vcloud_server_plugin/vdc.py | 7 +- 3 files changed, 237 insertions(+), 305 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 22aaa41..7f3b144 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -49,13 +49,11 @@ def test_get_original_port_for_delete(self): fake_ctx._target.instance.runtime_properties = { public_nat.PORT_REPLACEMENT: {}} - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertEqual( - public_nat._get_original_port_for_delete("10.1.1.1", "11"), - "11" - ) + self.assertEqual( + public_nat._get_original_port_for_delete( + fake_ctx, "10.1.1.1", "11"), + "11" + ) # replacement for other fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { @@ -63,13 +61,11 @@ def test_get_original_port_for_delete(self): "10.1.1.2:11": '12' } } - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertEqual( - public_nat._get_original_port_for_delete("10.1.1.1", "11"), - "11" - ) + self.assertEqual( + public_nat._get_original_port_for_delete( + fake_ctx, "10.1.1.1", "11"), + "11" + ) # replacement for other fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx._target.instance.runtime_properties = { @@ -77,13 +73,11 @@ def test_get_original_port_for_delete(self): "10.1.1.2:11": '12' } } - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertEqual( - public_nat._get_original_port_for_delete("10.1.1.2", "11"), - "12" - ) + self.assertEqual( + public_nat._get_original_port_for_delete( + fake_ctx, "10.1.1.2", "11"), + "12" + ) def test_get_original_port_for_create(self): gateway = mock.Mock() @@ -91,26 +85,26 @@ def test_get_original_port_for_create(self): rule_inlist = self.generate_nat_rule( 'DNAT', 'external', 'any', 'internal', '11', 'TCP') gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - # exeption about same port - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat._get_original_port_for_create( - gateway, 'DNAT', 'external', 'any', 'internal', '11', 'TCP' - ) - # everythiong fine with different port - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'DNAT', 'external', '12', 'internal', '12', 'TCP' - ), - 12) - # relink some port to other - # port have not used yet - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', 13, 'internal', '12', 'TCP'), - 13) + # exeption about same port + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'DNAT', 'external', 'any', 'internal', + '11', 'TCP' + ) + # everythiong fine with different port + self.assertEqual( + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'DNAT', 'external', '12', 'internal', + '12', 'TCP' + ), + 12) + # relink some port to other + # port have not used yet + self.assertEqual( + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'SNAT', 'external', 13, 'internal', + '12', 'TCP'), + 13) def test_get_original_port_for_create_with_ctx(self): # with replace, but without replace table - up port +1 @@ -123,42 +117,38 @@ def test_get_original_port_for_create_with_ctx(self): 'SNAT', 'external', 10, 'internal', 11, 'TCP' ) gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', '10', 'internal', '11', 'TCP' - ), - 11 - ) - self.assertEqual( - fake_ctx._target.instance.runtime_properties, - { - public_nat.PORT_REPLACEMENT: { - 'external:10': 11 - } + self.assertEqual( + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'SNAT', 'external', '10', 'internal', + '11', 'TCP' + ), + 11 + ) + self.assertEqual( + fake_ctx._target.instance.runtime_properties, + { + public_nat.PORT_REPLACEMENT: { + 'external:10': 11 } - ) + } + ) # same but without replacement at all fake_ctx._target.instance.runtime_properties = {} - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertEqual( - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', '10', 'internal', '11', 'TCP' - ), - 11 - ) - self.assertEqual( - fake_ctx._target.instance.runtime_properties, - { - public_nat.PORT_REPLACEMENT: { - 'external:10': 11 - } + self.assertEqual( + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'SNAT', 'external', '10', 'internal', + '11', 'TCP' + ), + 11 + ) + self.assertEqual( + fake_ctx._target.instance.runtime_properties, + { + public_nat.PORT_REPLACEMENT: { + 'external:10': 11 } - ) + } + ) # we dont have enought ports rule_inlist = self.generate_nat_rule( 'SNAT', 'external', utils.MAX_PORT_NUMBER, @@ -166,14 +156,11 @@ def test_get_original_port_for_create_with_ctx(self): ) gateway.get_nat_rules = mock.MagicMock(return_value=[rule_inlist]) fake_ctx._target.instance.runtime_properties = {} - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat._get_original_port_for_create( - gateway, 'SNAT', 'external', - utils.MAX_PORT_NUMBER, 'internal', '11', 'TCP' - ) + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat._get_original_port_for_create( + fake_ctx, gateway, 'SNAT', 'external', + utils.MAX_PORT_NUMBER, 'internal', '11', 'TCP' + ) def test_get_gateway_ip_range(self): gate = mock.Mock() @@ -256,18 +243,15 @@ def test_obtain_public_ip(self): return_value=[rule_inlist] ) with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - self.assertEqual( - public_nat._obtain_public_ip( - fake_client, fake_ctx, gateway, - vcloud_network_plugin.CREATE - ), - '10.18.1.2' - ) + self.assertEqual( + public_nat._obtain_public_ip( + fake_client, fake_ctx, gateway, + vcloud_network_plugin.CREATE + ), + '10.18.1.2' + ) def test_get_network_ip_range(self): # dont have ip range for this network @@ -322,38 +306,35 @@ def test_create_ip_range(self): ) fake_client.get_networks = mock.MagicMock(return_value=[network]) with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - # empty gateway dhcp pool - # vca pool: 127.1.1.100..127.1.1.200 - self.assertEqual( - public_nat._create_ip_range(fake_client, gate), - '127.1.1.100 - 127.1.1.200' - ) - fake_client.get_networks.assert_called_with("some_vdc") - # network from gate - gate.get_dhcp_pools = mock.MagicMock(return_value=[ - self.genarate_pool( - "some", '127.1.1.1', '127.1.1.255' - ) - ]) - self.assertEqual( - public_nat._create_ip_range(fake_client, gate), - '127.1.1.1 - 127.1.1.255' - ) - # network not exist - network = self.generate_fake_client_network( - name="other", start_ip="127.1.1.100", - end_ip="127.1.1.200" - ) - fake_client.get_networks = mock.MagicMock( - return_value=[network] + # empty gateway dhcp pool + # vca pool: 127.1.1.100..127.1.1.200 + self.assertEqual( + public_nat._create_ip_range(fake_ctx, fake_client, gate), + '127.1.1.100 - 127.1.1.200' + ) + fake_client.get_networks.assert_called_with("some_vdc") + # network from gate + gate.get_dhcp_pools = mock.MagicMock(return_value=[ + self.genarate_pool( + "some", '127.1.1.1', '127.1.1.255' ) - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat._create_ip_range(fake_client, gate) + ]) + self.assertEqual( + public_nat._create_ip_range(fake_ctx, fake_client, gate), + '127.1.1.1 - 127.1.1.255' + ) + # network not exist + network = self.generate_fake_client_network( + name="other", start_ip="127.1.1.100", + end_ip="127.1.1.200" + ) + fake_client.get_networks = mock.MagicMock( + return_value=[network] + ) + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat._create_ip_range(fake_ctx, fake_client, gate) def test_save_configuration(self): @@ -400,61 +381,49 @@ def _ip_exist_in_runtime(fake_ctx): ) self.set_gateway_busy(gateway) fake_ctx = self.generate_relation_context_with_current_ctx() - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - self.assertFalse(public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.CREATE, - "1.2.3.4" - )) + self.assertFalse(public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.CREATE, + "1.2.3.4" + )) # operation create fake_ctx = self.generate_relation_context_with_current_ctx() self.set_services_conf_result( gateway, vcloud_plugin_common.TASK_STATUS_SUCCESS ) - with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx - ): - # success save configuration - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.CREATE, - "1.2.3.4") - self.assertEqual( - fake_ctx._target.instance.runtime_properties, - { - vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" - } - ) + # success save configuration + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.CREATE, + "1.2.3.4") + self.assertEqual( + fake_ctx._target.instance.runtime_properties, + { + vcloud_network_plugin.PUBLIC_IP: "1.2.3.4" + } + ) # delete - subscription service fake_ctx = _context_for_delete( vcloud_plugin_common.SUBSCRIPTION_SERVICE_TYPE ) with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, - "1.2.3.4" - ) + public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" + ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) # delete - without service fake_ctx = _context_for_delete(None) with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, - "1.2.3.4" - ) + public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" + ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) # delete - ondemand service - nat @@ -467,15 +436,12 @@ def _ip_exist_in_runtime(fake_ctx): } } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, - "1.2.3.4" - ) + public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" + ) self.assertFalse(_ip_exist_in_runtime(fake_ctx)) # delete - ondemand - not nat @@ -491,16 +457,13 @@ def _ip_exist_in_runtime(fake_ctx): 'nat': {} } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - # import pdb;pdb.set_trace() - public_nat._save_configuration( - gateway, fake_client, vcloud_network_plugin.DELETE, - "1.2.3.4" - ) + # import pdb;pdb.set_trace() + public_nat._save_configuration( + fake_ctx, gateway, fake_client, vcloud_network_plugin.DELETE, + "1.2.3.4" + ) gateway.deallocate_public_ip.assert_called_with("1.2.3.4") self.assertFalse(_ip_exist_in_runtime(fake_ctx)) runtime_properties = fake_ctx._target.instance.runtime_properties @@ -516,11 +479,12 @@ def _ip_exist_in_runtime(fake_ctx): def test_nat_network_operation(self): fake_client = self.generate_client() + fake_ctx = self.generate_relation_context_with_current_ctx() gateway = fake_client._vdc_gateway # used wrong operation with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.nat_network_operation( - fake_client, gateway, "unknow", "DNAT", "1.2.3.4", + fake_ctx, fake_client, gateway, "unknow", "DNAT", "1.2.3.4", "2.3.4.5", "11", "11", "TCP" ) # run correct operation/rule @@ -535,15 +499,13 @@ def test_nat_network_operation(self): fake_ctx._source.instance.runtime_properties = {} # checks with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat.nat_network_operation( - fake_client, gateway, operation, rule_type, - "1.2.3.4", "2.3.4.5", "11", "11", "TCP" - ) + public_nat.nat_network_operation( + fake_ctx, fake_client, gateway, operation, + rule_type, + "1.2.3.4", "2.3.4.5", "11", "11", "TCP" + ) if rule_type == "DNAT": if operation == vcloud_network_plugin.DELETE: gateway.del_nat_rule.assert_called_with( @@ -573,29 +535,28 @@ def test_nat_network_operation(self): fake_ctx._source.instance.runtime_properties = {} # save ssh port with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): + public_nat.nat_network_operation( + fake_ctx, fake_client, gateway, + vcloud_network_plugin.CREATE, + "DNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" + ) + self.assertEqual( + {'port_replacement': {'1.2.3.4:43': 43}}, + fake_ctx._target.instance.runtime_properties + ) + self.assertEqual( + {'ssh_port': '43', 'ssh_public_ip': '1.2.3.4'}, + fake_ctx._source.instance.runtime_properties + ) + # error with type + with self.assertRaises(cfy_exc.NonRecoverableError): public_nat.nat_network_operation( - fake_client, gateway, vcloud_network_plugin.CREATE, - "DNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" - ) - self.assertEqual( - {'port_replacement': {'1.2.3.4:43': 43}}, - fake_ctx._target.instance.runtime_properties + fake_ctx, fake_client, gateway, + vcloud_network_plugin.CREATE, + "QNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" ) - self.assertEqual( - {'ssh_port': '43', 'ssh_public_ip': '1.2.3.4'}, - fake_ctx._source.instance.runtime_properties - ) - # error with type - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.nat_network_operation( - fake_client, gateway, vcloud_network_plugin.CREATE, - "QNAT", "1.2.3.4", "2.3.4.5", "43", "22", "TCP" - ) def generate_client_and_context_server(self, no_vmip=False): """ @@ -636,15 +597,12 @@ def test_prepare_server_operation(self): fake_client, fake_ctx = self.generate_client_and_context_server() # no rules for update with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) # public ip equal to None in node properties fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.node.properties = { @@ -662,16 +620,13 @@ def test_prepare_server_operation(self): vcloud_network_plugin.PUBLIC_IP: None } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - self.assertFalse( - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + self.assertFalse( + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE ) + ) # we dont have connected private ip fake_client, fake_ctx = self.generate_client_and_context_server( no_vmip=True @@ -688,16 +643,13 @@ def test_prepare_server_operation(self): }] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - self.assertFalse( - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + self.assertFalse( + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE ) + ) # with some rules fake_client, fake_ctx = self.generate_client_and_context_server() fake_ctx._target.node.properties = { @@ -712,14 +664,11 @@ def test_prepare_server_operation(self): }] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', '11', '1.1.1.1', '11', 'TCP' ) @@ -737,14 +686,11 @@ def test_prepare_server_operation(self): }] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '1.1.1.1', 'any', 'any' ) @@ -757,14 +703,11 @@ def test_prepare_server_operation(self): 'rules': [{'type': 'SNAT'}, {'type': 'SNAT'}] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat.prepare_server_operation( - fake_client, vcloud_network_plugin.DELETE - ) + public_nat.prepare_server_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'SNAT', '1.1.1.1', 'any', '192.168.1.1', 'any', 'any' ) @@ -817,15 +760,12 @@ def test_prepare_network_operation(self): # no rules fake_client, fake_ctx = self.generate_client_and_context_network() with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - with self.assertRaises(cfy_exc.NonRecoverableError): - public_nat.prepare_network_operation( - fake_client, vcloud_network_plugin.DELETE - ) + with self.assertRaises(cfy_exc.NonRecoverableError): + public_nat.prepare_network_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) # public ip equal to None in node properties fake_client, fake_ctx = self.generate_client_and_context_network() fake_ctx._target.instance.runtime_properties = { @@ -841,16 +781,13 @@ def test_prepare_network_operation(self): }] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - self.assertFalse( - public_nat.prepare_network_operation( - fake_client, vcloud_network_plugin.DELETE - ) + self.assertFalse( + public_nat.prepare_network_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE ) + ) # rules with default values fake_client, fake_ctx = self.generate_client_and_context_network() fake_ctx._target.node.properties = { @@ -862,14 +799,11 @@ def test_prepare_network_operation(self): }] } with mock.patch( - 'vcloud_network_plugin.public_nat.ctx', fake_ctx + 'vcloud_plugin_common.ctx', fake_ctx ): - with mock.patch( - 'vcloud_plugin_common.ctx', fake_ctx - ): - public_nat.prepare_network_operation( - fake_client, vcloud_network_plugin.DELETE - ) + public_nat.prepare_network_operation( + fake_ctx, fake_client, vcloud_network_plugin.DELETE + ) fake_client._vdc_gateway.del_nat_rule.assert_called_with( 'DNAT', '192.168.1.1', 'any', '127.1.1.100 - 127.1.1.200', 'any', 'any' diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index b219f75..cb9b8b5 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, get_vcloud_config, @@ -33,7 +32,7 @@ @operation(resumable=True) @with_vca_client -def net_connect_to_nat_preconfigure(vca_client, **kwargs): +def net_connect_to_nat_preconfigure(ctx, vca_client, **kwargs): # combine properties obj = combine_properties( ctx.target, names=['nat'], properties=['rules']) @@ -50,7 +49,7 @@ def net_connect_to_nat_preconfigure(vca_client, **kwargs): @operation(resumable=True) @with_vca_client @lock_gateway -def net_connect_to_nat(vca_client, **kwargs): +def net_connect_to_nat(ctx, vca_client, **kwargs): """ create nat rule for current node """ @@ -60,14 +59,14 @@ def net_connect_to_nat(vca_client, **kwargs): if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return - if not prepare_network_operation(vca_client, CREATE): + if not prepare_network_operation(ctx, vca_client, CREATE): return set_retry(ctx) @operation(resumable=True) @with_vca_client @lock_gateway -def net_disconnect_from_nat(vca_client, **kwargs): +def net_disconnect_from_nat(ctx, vca_client, **kwargs): """ drop nat rule for current node """ @@ -77,35 +76,35 @@ def net_disconnect_from_nat(vca_client, **kwargs): if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return - if not prepare_network_operation(vca_client, DELETE): + if not prepare_network_operation(ctx, vca_client, DELETE): return set_retry(ctx) @operation(resumable=True) @with_vca_client @lock_gateway -def server_connect_to_nat(vca_client, **kwargs): +def server_connect_to_nat(ctx, vca_client, **kwargs): """ create nat rules for server """ - if not prepare_server_operation(vca_client, CREATE): + if not prepare_server_operation(ctx, vca_client, CREATE): return set_retry(ctx) @operation(resumable=True) @with_vca_client @lock_gateway -def server_disconnect_from_nat(vca_client, **kwargs): +def server_disconnect_from_nat(ctx, vca_client, **kwargs): """ drop nat rules for server """ - if not prepare_server_operation(vca_client, DELETE): + if not prepare_server_operation(ctx, vca_client, DELETE): return set_retry(ctx) @operation(resumable=True) @with_vca_client -def create_node(vca_client, **kwargs): +def create_node(ctx, vca_client, **kwargs): """ save properties on create step """ @@ -116,7 +115,7 @@ def create_node(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ validate nat rules in node properties """ @@ -148,7 +147,7 @@ def creation_validation(vca_client, **kwargs): "Parameter 'translated_port' must be integer") -def prepare_network_operation(vca_client, operation): +def prepare_network_operation(ctx, vca_client, operation): """ create nat rules by rules from network node """ @@ -160,21 +159,21 @@ def prepare_network_operation(vca_client, operation): ctx.logger.info("We dont have public ip. Retrying...") return False # if no private ip_range - raised error - private_ip = _create_ip_range(vca_client, gateway) + private_ip = _create_ip_range(ctx, vca_client, gateway) for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] nat_network_operation( - vca_client, gateway, operation, + ctx, vca_client, gateway, operation, rule_type, public_ip, private_ip, "any", "any", "any") except KeyError as e: raise cfy_exc.NonRecoverableError( "Parameter not found: {0}".format(e) ) - return _save_configuration(gateway, vca_client, operation, public_ip) + return _save_configuration(ctx, gateway, vca_client, operation, public_ip) -def prepare_server_operation(vca_client, operation): +def prepare_server_operation(ctx, vca_client, operation): """ generate nat rules by current list of rules in node """ @@ -202,25 +201,25 @@ def prepare_server_operation(vca_client, operation): original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") nat_network_operation( - vca_client, gateway, operation, + ctx, vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) if _is_snat(rule_type): has_snat = True except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) - return _save_configuration(gateway, vca_client, operation, public_ip) + return _save_configuration(ctx, gateway, vca_client, operation, public_ip) -def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, - private_ip, original_port, translated_port, - protocol): +def nat_network_operation(ctx, vca_client, gateway, operation, rule_type, + public_ip, private_ip, original_port, + translated_port, protocol): """ create/drop nat rule for current network """ if operation == CREATE: new_original_port = _get_original_port_for_create( - gateway, rule_type, public_ip, original_port, + ctx, gateway, rule_type, public_ip, original_port, private_ip, translated_port, protocol) function = gateway.add_nat_rule message = "Add" @@ -228,7 +227,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, save_ssh_parameters(ctx, str(new_original_port), public_ip) elif operation == DELETE: new_original_port = _get_original_port_for_delete( - public_ip, original_port) + ctx, public_ip, original_port) function = gateway.del_nat_rule message = "Remove" else: @@ -259,7 +258,7 @@ def nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, "Unknown rule type: {0}".format(rule_type)) -def _save_configuration(gateway, vca_client, operation, public_ip): +def _save_configuration(ctx, gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ @@ -290,7 +289,7 @@ def _save_configuration(gateway, vca_client, operation, public_ip): return True -def _create_ip_range(vca_client, gateway): +def _create_ip_range(ctx, vca_client, gateway): """ return ip range by avaible ranges from gateway and current network, on error - raise error, never return None @@ -369,7 +368,7 @@ def _obtain_public_ip(vca_client, ctx, gateway, operation): def _get_original_port_for_create( - gateway, rule_type, original_ip, original_port, translated_ip, + ctx, gateway, rule_type, original_ip, original_port, translated_ip, translated_port, protocol ): """ @@ -413,7 +412,7 @@ def _get_original_port_for_create( "Can't create NAT rule because maximum port number was reached") -def _get_original_port_for_delete(original_ip, original_port): +def _get_original_port_for_delete(ctx, original_ip, original_port): """ check may be we already replaced port by some new free port """ diff --git a/vcloud_server_plugin/vdc.py b/vcloud_server_plugin/vdc.py index 733c533..79d25e7 100644 --- a/vcloud_server_plugin/vdc.py +++ b/vcloud_server_plugin/vdc.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify.decorators import operation from cloudify import exceptions as cfy_exc @@ -31,7 +30,7 @@ @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """check params e.g.: @@ -71,7 +70,7 @@ def creation_validation(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def create(vca_client, **kwargs): +def create(ctx, vca_client, **kwargs): """create vdc""" config = get_vcloud_config() # Subscription service does not support vdc create, @@ -107,7 +106,7 @@ def create(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def delete(vca_client, **kwargs): +def delete(ctx, vca_client, **kwargs): """delete vdc""" # combine properties obj = combine_properties(ctx, kwargs=kwargs, properties=['name']) From 20e33c36e507ba4f63255d86fa29106b4ea16408 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 16:45:24 +0200 Subject: [PATCH 221/228] CYBL-979: Network: get rid of use static ctx --- .../test_mock_network_plugin_network.py | 13 ++- ...t_mock_network_plugin_network_subroutes.py | 83 +++++++++---------- vcloud_network_plugin/network.py | 13 ++- 3 files changed, 52 insertions(+), 57 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_network.py b/tests/unittests/test_mock_network_plugin_network.py index 5d72e8e..7c46603 100644 --- a/tests/unittests/test_mock_network_plugin_network.py +++ b/tests/unittests/test_mock_network_plugin_network.py @@ -290,14 +290,13 @@ def test_dhcp_operation(self): fake_client._vdc_gateway.is_busy = mock.MagicMock( return_value=True ) - with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - self.assertFalse( - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - 'secret_network', network.DELETE_POOL - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + self.assertFalse( + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + 'secret_network', network.DELETE_POOL ) + ) def test_creation_validation(self): fake_client = self.generate_client( diff --git a/tests/unittests/test_mock_network_plugin_network_subroutes.py b/tests/unittests/test_mock_network_plugin_network_subroutes.py index dbd379a..71f9f0a 100644 --- a/tests/unittests/test_mock_network_plugin_network_subroutes.py +++ b/tests/unittests/test_mock_network_plugin_network_subroutes.py @@ -57,12 +57,11 @@ def test__dhcp_operation(self): 'vdc': 'vdc_name' } }) - with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.ADD_POOL - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL + ) # wrong dhcp_range fake_ctx = self.generate_node_context(properties={ 'network': { @@ -75,13 +74,12 @@ def test__dhcp_operation(self): 'vdc': 'vdc_name' } }) - with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - with self.assertRaises(cfy_exc.NonRecoverableError): - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.ADD_POOL - ) + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + with self.assertRaises(cfy_exc.NonRecoverableError): + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL + ) fake_ctx = self.generate_node_context(properties={ 'network': { @@ -95,41 +93,40 @@ def test__dhcp_operation(self): } }) - with mock.patch('vcloud_network_plugin.network.ctx', fake_ctx): - with mock.patch('vcloud_plugin_common.ctx', fake_ctx): - # returned error/None from server - with self.assertRaises(cfy_exc.NonRecoverableError): - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.ADD_POOL - ) - fake_client.get_gateway.assert_called_with( - 'vdc_name', 'gateway' + with mock.patch('vcloud_plugin_common.ctx', fake_ctx): + # returned error/None from server + with self.assertRaises(cfy_exc.NonRecoverableError): + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL ) + fake_client.get_gateway.assert_called_with( + 'vdc_name', 'gateway' + ) - # returned error/None from server delete - with self.assertRaises(cfy_exc.NonRecoverableError): - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.DELETE_POOL - ) + # returned error/None from server delete + with self.assertRaises(cfy_exc.NonRecoverableError): + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.DELETE_POOL + ) - # returned busy, try next time - self.set_gateway_busy(fake_client._vdc_gateway) - self.prepare_retry(fake_ctx) + # returned busy, try next time + self.set_gateway_busy(fake_client._vdc_gateway) + self.prepare_retry(fake_ctx) - self.assertFalse(network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.DELETE_POOL - )) + self.assertFalse(network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.DELETE_POOL + )) - # no such gateway - fake_client.get_gateway = mock.MagicMock(return_value=None) - with self.assertRaises(cfy_exc.NonRecoverableError): - network._dhcp_operation( - fake_client, fake_ctx.node.properties, - '_management_network', network.ADD_POOL - ) + # no such gateway + fake_client.get_gateway = mock.MagicMock(return_value=None) + with self.assertRaises(cfy_exc.NonRecoverableError): + network._dhcp_operation( + fake_ctx, fake_client, fake_ctx.node.properties, + '_management_network', network.ADD_POOL + ) if __name__ == '__main__': diff --git a/vcloud_network_plugin/network.py b/vcloud_network_plugin/network.py index 76590b5..15acb7c 100644 --- a/vcloud_network_plugin/network.py +++ b/vcloud_network_plugin/network.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (with_vca_client, wait_for_task, @@ -34,7 +33,7 @@ @operation(resumable=True) @with_vca_client -def create(vca_client, **kwargs): +def create(ctx, vca_client, **kwargs): """ create new vcloud air network, e.g.: { @@ -106,14 +105,14 @@ def create(vca_client, **kwargs): "Could not create network {0}: {1}". format(network_name, result)) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name - if not _dhcp_operation(vca_client, obj, network_name, ADD_POOL): + if not _dhcp_operation(ctx, vca_client, obj, network_name, ADD_POOL): ctx.instance.runtime_properties[SKIP_CREATE_NETWORK] = True return set_retry(ctx) @operation(resumable=True) @with_vca_client -def delete(vca_client, **kwargs): +def delete(ctx, vca_client, **kwargs): """ delete vcloud air network """ @@ -126,7 +125,7 @@ def delete(vca_client, **kwargs): " been used") return network_name = get_network_name(obj) - if not _dhcp_operation(vca_client, obj, network_name, DELETE_POOL): + if not _dhcp_operation(ctx, vca_client, obj, network_name, DELETE_POOL): return set_retry(ctx) ctx.logger.info("Delete network '{0}'".format(network_name)) success, task = vca_client.delete_vdc_network( @@ -147,7 +146,7 @@ def delete(vca_client, **kwargs): @operation(resumable=True) @with_vca_client -def creation_validation(vca_client, **kwargs): +def creation_validation(ctx, vca_client, **kwargs): """ check network description from node description """ @@ -196,7 +195,7 @@ def creation_validation(vca_client, **kwargs): "IP addresses in different subnets.") -def _dhcp_operation(vca_client, obj, network_name, operation): +def _dhcp_operation(ctx, vca_client, obj, network_name, operation): """ update dhcp setting for network """ From 743c1c9b8c32318a224bc5cc1b1e642af3b4c79a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 31 Jan 2020 17:00:05 +0200 Subject: [PATCH 222/228] CYBL-979: Keypair: get rid of use static ctx --- .../test_mock_network_plugin_keypair.py | 15 +++++---------- vcloud_network_plugin/keypair.py | 18 +++++++++--------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 2aa2599..52afec7 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -147,19 +147,14 @@ def test_create_path(self): fake_ctx._context = {} fake_ctx._context['storage'] = mock.MagicMock() fake_ctx._context['storage']._storage_dir = 'storage_dir' - patcher1 = mock.patch('vcloud_network_plugin.keypair.ctx', fake_ctx) - patcher2 = mock.patch('vcloud_network_plugin.keypair.os.environ', - {'VIRTUALENV': '/path/to/dir'}) - patcher1.start() - patcher2.start() - path = keypair._create_path() + patcher = mock.patch('vcloud_network_plugin.keypair.os.environ', + {'VIRTUALENV': '/path/to/dir'}) + patcher.start() + path = keypair._create_path(ctx=fake_ctx) self.assertEqual('storage_dir/id_private.key', path) - patcher1.stop() fake_ctx._local = False - patcher1 = mock.patch('vcloud_network_plugin.keypair.ctx', fake_ctx) - patcher1.start() - path = keypair._create_path() + path = keypair._create_path(ctx=fake_ctx) self.assertEqual('/path/to/id_private.key', path) mock.patch.stopall() diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 6be24b0..0432193 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cloudify import ctx from cloudify import exceptions as cfy_exc from cloudify.decorators import operation from vcloud_plugin_common import (combine_properties, delete_properties) @@ -34,7 +33,7 @@ @operation(resumable=True) -def creation_validation(**kwargs): +def creation_validation(ctx, **kwargs): """ check availability of path used in field private_key_path of node properties @@ -53,7 +52,7 @@ def creation_validation(**kwargs): @operation(resumable=True) -def create(**kwargs): +def create(ctx, **kwargs): ctx.instance.runtime_properties[PUBLIC_KEY] = {} ctx.instance.runtime_properties[PRIVATE_KEY] = {} ctx.instance.runtime_properties[PUBLIC_KEY][USER] = \ @@ -71,7 +70,8 @@ def create(**kwargs): ctx.instance.runtime_properties[PRIVATE_KEY][KEY] = private ctx.instance.runtime_properties[PUBLIC_KEY][KEY] = public if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): - ctx.instance.runtime_properties[PRIVATE_KEY][PATH] = _create_path() + ctx.instance.runtime_properties[ + PRIVATE_KEY][PATH] = _create_path(ctx) _save_key_file(ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) else: @@ -84,14 +84,14 @@ def create(**kwargs): if obj.get(PRIVATE_KEY, {}).get(CREATE_PRIVATE_KEY_FILE): if obj.get(PRIVATE_KEY, {}).get(KEY): ctx.instance.runtime_properties[ - PRIVATE_KEY][PATH] = _create_path() + PRIVATE_KEY][PATH] = _create_path(ctx) _save_key_file( ctx.instance.runtime_properties[PRIVATE_KEY][PATH], ctx.instance.runtime_properties[PRIVATE_KEY][KEY]) @operation(resumable=True) -def delete(**kwargs): +def delete(ctx, **kwargs): # combine properties obj = combine_properties(ctx, kwargs=kwargs, names=[PRIVATE_KEY, PUBLIC_KEY], @@ -112,7 +112,7 @@ def delete(**kwargs): @operation(resumable=True) -def server_connect_to_keypair(**kwargs): +def server_connect_to_keypair(ctx, **kwargs): host_rt_properties = ctx.source.instance.runtime_properties target_rt_properties = ctx.target.instance.runtime_properties if SSH_KEY not in host_rt_properties: @@ -133,7 +133,7 @@ def server_connect_to_keypair(**kwargs): @operation(resumable=True) -def server_disconnect_from_keypair(**kwargs): +def server_disconnect_from_keypair(ctx, **kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY in host_rt_properties: del host_rt_properties[SSH_KEY] @@ -149,7 +149,7 @@ def _generate_pair(): return public_value, private_value -def _create_path(): +def _create_path(ctx): if ctx._local: key_dir = ctx._context['storage']._storage_dir else: From 8fd27543ea19d70339a4651a76c808190493bcdf Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 3 Feb 2020 16:32:54 +0200 Subject: [PATCH 223/228] CYBL-979: Fix exception catch code in cpu/memory change --- vcloud_server_plugin/server.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 0abb47e..025ba09 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -359,28 +359,31 @@ def configure(ctx, vca_client, **kwargs): memory = hardware.get('memory') _check_hardware(cpu, memory) if memory: + task = None try: ctx.logger.info( "Customize VM memory: '{0}'.".format(memory) ) task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) - except Exception: + except Exception as e: raise cfy_exc.NonRecoverableError( - "Customize VM memory failed: '{0}'. {1}". - format(task, error_response(vapp))) + "Customize VM memory failed: {task}. " + "Vapp: {app} Error: {e} ". + format(e=e, task=task, app=error_response(vapp))) if cpu: + task = None try: ctx.logger.info( "Customize VM cpu: '{0}'.".format(cpu) ) task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) - except Exception: + except Exception as e: raise cfy_exc.NonRecoverableError( - "Customize VM cpu failed: '{0}'. {1}". - format(task, error_response(vapp))) - + "Customize VM cpu failed: {task}. " + "Vapp: {app} Error: {e} ". + format(e=e, task=task, app=error_response(vapp))) if custom or public_keys: script = _build_script(custom, public_keys) password = custom.get('admin_password') From 746155d9fab415711e67ff292a84c90ea61f0e92 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 4 Feb 2020 16:32:12 +0200 Subject: [PATCH 224/228] CYBL-979: Update runtime only on direct calls --- examples/blueprint.yaml | 3 +- plugin.yaml | 453 +++++++++++++++++- .../test_mock_network_plugin_public_nat.py | 16 - .../test_mock_storage_plugin_volume.py | 1 - vcloud_network_plugin/floatingip.py | 2 +- vcloud_network_plugin/keypair.py | 2 +- vcloud_network_plugin/public_nat.py | 19 +- vcloud_network_plugin/security_group.py | 3 +- vcloud_plugin_common/__init__.py | 12 +- vcloud_server_plugin/server.py | 4 +- 10 files changed, 447 insertions(+), 68 deletions(-) diff --git a/examples/blueprint.yaml b/examples/blueprint.yaml index edcbdd9..1099de0 100644 --- a/examples/blueprint.yaml +++ b/examples/blueprint.yaml @@ -2,7 +2,8 @@ tosca_definitions_version: cloudify_dsl_1_3 imports: - https://cloudify.co/spec/cloudify/4.4/types.yaml - - http://www.getcloudify.org/spec/tosca-vcloud-plugin/1.6.0/plugin.yaml + # - http://www.getcloudify.org/spec/tosca-vcloud-plugin/1.6.0/plugin.yaml + - ../plugin.yaml node_types: vcloud_configuration: diff --git a/plugin.yaml b/plugin.yaml index 0edda64..a3c1dc4 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -6,21 +6,350 @@ plugins: package_name: tosca-vcloud-plugin package_version: '1.6.1.dev1' +data_types: + + cloudify.datatypes.vlcoud.config: + properties: + username: + type: string + required: false + description: > + The vCloud account username. + password: + type: string + required: false + description: > + The vCloud account password. + url: + type: string + required: false + description: > + The vCloud URL. + org: + type: string + required: false + description: > + The organization name. Required only for the ondemand and + subscription service types. + instance: + type: string + required: false + description: > + The instance UUID. Required only for the ondemand service type. + vdc: + type: string + required: false + description: > + The virtual datacenter name. + service: + type: string + required: false + description: > + The vCloud service name. + service_type: + type: string + default: subscription + description: > + The service type. Can be subscription, ondemand, vcd or private. + Private is an alias for vcd and both types can be used with a + private vCloud environment without any difference. Defaults to subscription. + api_version: + type: string + default: 5.7 + description: > + The vCloud API version. For Subscription, defaults to 5.6. For + OnDemand, defaults to 5.7. + region: + type: string + required: false + description: > + The region name. Applies to OnDemand. + org_url: + type: string + required: false + description: > + The organization URL. Required only for private service type. + edge_gateway: + type: string + required: false + description: > + The Edge gateway name. + ssl_verify: + type: boolean + default: true + description: > + A boolean flag for disabling the SSL certificate check. + Only applicable for a private cloud service with self-signed + certificates. Defaults to True + + cloudify.datatypes.vlcoud.server_key: + properties: + key: + type: string + required: false + description: > + The public SSH key. + user: + type: string + required: false + description: > + The user name. + + cloudify.datatypes.vlcoud.server_customization: + properties: + public_keys: + type: string + required: false + description: > + The public keys to be injected. A list of key-value configurations. + computer_name: + type: string + required: false + description: > + The VM hostname. + admin_password: + type: string + required: false + description: > + The root password. + pre_script: + type: string + required: false + description: > + A pre-customization script. + post_script: + type: string + required: false + description: > + A pPost-customization script. + script_executor: + type: string + default: /bin/bash + description: > + The script executor. The default is /bin/bash. + + cloudify.datatypes.vlcoud.server_hardware: + properties: + cpu: + type: integer + required: false + description: > + The VM CPU count. + memory: + type: integer + required: false + description: > + The VM memory size, in MB. + + cloudify.datatypes.vlcoud.server: + properties: + name: + type: string + required: false + description: > + The server name. + template: + type: string + required: false + description: > + The vApp template from which the server is spawned. + catalog: + type: string + required: false + description: > + The vApp templates catalog. + guest_customization: + type: cloudify.datatypes.vlcoud.server_customization + required: false + description: > + The guest customization section + hardware: + type: cloudify.datatypes.vlcoud.server_hardware + required: false + description: > + The key-value hardware customization section, including: + + cloudify.datatypes.vlcoud.network_dhcp: + properties: + dhcp_range: + type: string + required: false + description: > + The DHCP pool range. + default_lease: + type: string + required: false + description: > + The default lease in seconds. + max_lease: + type: string + required: false + description: > + The maximum lease, in seconds. + + cloudify.datatypes.vlcoud.network: + properties: + edge_gateway: + type: string + required: false + description: > + The Edge gateway name. + name: + type: string + required: false + description: > + The network name. + static_range: + type: string + required: false + description: > + The static IP allocation pool range. + netmask: + type: string + required: false + description: > + The network netmask. + gateway_ip: + type: string + required: false + description: > + The network gateway. + dns: + required: false + description: > + The list of DNS IP addresses. + dns_suffix: + type: string + required: false + description: > + The DNS suffix. + dhcp: + type: cloudify.datatypes.vlcoud.network_dhcp + description: > + The DHCP settings. + + cloudify.datatypes.vlcoud.port: + properties: + network: + type: string + required: false + description: > + The network name. + ip_allocation_mode: + type: string + required: false + description: > + The IP allocation mode. Can be dhcp, pool or manual. + ip_address: + type: string + required: false + description: > + The IP address if the IP allocation mode is manual. + mac_address: + type: string + required: false + description: > + The interface MAC address. + primary_interface: + type: boolean + default: false + description: > + Specifies whether the interface is the primary interface (true or + false). + + cloudify.datatypes.vlcoud.floatingip: + properties: + edge_gateway: + type: string + required: false + description: > + The vCloud gateway name. + public_ip: + type: string + required: false + description: > + The public IP address. If not specified, the public IP is allocated + from the pool of free public IPs. + + cloudify.datatypes.vlcoud.nat: + properties: + edge_gateway: + type: string + required: false + description: > + The vCloud gateway name. + public_ip: + type: string + required: false + description: > + The public IP. If not specified, the public IP is allocated from + the pool of free public IPs. + + cloudify.datatypes.vlcoud.security_group: + properties: + edge_gateway: + type: string + required: false + description: > + The vCloud gateway name. + + cloudify.datatypes.vlcoud.volume: + properties: + name: + type: string + required: false + description: > + Volume name + size: + type: integer + required: false + description: > + Volume size + + cloudify.datatypes.vlcoud.private_key: + properties: + create_file: + type: string + required: false + description: > + Whether to save the file. Use with auto_generate: true. + + cloudify.datatypes.vlcoud.public_key: + properties: + key: + type: string + required: false + description: > + The SSH public key. + user: + type: string + required: false + description: > + The user name. + node_types: cloudify.vcloud.nodes.Server: derived_from: cloudify.nodes.Compute properties: use_external_resource: + type: boolean default: false + description: > + Use predefined resource resource_id: - default: '' + default: false + description: > + Resource Id server: - default: {} + type: cloudify.datatypes.vlcoud.server management_network: - default: '' + type: string + default: "" + description: > + The management network name. vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: @@ -47,13 +376,18 @@ node_types: derived_from: cloudify.nodes.Network properties: network: - default: {} + type: cloudify.datatypes.vlcoud.network use_external_resource: + type: boolean default: false + description: > + Use predefined resource resource_id: - default: '' + default: false + description: > + Resource Id vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: @@ -71,14 +405,16 @@ node_types: derived_from: cloudify.nodes.Port properties: port: - default: {} + type: cloudify.datatypes.vlcoud.port vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: implementation: vcloud.vcloud_network_plugin.port.creation_validation - inputs: {} + inputs: + port: + default: { get_property: [SELF, port]} delete: implementation: vcloud.vcloud_network_plugin.port.delete inputs: {} @@ -87,56 +423,104 @@ node_types: derived_from: cloudify.nodes.VirtualIP properties: floatingip: - default: {} + type: cloudify.datatypes.vlcoud.floatingip vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: implementation: vcloud.vcloud_network_plugin.floatingip.creation_validation - inputs: {} + inputs: + floatingip: + default: { get_property: [SELF, floatingip]} cloudify.vcloud.nodes.PublicNAT: derived_from: cloudify.nodes.VirtualIP properties: use_external_resource: + type: boolean default: false + description: > + Use predefined resource nat: - default: {} + type: cloudify.datatypes.vlcoud.nat + description: > + The key-value NAT configuration. rules: default: [] + description: > + The key-value NAT rules configuration: + protocol - The network protocol. Can be tcp, udp or any. + Applies only for DNAT. + original_port - The original port. Applies only for DNAT. + translated_port - The translated port. Applies only for + DNAT. + type - The list of NAT types. Can be SNAT, DNAT or both. vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: implementation: vcloud.vcloud_network_plugin.public_nat.creation_validation - inputs: {} + inputs: + use_external_resource: + default: { get_property: [SELF, use_external_resource]} + nat: + default: { get_property: [SELF, nat]} + rules: + default: { get_property: [SELF, rules]} cloudify.vcloud.nodes.SecurityGroup: derived_from: cloudify.nodes.SecurityGroup properties: security_group: - default: {} + type: cloudify.datatypes.vlcoud.security_group + description: > + The key-value SecurityGroup configuration rules: default: [] + description: > + The security group rules. A list of key-value configurations. + protocol - tcp, udp, icmp or any. + source - The source of traffic on which to apply the + firewall. Can be internal, external, host, any, the IP + address or IP range. + source_port - The port number or any. + destination - The destination of traffic on which to apply + the firewall rule. Can be internal, external, host, any, + the IP address or IP range. + destination_port - The port number or any. + action - allow or deny. + log_traffic - Used to capture traffic. true or false. + description - The rule description. vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: implementation: vcloud.vcloud_network_plugin.security_group.creation_validation - inputs: {} + inputs: + security_group: + default: { get_property: [SELF, security_group]} + rules: + default: { get_property: [SELF, rules]} cloudify.vcloud.nodes.KeyPair: derived_from: cloudify.nodes.Root properties: auto_generate: + type: boolean default: false + description: > + Use to auto-generate the key. private_key: - default: {} + type: cloudify.datatypes.vlcoud.private_key + description: > + The key-value private key configuration public_key: - default: {} + type: cloudify.datatypes.vlcoud.public_key + description: > + The key-value public key configuration interfaces: cloudify.interfaces.validation: creation: @@ -154,15 +538,26 @@ node_types: derived_from: cloudify.nodes.Volume properties: device_name: + type: string default: '' + description: > + Device name volume: + type: cloudify.datatypes.vlcoud.volume + description: > + The key-value volume configuration default: {} use_external_resource: + type: boolean default: false + description: > + Use predefined resource resource_id: - default: '' + default: false + description: > + Resource Id vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: @@ -180,13 +575,21 @@ node_types: derived_from: cloudify.nodes.Root properties: name: + type: string default: '' + description: > + VDC name use_external_resource: + type: boolean default: false + description: > + Use predefined resource resource_id: - default: '' + default: false + description: > + Resource Id vcloud_config: - default: {} + type: cloudify.datatypes.vlcoud.config interfaces: cloudify.interfaces.lifecycle: create: diff --git a/tests/unittests/test_mock_network_plugin_public_nat.py b/tests/unittests/test_mock_network_plugin_public_nat.py index 7f3b144..ce21a48 100644 --- a/tests/unittests/test_mock_network_plugin_public_nat.py +++ b/tests/unittests/test_mock_network_plugin_public_nat.py @@ -809,22 +809,6 @@ def test_prepare_network_operation(self): 'any', 'any' ) - def test_create(self): - fake_client = self.generate_client() - # no nat - fake_ctx = self.generate_node_context_with_current_ctx( - properties={ - 'vcloud_config': { - 'vdc': 'vdc_name' - } - } - ) - with mock.patch( - 'vcloud_plugin_common.VcloudAirClient.get', - mock.MagicMock(return_value=fake_client) - ): - public_nat.create_node(ctx=fake_ctx, vca_client=None) - def test_creation_validation(self): fake_client = self.generate_client() # no nat diff --git a/tests/unittests/test_mock_storage_plugin_volume.py b/tests/unittests/test_mock_storage_plugin_volume.py index f077d5d..6313f9a 100644 --- a/tests/unittests/test_mock_storage_plugin_volume.py +++ b/tests/unittests/test_mock_storage_plugin_volume.py @@ -410,7 +410,6 @@ def test_detach_volume(self): ): volume.detach_volume(ctx=fake_ctx, vca_client=None) - @unittest.skip("Fabric changed api, skip for now") def run_wait_boot(self, fabric_settings, fabric_run, ctx, sleep_call=True): sleep_function = mock.MagicMock() with mock.patch( diff --git a/vcloud_network_plugin/floatingip.py b/vcloud_network_plugin/floatingip.py index 916537a..17271b4 100644 --- a/vcloud_network_plugin/floatingip.py +++ b/vcloud_network_plugin/floatingip.py @@ -86,7 +86,7 @@ def _floatingip_operation(operation, vca_client, ctx): """ service_type = get_vcloud_config().get('service_type') # combine properties - obj = combine_properties(ctx.target, names=['floatingip']) + obj = combine_properties(ctx.target, names=['floatingip'], copy_back=False) gateway = get_gateway( vca_client, obj['floatingip']['edge_gateway']) diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 0432193..7cbe3bc 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -35,7 +35,7 @@ @operation(resumable=True) def creation_validation(ctx, **kwargs): """ - check availability of path used in field private_key_path of + check availability of path used in field private key path of node properties """ # combine properties diff --git a/vcloud_network_plugin/public_nat.py b/vcloud_network_plugin/public_nat.py index cb9b8b5..a6f1458 100644 --- a/vcloud_network_plugin/public_nat.py +++ b/vcloud_network_plugin/public_nat.py @@ -35,7 +35,7 @@ def net_connect_to_nat_preconfigure(ctx, vca_client, **kwargs): # combine properties obj = combine_properties( - ctx.target, names=['nat'], properties=['rules']) + ctx.target, names=['nat'], properties=['rules'], copy_back=False) rules = obj['rules'] if not rules or len(rules) != 1: raise cfy_exc.NonRecoverableError( @@ -55,7 +55,7 @@ def net_connect_to_nat(ctx, vca_client, **kwargs): """ # combine properties obj = combine_properties( - ctx.target, names=['nat'], properties=['rules']) + ctx.target, names=['nat'], properties=['rules'], copy_back=False) if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return @@ -72,7 +72,7 @@ def net_disconnect_from_nat(ctx, vca_client, **kwargs): """ # combine properties obj = combine_properties( - ctx.target, names=['nat'], properties=['rules']) + ctx.target, names=['nat'], properties=['rules'], copy_back=False) if obj.get('use_external_resource', False): ctx.logger.info("Using existing Public NAT.") return @@ -102,17 +102,6 @@ def server_disconnect_from_nat(ctx, vca_client, **kwargs): return set_retry(ctx) -@operation(resumable=True) -@with_vca_client -def create_node(ctx, vca_client, **kwargs): - """ - save properties on create step - """ - # combine properties - combine_properties( - ctx, kwargs=kwargs, names=['nat'], properties=['rules']) - - @operation(resumable=True) @with_vca_client def creation_validation(ctx, vca_client, **kwargs): @@ -180,7 +169,7 @@ def prepare_server_operation(ctx, vca_client, operation): try: # combine properties obj = combine_properties( - ctx.target, names=['nat'], properties=['rules']) + ctx.target, names=['nat'], properties=['rules'], copy_back=False) gateway = get_gateway( vca_client, obj['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) diff --git a/vcloud_network_plugin/security_group.py b/vcloud_network_plugin/security_group.py index b6ec2de..05dc834 100644 --- a/vcloud_network_plugin/security_group.py +++ b/vcloud_network_plugin/security_group.py @@ -119,7 +119,8 @@ def _rule_operation(ctx, operation, vca_client): gateway = get_gateway(vca_client, gateway_name) # combine properties obj = combine_properties( - ctx.target, names=['security_group'], properties=['rules']) + ctx.target, names=['security_group'], properties=['rules'], + copy_back=False) for rule in obj['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") diff --git a/vcloud_plugin_common/__init__.py b/vcloud_plugin_common/__init__.py index 7de19cf..a22d9fd 100644 --- a/vcloud_plugin_common/__init__.py +++ b/vcloud_plugin_common/__init__.py @@ -569,7 +569,8 @@ def delete_properties(ctx): del ctx.instance.runtime_properties[key] -def combine_properties(ctx, kwargs=None, names=None, properties=None): +def combine_properties(ctx, kwargs=None, names=None, properties=None, + copy_back=True): """combine properties + runtime properties + kwargs""" if not kwargs: kwargs = {} @@ -600,8 +601,9 @@ def combine_properties(ctx, kwargs=None, names=None, properties=None): ctx.node.properties.get(name) ) ) - # update runtime properties back - for name in obj: - if "vcloud_config" != name: - ctx.instance.runtime_properties[name] = obj[name] + if copy_back: + # update runtime properties back + for name in obj: + if "vcloud_config" != name: + ctx.instance.runtime_properties[name] = obj[name] return obj diff --git a/vcloud_server_plugin/server.py b/vcloud_server_plugin/server.py index 025ba09..376282f 100644 --- a/vcloud_server_plugin/server.py +++ b/vcloud_server_plugin/server.py @@ -673,7 +673,7 @@ def _create_connections_list(ctx, vca_client): management_network_name = ctx.node.properties.get('management_network') for port in ports: - obj = combine_properties(port, names=['port']) + obj = combine_properties(port, names=['port'], copy_back=False) port_properties = obj['port'] connections.append( _create_connection(port_properties['network'], @@ -686,7 +686,7 @@ def _create_connections_list(ctx, vca_client): ) for net in networks: - obj = combine_properties(net, names=['network']) + obj = combine_properties(net, names=['network'], copy_back=False) connections.append( _create_connection(get_network_name(net.node.properties), None, None, 'POOL')) From 5570c7d092c46cc8d090cd75b13c67da33021b39 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 7 Feb 2020 14:54:19 +0200 Subject: [PATCH 225/228] CYBL-979: use new style agent_config --- vcloud_network_plugin/keypair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index 7cbe3bc..ad01462 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -24,7 +24,7 @@ PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' CREATE_PRIVATE_KEY_FILE = 'create_file' -CLOUDIFY_AGENT = 'cloudify_agent' +CLOUDIFY_AGENT = 'agent_config' PATH = 'path' KEY = 'key' USER = 'user' From 71ca23470f514dedb78663aeff1ac644680f153a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 11 Feb 2020 17:23:48 +0200 Subject: [PATCH 226/228] version bump --- plugin.yaml | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index a3c1dc4..7eeaed7 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2,9 +2,9 @@ plugins: vcloud: executor: central_deployment_agent - source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.1.dev1.zip + source: https://github.com/cloudify-cosmo/tosca-vcloud-plugin/archive/1.6.1.zip package_name: tosca-vcloud-plugin - package_version: '1.6.1.dev1' + package_version: '1.6.1' data_types: diff --git a/setup.py b/setup.py index b84ca06..537b5b2 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( zip_safe=True, name='tosca-vcloud-plugin', - version='1.6.1.dev1', + version='1.6.1', packages=[ 'vcloud_plugin_common', 'vcloud_server_plugin', From c5196abd066ba5315b66911e5390b0ed6c15988f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 14 Feb 2020 11:19:36 +0200 Subject: [PATCH 227/228] sync constant name with value --- tests/unittests/test_mock_network_plugin_keypair.py | 4 ++-- vcloud_network_plugin/keypair.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/unittests/test_mock_network_plugin_keypair.py b/tests/unittests/test_mock_network_plugin_keypair.py index 52afec7..66eb016 100644 --- a/tests/unittests/test_mock_network_plugin_keypair.py +++ b/tests/unittests/test_mock_network_plugin_keypair.py @@ -197,7 +197,7 @@ def test_server_connect_to_keypair(self): self.assertEqual( fake_ctx.source.instance.runtime_properties, { - keypair.CLOUDIFY_AGENT: { + keypair.AGENT_CONFIG: { keypair.KEY: '/path/' }, keypair.SSH_KEY: { @@ -212,7 +212,7 @@ def test_server_disconnect_from_keypair(self): # test drop all keys informations from node fake_ctx = self.generate_relation_context_with_current_ctx() fake_ctx.source.instance.runtime_properties = { - keypair.CLOUDIFY_AGENT: { + keypair.AGENT_CONFIG: { keypair.KEY: '/path/' }, keypair.SSH_KEY: { diff --git a/vcloud_network_plugin/keypair.py b/vcloud_network_plugin/keypair.py index ad01462..f5dc23a 100644 --- a/vcloud_network_plugin/keypair.py +++ b/vcloud_network_plugin/keypair.py @@ -24,7 +24,7 @@ PRIVATE_KEY = 'private_key' PUBLIC_KEY = 'public_key' CREATE_PRIVATE_KEY_FILE = 'create_file' -CLOUDIFY_AGENT = 'agent_config' +AGENT_CONFIG = 'agent_config' PATH = 'path' KEY = 'key' USER = 'user' @@ -126,8 +126,8 @@ def server_connect_to_keypair(ctx, **kwargs): host_rt_properties[SSH_KEY][USER] = target_rt_properties[ PUBLIC_KEY].get(USER) if target_rt_properties[PRIVATE_KEY].get(PATH): - host_rt_properties[CLOUDIFY_AGENT] = {} - host_rt_properties[CLOUDIFY_AGENT][KEY] = target_rt_properties[ + host_rt_properties[AGENT_CONFIG] = {} + host_rt_properties[AGENT_CONFIG][KEY] = target_rt_properties[ PRIVATE_KEY].get(PATH) ctx.source.instance.update() @@ -137,8 +137,8 @@ def server_disconnect_from_keypair(ctx, **kwargs): host_rt_properties = ctx.source.instance.runtime_properties if SSH_KEY in host_rt_properties: del host_rt_properties[SSH_KEY] - if CLOUDIFY_AGENT in host_rt_properties: - del host_rt_properties[CLOUDIFY_AGENT] + if AGENT_CONFIG in host_rt_properties: + del host_rt_properties[AGENT_CONFIG] def _generate_pair(): From 508fff53eda985dc53f517f4cece84ceb9f5d510 Mon Sep 17 00:00:00 2001 From: AdarShaked Date: Mon, 9 Mar 2020 15:20:50 +0200 Subject: [PATCH 228/228] added link to blueprints exapmples in README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c84950f..2f2b860 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,7 @@ tox -e ondemand -- \test_network_plugin.py tox -e ondemand -- \test_network_plugin.py:ValidationOperationsTestCase tox -e ondemand -- \test_network_plugin.py:ValidationOperationsTestCase.test_validation -``` \ No newline at end of file +``` + +## Examples +For official blueprint examples using this Cloudify plugin, please see [Cloudify Community Blueprints Examples](https://github.com/cloudify-community/blueprint-examples/).