예제 #1
0
 def curl():
     try:
         return subprocess.check_output(shlex.split(cmd))
     except subprocess.CalledProcessError:
         LOG.error("Checking output of curl to the service IP %s "
                   "failed" % self.service_ip)
         raise lib_exc.UnexpectedResponseCode()
예제 #2
0
 def curl():
     output = self.exec_command_in_pod(pod_name, cmd)
     # check if the curl command succeeded
     if not output:
         LOG.error("Curl the service IP %s failed" % self.service_ip)
         raise lib_exc.UnexpectedResponseCode()
     return output
예제 #3
0
    def test_namespace(self):
        # Check resources are created
        namespace_name, namespace = self.create_namespace()

        existing_namespaces = [
            ns.metadata.name for ns in self.list_namespaces().items
        ]

        self.assertIn(namespace_name, existing_namespaces)

        subnet_name = 'ns/' + namespace_name + '-subnet'
        kuryr_net_crd_name = 'ns-' + namespace_name

        seen_subnets = self.os_admin.subnets_client.list_subnets()
        seen_subnet_names = [n['name'] for n in seen_subnets['subnets']]

        self.assertIn(subnet_name, seen_subnet_names)

        subnet_id = [
            n['id'] for n in seen_subnets['subnets']
            if n['name'] == subnet_name
        ]
        net_id = [
            n['network_id'] for n in seen_subnets['subnets']
            if n['name'] == subnet_name
        ]

        kuryr_net_crd = self.get_kuryr_net_crds(kuryr_net_crd_name)

        self.assertIn(kuryr_net_crd_name, kuryr_net_crd['metadata']['name'])
        self.assertIn(kuryr_net_crd['spec']['subnetId'], subnet_id)
        self.assertIn(kuryr_net_crd['spec']['netId'], net_id)

        # Check namespace pod connectivity
        pod_name, pod = self.create_pod(labels={"app": 'pod-label'},
                                        namespace=namespace_name)
        svc_name, _ = self.create_service(pod_label=pod.metadata.labels,
                                          spec_type='LoadBalancer',
                                          namespace=namespace_name)
        svc_service_ip = self.get_service_ip(service_name=svc_name,
                                             spec_type='LoadBalancer',
                                             namespace=namespace_name)
        self.wait_service_status(svc_service_ip,
                                 CONF.kuryr_kubernetes.lb_build_timeout)

        cmd = "curl {dst_ip}".format(dst_ip=svc_service_ip)
        try:
            subprocess.check_output(shlex.split(cmd))
        except subprocess.CalledProcessError:
            LOG.error("Checking output of curl to the service IP %s "
                      "failed" % svc_service_ip)
            raise lib_exc.UnexpectedResponseCode()

        # Check resources are deleted
        self._delete_namespace_resources(namespace_name, kuryr_net_crd,
                                         subnet_name)
예제 #4
0
    def create_object_continue(self,
                               container,
                               object_name,
                               data,
                               metadata=None):
        """Put an object using Expect:100-continue"""
        headers = {}
        if metadata:
            for key in metadata:
                headers[str(key)] = metadata[key]

        headers['X-Auth-Token'] = self.token
        headers['content-length'] = 0 if data is None else len(data)
        headers['Expect'] = '100-continue'

        parsed = urlparse.urlparse(self.base_url)
        path = str(parsed.path) + "/"
        path += "%s/%s" % (str(container), str(object_name))

        conn = create_connection(parsed)

        # Send the PUT request and the headers including the "Expect" header
        conn.putrequest('PUT', path)

        for header, value in six.iteritems(headers):
            conn.putheader(header, value)
        conn.endheaders()

        # Read the 100 status prior to sending the data
        response = conn.response_class(conn.sock,
                                       strict=conn.strict,
                                       method=conn._method)
        _, status, _ = response._read_status()

        # toss the CRLF at the end of the response
        response._safe_read(2)

        # Expecting a 100 here, if not close and throw an exception
        if status != 100:
            conn.close()
            pattern = "%s %s" % (
                """Unexpected http success status code {0}.""",
                """The expected status code is {1}""")
            details = pattern.format(status, 100)
            raise exceptions.UnexpectedResponseCode(details)

        # If a continue was received go ahead and send the data
        # and get the final response
        conn.send(data)

        resp = conn.getresponse()

        return resp.status, resp.reason
예제 #5
0
        def _wait():
            try:
                res = cls.client.get_resource("instances", id)
                cur_status = res["instance"]["status"]
            except exceptions.NotFound:
                if need_delete or "DELETED" in expected_status:
                    LOG.info('Instance %s is deleted', id)
                    raise loopingcall.LoopingCallDone()
                return

            if cur_status in expected_status:
                LOG.info('Instance %s becomes %s', id, cur_status)
                raise loopingcall.LoopingCallDone()
            elif "ERROR" not in expected_status and cur_status == "ERROR":
                # If instance status goes to ERROR but is not expected, stop
                # waiting

                res = cls.admin_client.get_resource("instances", id)
                LOG.info(f'Instance fault msg: {res["instance"].get("fault")}')

                # Show trove-guestagent log for debug purpose.
                # Only admin user is able to publish and show the trove guest
                # agent log. Make sure the container is deleted after fetching
                # the log.
                try:
                    LOG.info(f"Publishing guest log for instance {id}")
                    cls.publish_log(id, 'guest')
                    LOG.info(f"Getting guest log content for instance {id}")
                    log_gen = cls.log_generator(id, 'guest', lines=0)
                    log_content = "".join([chunk for chunk in log_gen()])
                    LOG.info(
                        f"\n=============================================\n"
                        f"Trove guest agent log for instance {id}\n"
                        f"=============================================")
                    LOG.info(log_content)
                except Exception as err:
                    LOG.warning(f"Failed to get guest log for instance {id}, "
                                f"error: {str(err)}")
                finally:
                    # Remove the swift container of database logs.
                    LOG.info(f"Deleting swift container "
                             f"{CONF.database.database_log_container}")
                    cls.delete_swift_containers(
                        cls.admin_container_client, cls.admin_object_client,
                        CONF.database.database_log_container)

                message = "Instance status is ERROR."
                caller = test_utils.find_test_caller()
                if caller:
                    message = '({caller}) {message}'.format(caller=caller,
                                                            message=message)
                raise exceptions.UnexpectedResponseCode(message)
예제 #6
0
 def test_lb_service_curl(self):
     cmd_output_list = list()
     LOG.info("Trying to curl the service IP %s" % self.service_ip)
     cmd = "curl {dst_ip}".format(dst_ip=self.service_ip)
     for i in range(2):
         try:
             cmd_output_list.append(
                 subprocess.check_output(shlex.split(cmd)))
         except subprocess.CalledProcessError:
             LOG.error("Checking output of curl to the service IP %s "
                       "failed" % self.service_ip)
             raise lib_exc.UnexpectedResponseCode()
     self.assertNotEqual(cmp(cmd_output_list[0], cmd_output_list[1]), '0')
예제 #7
0
 def test_pod_service_curl(self):
     cmd_output_list = list()
     pod_name, pod = self.create_pod()
     self.addCleanup(self.delete_pod, pod_name)
     cmd = [
         "/bin/sh", "-c", "curl {dst_ip}".format(dst_ip=self.service_ip)]
     for i in range(2):
         cmd_output_list.append(self.exec_command_in_pod(pod_name, cmd))
         # check if the curl command succeeded
         if not cmd_output_list[i]:
             LOG.error("Curl the service IP %s failed" % self.service_ip)
             raise lib_exc.UnexpectedResponseCode()
     self.assertNotEqual(cmp(cmd_output_list[0], cmd_output_list[1]), '0')
예제 #8
0
        def _wait():
            try:
                res = cls.client.get_resource("backups", id)
                cur_status = res["backup"]["status"]
            except exceptions.NotFound:
                if need_delete or "DELETED" in expected_status:
                    LOG.info('Backup %s is deleted', id)
                    raise loopingcall.LoopingCallDone()
                return

            if cur_status in expected_status:
                LOG.info('Backup %s becomes %s', id, cur_status)
                raise loopingcall.LoopingCallDone()
            elif "FAILED" not in expected_status and cur_status == "FAILED":
                # If backup status goes to FAILED but is not expected, stop
                # waiting
                message = "Backup status is FAILED."
                caller = test_utils.find_test_caller()
                if caller:
                    message = '({caller}) {message}'.format(caller=caller,
                                                            message=message)
                raise exceptions.UnexpectedResponseCode(message)
예제 #9
0
    def _error_checker(self, method, url, headers, body, resp, resp_body):

        # NOTE(mtreinish): Check for httplib response from glance_http. The
        # object can't be used here because importing httplib breaks httplib2.
        # If another object from a class not imported were passed here as
        # resp this could possibly fail
        if str(type(resp)) == "<type 'instance'>":
            ctype = resp.getheader('content-type')
        else:
            try:
                ctype = resp['content-type']
            # NOTE(mtreinish): Keystone delete user responses doesn't have a
            # content-type header. (They don't have a body) So just pretend it
            # is set.
            except KeyError:
                ctype = 'application/json'

        # It is not an error response
        if resp.status < 400:
            return

        JSON_ENC = ['application/json', 'application/json; charset=utf-8']
        # NOTE(mtreinish): This is for compatibility with Glance and swift
        # APIs. These are the return content types that Glance api v1
        # (and occasionally swift) are using.
        TXT_ENC = [
            'text/plain', 'text/html', 'text/html; charset=utf-8',
            'text/plain; charset=utf-8'
        ]

        if ctype.lower() in JSON_ENC:
            parse_resp = True
        elif ctype.lower() in TXT_ENC:
            parse_resp = False
        else:
            raise exceptions.UnexpectedContentType(str(resp.status), resp=resp)

        if resp.status == 401:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.Unauthorized(resp_body, resp=resp)

        if resp.status == 403:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.Forbidden(resp_body, resp=resp)

        if resp.status == 404:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.NotFound(resp_body, resp=resp)

        if resp.status == 400:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.BadRequest(resp_body, resp=resp)

        if resp.status == 410:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.Gone(resp_body, resp=resp)

        if resp.status == 409:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.Conflict(resp_body, resp=resp)

        if resp.status == 413:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            if self.is_absolute_limit(resp, resp_body):
                raise exceptions.OverLimit(resp_body, resp=resp)
            else:
                raise exceptions.RateLimitExceeded(resp_body, resp=resp)

        if resp.status == 415:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.InvalidContentType(resp_body, resp=resp)

        if resp.status == 422:
            if parse_resp:
                resp_body = self._parse_resp(resp_body)
            raise exceptions.UnprocessableEntity(resp_body, resp=resp)

        if resp.status in (500, 501):
            message = resp_body
            if parse_resp:
                try:
                    resp_body = self._parse_resp(resp_body)
                except ValueError:
                    # If response body is a non-json string message.
                    # Use resp_body as is and raise InvalidResponseBody
                    # exception.
                    raise exceptions.InvalidHTTPResponseBody(message)
                else:
                    if isinstance(resp_body, dict):
                        # I'm seeing both computeFault
                        # and cloudServersFault come back.
                        # Will file a bug to fix, but leave as is for now.
                        if 'cloudServersFault' in resp_body:
                            message = resp_body['cloudServersFault']['message']
                        elif 'computeFault' in resp_body:
                            message = resp_body['computeFault']['message']
                        elif 'error' in resp_body:
                            message = resp_body['error']['message']
                        elif 'message' in resp_body:
                            message = resp_body['message']
                    else:
                        message = resp_body

            if resp.status == 501:
                raise exceptions.NotImplemented(resp_body,
                                                resp=resp,
                                                message=message)
            else:
                raise exceptions.ServerFault(resp_body,
                                             resp=resp,
                                             message=message)

        if resp.status >= 400:
            raise exceptions.UnexpectedResponseCode(str(resp.status),
                                                    resp=resp)
예제 #10
0
def wait_for_status(show_client,
                    id,
                    status_key,
                    status,
                    check_interval,
                    check_timeout,
                    root_tag=None,
                    error_ok=False,
                    **kwargs):
    """Waits for an object to reach a specific status.

    :param show_client: The tempest service client show method.
                        Ex. cls.os_primary.servers_client.show_server
    :param id: The id of the object to query.
    :param status_key: The key of the status field in the response.
                       Ex. provisioning_status
    :param status: The status to wait for. Ex. "ACTIVE"
    :check_interval: How often to check the status, in seconds.
    :check_timeout: The maximum time, in seconds, to check the status.
    :root_tag: The root tag on the response to remove, if any.
    :error_ok: When true, ERROR status will not raise an exception.
    :raises CommandFailed: Raised if the object goes into ERROR and ERROR was
                           not the desired status.
    :raises TimeoutException: The object did not achieve the status or ERROR in
                              the check_timeout period.
    :returns: The object details from the show client.
    """
    start = int(time.time())
    LOG.info('Waiting for {name} status to update to {status}'.format(
        name=show_client.__name__, status=status))
    while True:
        if status == const.DELETED:
            try:
                response = show_client(id, **kwargs)
            except exceptions.NotFound:
                return
        else:
            response = show_client(id, **kwargs)

        if root_tag:
            object_details = response[root_tag]
        else:
            object_details = response

        if object_details[status_key] == status:
            LOG.info('{name}\'s status updated to {status}.'.format(
                name=show_client.__name__, status=status))
            return object_details
        elif object_details[status_key] == 'ERROR':
            message = ('{name} {field} updated to an invalid state of '
                       'ERROR'.format(name=show_client.__name__,
                                      field=status_key))
            caller = test_utils.find_test_caller()
            if caller:
                message = '({caller}) {message}'.format(caller=caller,
                                                        message=message)
            if not error_ok:
                raise exceptions.UnexpectedResponseCode(message)
        elif int(time.time()) - start >= check_timeout:
            message = (
                '{name} {field} failed to update to {expected_status} within '
                'the required time {timeout}. Current status of {name}: '
                '{status}'.format(name=show_client.__name__,
                                  timeout=check_timeout,
                                  status=object_details[status_key],
                                  expected_status=status,
                                  field=status_key))
            caller = test_utils.find_test_caller()
            if caller:
                message = '({caller}) {message}'.format(caller=caller,
                                                        message=message)
            raise exceptions.TimeoutException(message)

        time.sleep(check_interval)