Increase timeout to reach vnf API
[functest.git] / functest / core / cloudify.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2018 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """Cloudify testcase implementation."""
11
12 from __future__ import division
13
14 import logging
15 import time
16 import traceback
17
18 from cloudify_rest_client import CloudifyClient
19 from cloudify_rest_client.executions import Execution
20
21 from functest.core import singlevm
22
23
24 class Cloudify(singlevm.SingleVm2):
25     """Cloudify Orchestrator Case."""
26
27     __logger = logging.getLogger(__name__)
28
29     filename = ('/home/opnfv/functest/images/'
30                 'ubuntu-16.04-server-cloudimg-amd64-disk1.img')
31     flavor_ram = 4096
32     flavor_vcpus = 2
33     flavor_disk = 40
34     username = 'ubuntu'
35     ssh_connect_loops = 12
36     create_server_timeout = 600
37     ports = [80, 443, 5671, 53333]
38
39     cloudify_container = "cloudifyplatform/community:19.01.24"
40
41     def __init__(self, **kwargs):
42         """Initialize Cloudify testcase object."""
43         if "case_name" not in kwargs:
44             kwargs["case_name"] = "cloudify"
45         super(Cloudify, self).__init__(**kwargs)
46         self.cfy_client = None
47
48     def prepare(self):
49         super(Cloudify, self).prepare()
50         for port in self.ports:
51             self.cloud.create_security_group_rule(
52                 self.sec.id, port_range_min=port, port_range_max=port,
53                 protocol='tcp', direction='ingress')
54
55     def execute(self):
56         """
57         Deploy Cloudify Manager.
58         """
59         (_, stdout, stderr) = self.ssh.exec_command(
60             "sudo wget https://get.docker.com/ -O script.sh && "
61             "sudo chmod +x script.sh && "
62             "sudo ./script.sh && "
63             "sudo docker run --name cfy_manager_local -d "
64             "--restart unless-stopped -v /sys/fs/cgroup:/sys/fs/cgroup:ro "
65             "--tmpfs /run --tmpfs /run/lock --security-opt seccomp:unconfined "
66             "--cap-add SYS_ADMIN --network=host {}".format(
67                 self.cloudify_container))
68         self.__logger.debug("output:\n%s", stdout.read())
69         self.__logger.debug("error:\n%s", stderr.read())
70         self.cfy_client = CloudifyClient(
71             host=self.fip.floating_ip_address,
72             username='admin', password='admin', tenant='default_tenant')
73         self.__logger.info("Attemps running status of the Manager")
74         secret_key = "foo"
75         secret_value = "bar"
76         for loop in range(20):
77             try:
78                 self.__logger.debug(
79                     "status %s", self.cfy_client.manager.get_status())
80                 cfy_status = self.cfy_client.manager.get_status()['status']
81                 self.__logger.info(
82                     "The current manager status is %s", cfy_status)
83                 if str(cfy_status) != 'running':
84                     raise Exception("Cloudify Manager isn't up and running")
85                 for secret in iter(self.cfy_client.secrets.list()):
86                     if secret_key == secret["key"]:
87                         self.__logger.debug("Updating secrets: %s", secret_key)
88                         self.cfy_client.secrets.update(
89                             secret_key, secret_value)
90                         break
91                 else:
92                     self.__logger.debug("Creating secrets: %s", secret_key)
93                     self.cfy_client.secrets.create(secret_key, secret_value)
94                 self.cfy_client.secrets.delete(secret_key)
95                 self.__logger.info("Secrets API successfully reached")
96                 break
97             except Exception:  # pylint: disable=broad-except
98                 self.__logger.debug(
99                     "try %s: Cloudify Manager isn't up and running \n%s",
100                     loop + 1, traceback.format_exc())
101                 time.sleep(30)
102         else:
103             self.__logger.error("Cloudify Manager isn't up and running")
104             return 1
105         self.__logger.info("Cloudify Manager is up and running")
106         return 0
107
108
109 def wait_for_execution(client, execution, logger, timeout=3600, ):
110     """Wait for a workflow execution on Cloudify Manager."""
111     # if execution already ended - return without waiting
112     if execution.status in Execution.END_STATES:
113         return execution
114
115     if timeout is not None:
116         deadline = time.time() + timeout
117
118     # Poll for execution status and execution logs, until execution ends
119     # and we receive an event of type in WORKFLOW_END_TYPES
120     offset = 0
121     batch_size = 50
122     event_list = []
123     execution_ended = False
124     while True:
125         event_list = client.events.list(
126             execution_id=execution.id,
127             _offset=offset,
128             _size=batch_size,
129             include_logs=True,
130             sort='@timestamp').items
131
132         offset = offset + len(event_list)
133         for event in event_list:
134             logger.debug(event.get('message'))
135
136         if timeout is not None:
137             if time.time() > deadline:
138                 raise RuntimeError(
139                     'execution of operation {0} for deployment {1} '
140                     'timed out'.format(execution.workflow_id,
141                                        execution.deployment_id))
142             else:
143                 # update the remaining timeout
144                 timeout = deadline - time.time()
145
146         if not execution_ended:
147             execution = client.executions.get(execution.id)
148             execution_ended = execution.status in Execution.END_STATES
149
150         if execution_ended:
151             break
152
153         time.sleep(5)
154
155     return execution
156
157
158 def get_execution_id(client, deployment_id):
159     """
160     Get the execution id of a env preparation.
161
162     network, security group, fip, VM creation
163     """
164     executions = client.executions.list(deployment_id=deployment_id)
165     for execution in executions:
166         if execution.workflow_id == 'create_deployment_environment':
167             return execution
168     raise RuntimeError('Failed to get create_deployment_environment '
169                        'workflow execution.'
170                        'Available executions: {0}'.format(executions))