Skip to content

Commit 75a9ab8

Browse files
author
earthmant
committed
plugin replacement code
1 parent b6f98d8 commit 75a9ab8

File tree

14 files changed

+380
-125
lines changed

14 files changed

+380
-125
lines changed

CHANGELOG.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2.0.0:
2+
- New version.

cicd/__init__.py

Whitespace-only changes.

cicd/update_test_manager.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from os import path, pardir
2+
from ecosystem_tests.dorkl import replace_plugin_package_on_manager
3+
from ecosystem_cicd_tools.validations import validate_plugin_version
4+
5+
abs_path = path.join(
6+
path.abspath(path.join(path.dirname(__file__), pardir)))
7+
8+
if __name__ == '__main__':
9+
version = validate_plugin_version(abs_path)
10+
for package in ['cloudify_vcd', 'vcd_plugin_sdk']:
11+
replace_plugin_package_on_manager(
12+
'cloudify-vcd-plugin', version, package, )

cloudify_vcd/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __init__(self, *_, **__):
1919
'cloudify.nodes.vcloud.IsolatedVDCNetwork': [VCloudNetwork],
2020
'cloudify.nodes.vcloud.RoutedVDCNetwork': [VCloudNetwork],
2121
'cloudify.nodes.vcloud.VApp': [VCloudvApp],
22-
'cloudify.nodes.vcloud.VM': [VCloudVM],
22+
'cloudify.nodes.vcloud.VM': [VCloudVM, VCloudvApp],
2323
'cloudify.nodes.vcloud.Disk': [VCloudDisk],
2424
'cloudify.nodes.vcloud.Media': [VCloudMedia, VCloudISO],
2525
}

cloudify_vcd/decorators.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11

22
from pyvcloud.vcd.exceptions import (
3+
AccessForbiddenException,
34
EntityNotFoundException,
45
UnauthorizedException,
56
BadRequestException,
7+
NotFoundException,
68
VcdTaskException)
79

810
from functools import wraps
@@ -38,17 +40,35 @@ def wrapper(*_, **kwargs):
3840

3941
if not resource_data.primary_external:
4042
try:
41-
ctx.logger.info('Before')
43+
ctx.logger.debug('Executing func {func} '
44+
'with args {args} '
45+
'kwargs {kwargs}'.format(
46+
func=func, args=args, kwargs=kwargs))
4247
resource, result = func(*args, **kwargs)
43-
ctx.logger.info('After')
44-
except (EntityNotFoundException, BadRequestException) as e:
45-
if isinstance(e, EntityNotFoundException):
48+
ctx.logger.debug('Executed func {func} '
49+
'result {result}'.format(
50+
func=func, result=result))
51+
except (AccessForbiddenException,
52+
EntityNotFoundException,
53+
BadRequestException,
54+
NotFoundException) as e:
55+
ctx.logger.error(
56+
'Failed to execute func {func} '
57+
'with args {args} '
58+
'kwargs {kwargs} '
59+
'Error: {e}'.format(func=func,
60+
args=args,
61+
kwargs=kwargs,
62+
e=str(e)))
63+
if isinstance(e, (TypeError,
64+
NotFoundException,
65+
EntityNotFoundException)):
4666
if operation_name not in NO_RESOURCE_OK:
4767
raise NonRecoverableError(
4868
'The expected resource {r} does not exist.'.format(
4969
r=resource_data.primary_id))
5070
ctx.logger.error('Attempted to perform {op} '
51-
'operation on {r},'
71+
'operation on {r}, '
5272
'but the resource was not '
5373
'found.'.format(
5474
op=operation_name,
@@ -57,15 +77,15 @@ def wrapper(*_, **kwargs):
5777
resource_data.primary_ctx.instance.runtime_properties[
5878
'__RETRY_BAD_REQUEST'] = True
5979
resource_data.primary_ctx.instance.update()
60-
raise OperationRetry(str(e))
80+
raise OperationRetry(str(e))
6181
else:
6282
last_task = get_last_task(result)
6383

6484
if not resource:
6585
args[0] = True # Tell the function to expect external resource.
6686
try:
6787
resource, _ = func(*args, **kwargs)
68-
except EntityNotFoundException:
88+
except (TypeError, NotFoundException, EntityNotFoundException):
6989
if operation_name not in NO_RESOURCE_OK:
7090
raise NonRecoverableError(
7191
'The expected resource {r} does not exist.'.format(

cloudify_vcd/gateway_tasks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
from cloudify import ctx
33

4-
from vcd_plugin_sdk.exceptions import VCloudSDKException
5-
from .decorators import resource_operation
64
from .utils import expose_props
5+
from .decorators import resource_operation
6+
from vcd_plugin_sdk.exceptions import VCloudSDKException
77

88

99
@resource_operation
@@ -252,8 +252,8 @@ def delete_nat_rules(_,
252252
____,
253253
_____,
254254
______,
255-
_______,
256255
nat_rule_ctx,
256+
_______,
257257
gateway_id,
258258
gateway_client,
259259
gateway_vdc,
@@ -264,7 +264,7 @@ def delete_nat_rules(_,
264264
gateway = gateway_class(
265265
gateway_id, gateway_client, gateway_vdc)
266266
nat_rules = nat_rule_ctx.instance.runtime_properties.get('rules')
267-
for nat_rule_id, _ in nat_rules:
267+
for nat_rule_id, _ in nat_rules.items():
268268
try:
269269
gateway.delete_nat_rule(nat_rule_id)
270270
except VCloudSDKException:

cloudify_vcd/network_tasks.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
from .decorators import resource_operation
3-
from .utils import (
4-
find_resource_id_from_relationship_by_type)
3+
from .utils import find_resource_id_from_relationship_by_type
54

65
REL_NETWORK_GW = 'cloudify.relationships.vcloud.network_connected_to_gateway'
76

cloudify_vcd/utils.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
from pyvcloud.vcd.exceptions import (
66
VcdTaskException,
77
EntityNotFoundException,
8+
AccessForbiddenException,
89
)
910

1011
from cloudify import ctx
11-
from cloudify.exceptions import NonRecoverableError
12+
from cloudify.exceptions import OperationRetry, NonRecoverableError
1213
from cloudify.constants import NODE_INSTANCE, RELATIONSHIP_INSTANCE
1314

1415
from .constants import CLIENT_CONFIG_KEYS, CLIENT_CREDENTIALS_KEYS, TYPE_MATRIX, NO_RESOURCE_OK
@@ -65,6 +66,10 @@ def primary_ctx(self):
6566
def primary_external(self):
6667
return self._resources[0].get('external')
6768

69+
@property
70+
def primary_vdc(self):
71+
return self._resources[0].get('vdc')
72+
6873
@property
6974
def primary_resource(self):
7075
return self.primary_class(self.primary_id,
@@ -398,6 +403,20 @@ def vcd_busy_exception(exc):
398403
def vcd_unclear_exception(exc):
399404
if 'Status code: 400/None, None' in str(exc):
400405
return True
406+
if isinstance(exc, AccessForbiddenException):
407+
return True
408+
return False
409+
410+
411+
def vcd_already_exists(exc):
412+
if '400/DUPLICATE_NAME' in str(exc):
413+
return True
414+
return False
415+
416+
417+
def vcd_unresolved_vm(exc):
418+
if 'Unresolved' in str(exc):
419+
return True
401420
return False
402421

403422

@@ -414,7 +433,5 @@ def check_if_task_successful(_resource, task):
414433
except VcdTaskException as e:
415434
if cannot_deploy(e):
416435
raise NonRecoverableError(str(e))
417-
ctx.logger.error(
418-
'Unhandled state validation error: {e}.'.format(e=str(e)))
419-
return False
436+
raise OperationRetry('Unhandled state validation error: {e}.'.format(e=str(e)))
420437
return True

cloudify_vcd/vapp_tasks.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11

2+
from pyvcloud.vcd.exceptions import (
3+
BadRequestException,
4+
OperationNotSupportedException)
5+
6+
from cloudify.exceptions import OperationRetry
7+
28
from .decorators import resource_operation
9+
from .network_tasks import get_network_type
310
from .utils import (
11+
find_rel_by_type,
12+
vcd_unresolved_vm,
13+
vcd_already_exists,
414
find_resource_id_from_relationship_by_type)
515

616
REL_VAPP_NETWORK = 'cloudify.relationships.vcloud.vapp_connected_to_network'
17+
REL_VM_NETWORK = 'cloudify.relationships.vcloud.vm_connected_to_network'
18+
REL_VM_VAPP = 'cloudify.relationships.vcloud.vm_contained_in_vapp'
719

820

921
@resource_operation
@@ -45,6 +57,10 @@ def stop_vapp(_,
4557
vapp_vdc,
4658
kwargs=vapp_config
4759
)
60+
# try:
61+
# vapp.undeploy()
62+
# except OperationNotSupportedException:
63+
# pass
4864
vapp.undeploy()
4965
return vapp, None
5066

@@ -66,3 +82,125 @@ def delete_vapp(_,
6682
)
6783
vapp.delete()
6884
return vapp, None
85+
86+
87+
@resource_operation
88+
def create_vm(vm_external,
89+
vm_id,
90+
vm_client,
91+
vm_vdc,
92+
vm_config,
93+
vm_class,
94+
vm_ctx):
95+
vapp_name = find_resource_id_from_relationship_by_type(
96+
vm_ctx.instance, REL_VM_VAPP) # or vapp_id
97+
network = find_rel_by_type(
98+
vm_ctx.instance, REL_VM_NETWORK)
99+
if network:
100+
vm_config['network'] = vm_config.get(
101+
'network',
102+
network.target.instance.runtime_properties.get('resource_id'))
103+
104+
vm = vm_class(
105+
vm_id,
106+
vapp_name,
107+
vm_client,
108+
vdc_name=vm_vdc,
109+
kwargs={},
110+
vapp_kwargs=vm_config
111+
)
112+
if network:
113+
network_type = get_network_type(network.target.node.type_hierarchy)
114+
if not vm.check_network(vm_config['network'], network_type):
115+
raise OperationRetry(
116+
'Waiting on the network {n} to be ready'.format(
117+
n=vm_config['network']))
118+
try:
119+
last_task = vm.instantiate_vapp()
120+
except BadRequestException as e:
121+
if not vcd_already_exists(e) and not vm_external:
122+
raise
123+
else:
124+
vm.logger.warn('The vm {name} unexpectedly exists.'.format(
125+
name=vm.name))
126+
last_task = None
127+
vm_ctx.instance.runtime_properties['__VM_CREATE_VAPP'] = True
128+
return vm, last_task
129+
130+
131+
@resource_operation
132+
def start_vm(_,
133+
vm_id,
134+
vm_client,
135+
vm_vdc,
136+
vm_config,
137+
vm_class,
138+
vm_ctx):
139+
vapp_name = find_resource_id_from_relationship_by_type(
140+
vm_ctx.instance, REL_VM_VAPP)
141+
vm = vm_class(
142+
vm_id,
143+
vapp_name,
144+
vm_client,
145+
vdc_name=vm_vdc,
146+
kwargs={},
147+
vapp_kwargs=vm_config
148+
)
149+
last_task = vm.power_on()
150+
return vm, last_task
151+
152+
153+
@resource_operation
154+
def stop_vm(_,
155+
vm_id,
156+
vm_client,
157+
vm_vdc,
158+
vm_config,
159+
vm_class,
160+
vm_ctx):
161+
vapp_name = find_resource_id_from_relationship_by_type(
162+
vm_ctx.instance, REL_VM_VAPP)
163+
vm = vm_class(
164+
vm_id,
165+
vapp_name,
166+
vm_client,
167+
vdc_name=vm_vdc,
168+
kwargs={},
169+
vapp_kwargs=vm_config
170+
)
171+
try:
172+
last_task = vm.power_off()
173+
except OperationNotSupportedException as e:
174+
if not vcd_unresolved_vm(e):
175+
raise
176+
last_task = None
177+
return vm, last_task
178+
179+
180+
@resource_operation
181+
def delete_vm(_,
182+
vm_id,
183+
vm_client,
184+
vm_vdc,
185+
vm_config,
186+
vm_class,
187+
vm_ctx):
188+
vapp_name = find_resource_id_from_relationship_by_type(
189+
vm_ctx.instance, REL_VM_VAPP)
190+
vm = vm_class(
191+
vm_id,
192+
vapp_name,
193+
vm_client,
194+
vdc_name=vm_vdc,
195+
kwargs={},
196+
vapp_kwargs=vm_config
197+
)
198+
try:
199+
last_task = vm.undeploy()
200+
except OperationNotSupportedException as e:
201+
if not vcd_unresolved_vm(e):
202+
raise
203+
last_task = None
204+
if vm_ctx.instance.runtime_properties.get('__VM_CREATE_VAPP'):
205+
last_task = vm.vapp_object.delete()
206+
return vm, last_task

0 commit comments

Comments
 (0)