#    Copyright 2017 Mirantis, Inc.
#
#    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 os
import requests
import yaml

from devops.helpers import helpers
from devops.error import DevopsCalledProcessError

from tcp_tests import logger
from tcp_tests.helpers import ext
from tcp_tests.helpers.utils import retry
from tcp_tests.managers.execute_commands import ExecuteCommandsMixin
from tcp_tests.managers.k8s import cluster

LOG = logger.logger


class K8SManager(ExecuteCommandsMixin):
    """docstring for K8SManager"""

    __config = None
    __underlay = None

    def __init__(self, config, underlay, salt):
        self.__config = config
        self.__underlay = underlay
        self._salt = salt
        self._api = None
        self._controller_name = None
        self.kubectl = K8SKubectlCli(self)
        self.virtlet = K8SVirtlet(self)
        self.conformance_node = None
        super(K8SManager, self).__init__(config=config, underlay=underlay)

    def install(self, commands):
        self.execute_commands(commands,
                              label='Install Kubernetes services')
        self.__config.k8s.k8s_installed = True
        self.__config.k8s.kube_host = self.get_proxy_api()

    def get_proxy_api(self):
        k8s_proxy_ip_pillars = self._salt.get_pillar(
            tgt='I@haproxy:proxy:enabled:true and I@kubernetes:master',
            pillar='haproxy:proxy:listen:k8s_secure:binds:address')
        k8s_hosts = self._salt.get_pillar(
            tgt='I@haproxy:proxy:enabled:true and I@kubernetes:master',
            pillar='kubernetes:pool:apiserver:host')
        k8s_proxy_ip = set([ip
                            for item in k8s_proxy_ip_pillars
                            for node, ip in item.items() if ip])
        k8s_hosts = set([ip
                         for item in k8s_hosts
                         for node, ip in item.items() if ip])
        assert len(k8s_hosts) == 1, (
            "Found more than one Kubernetes API hosts in pillars:{0}, "
            "expected one!").format(k8s_hosts)
        k8s_host = k8s_hosts.pop()
        assert k8s_host in k8s_proxy_ip, (
            "Kubernetes API host:{0} not found in proxies:{1} "
            "on k8s master nodes. K8s proxies are expected on "
            "nodes with K8s master").format(k8s_host, k8s_proxy_ip)
        return k8s_host

    def _api_init(self):
        ca_result = self.controller_check_call(
            'base64 --wrap=0 /etc/kubernetes/ssl/ca-kubernetes.crt')

        self._api = cluster.K8sCluster(
            user=self.__config.k8s_deploy.kubernetes_admin_user,
            password=self.__config.k8s_deploy.kubernetes_admin_password,
            ca=ca_result['stdout'][0],
            host=self.__config.k8s.kube_host,
            port=self.__config.k8s.kube_apiserver_port)

    @property
    def api(self):
        """
            :rtype: cluster.K8sCluster
        """
        if self._api is None:
            self._api_init()
        return self._api

    def get_controllers(self):
        """ Return list of controllers ssh underlays """
        return [node for node in self.__config.underlay.ssh if
                ext.UNDERLAY_NODE_ROLES.k8s_controller in node['roles']]

    def get_masters(self):
        """ Return list of kubernetes masters hosts fqdn """
        masters_fqdn = self._salt.get_pillar(
            tgt='I@kubernetes:master', pillar='linux:network:fqdn')
        return [self.__underlay.host_by_node_name(node_name=v)
                for pillar in masters_fqdn for k, v in pillar.items()]

    def renew_controller(self, controller_node_name=None):
        """ Changes controller returned by controller_name property """
        if controller_node_name is not None:
            self._controller_name = controller_node_name
            return self._controller_name
        names = [node['node_name'] for node in self.get_controllers()]
        if len(names) == 1 and names[0] == self._controller_name:
            LOG.warn(
                "Cannot change controller because there is only 1 of them")
            return
        else:
            for name in names:
                if name != self._controller_name:
                    self._controller_name = name
                    return

    @property
    def controller_name(self):
        """ Return node name of controller node that used for all actions """
        if self._controller_name is None:
            self.renew_controller()
        return self._controller_name

    @property
    def controller_minion_id(self):
        """ Return node name of controller node that used for all actions """
        minion_ids = [minion_id['minion_id'] for minion_id in
                      self.get_controllers()]
        # we want to return same controller name every time
        minion_ids.sort()
        return minion_ids[0]

    @property
    def is_metallb_enabled(self):
        ctl_tgt = self.controller_minion_id
        LOG.debug("Controller target: {}".format(ctl_tgt))

        result = self._salt.get_pillar(
            tgt=ctl_tgt,
            pillar='kubernetes:common:addons:metallb:enabled')
        metallb = result[0].get(ctl_tgt, False)
        LOG.info("{} kubernetes:common:addons:metallb:enabled: {}"
                 .format(ctl_tgt, bool(metallb)))
        return metallb

    @property
    def is_ingress_nginx_enabled(self):
        ctl_tgt = self.controller_minion_id
        LOG.debug("Controller target: {}".format(ctl_tgt))

        result = self._salt.get_pillar(
            tgt=ctl_tgt,
            pillar='kubernetes:common:addons:ingress-nginx:enabled')
        ingress_nginx = result[0].get(ctl_tgt, False)
        LOG.info("{} kubernetes:common:addons:ingress-nginx:enabled: {}"
                 .format(ctl_tgt, bool(ingress_nginx)))
        return ingress_nginx

    def controller_check_call(self, cmd, **kwargs):
        """ Run command on controller and return result """
        LOG.info("running cmd on k8s controller: {}".format(cmd))
        return self.__underlay.check_call(
            cmd=cmd, node_name=self.controller_name, **kwargs)

    def get_keepalived_vip(self):
        """
        Return k8s VIP IP address

        :return: str, IP address
        """
        ctl_vip_pillar = self._salt.get_pillar(
            tgt="I@kubernetes:control",
            pillar="_param:cluster_vip_address")[0]
        return ctl_vip_pillar.values()[0]

    def run_sample_deployment(self, name, **kwargs):
        return K8SSampleDeployment(self, name, **kwargs)

    def get_pod_ips_from_container(self, pod_name, exclude_local=True,
                                   namespace='default'):
        """ Get ips from container using 'ip a'
            Required for cni-genie multi-cni cases

            :return: list of IP adresses
        """
        cmd = "ip a|grep \"inet \"|awk '{{print $2}}'"
        result = self.kubectl.cli_exec(namespace, pod_name, cmd)['stdout']
        ips = [line.strip().split('/')[0] for line in result]
        if exclude_local:
            ips = [ip for ip in ips if not ip.startswith("127.")]
        return ips

    def update_k8s_version(self, tag):
        """
        Update k8s images tag version in cluster meta and apply required
        for update states

        :param tag: New version tag of k8s images
        :return:
        """
        master_host = self.__config.salt.salt_master_host

        def update_image_tag_meta(config, image_name):
            image_old = config.get(image_name)
            image_base = image_old.split(':')[0]
            image_new = "{}:{}".format(image_base, tag)
            LOG.info("Changing k8s '{0}' image cluster meta to '{1}'".format(
                image_name, image_new))

            with self.__underlay.remote(host=master_host) as r:
                cmd = "salt-call reclass.cluster_meta_set" \
                      " name={0} value={1}".format(image_name, image_new)
                r.check_call(cmd)
            return image_new

        cfg = self.__config

        update_image_tag_meta(cfg.k8s_deploy, "kubernetes_hyperkube_image")
        update_image_tag_meta(cfg.k8s_deploy, "kubernetes_pause_image")
        cfg.k8s.k8s_conformance_image = update_image_tag_meta(
            cfg.k8s, "k8s_conformance_image")

        steps_path = cfg.k8s_deploy.k8s_update_steps_path
        update_commands = self.__underlay.read_template(steps_path)
        self.execute_commands(
            update_commands, label="Updating kubernetes to '{}'".format(tag))

    def run_conformance(self, timeout=60*60, log_out='k8s_conformance.log',
                        raise_on_err=True, node_name=None,
                        api_server='http://127.0.0.1:8080'):
        if node_name is None:
            node_name = self.controller_name
        cmd = "set -o pipefail; docker run --net=host " \
              "-e API_SERVER='{api}' {image} | tee '{log}'".format(
               api=api_server, log=log_out,
               image=self.__config.k8s.k8s_conformance_image)
        return self.__underlay.check_call(
               cmd=cmd, node_name=node_name, timeout=timeout,
               raise_on_err=raise_on_err, verbose=True)

    def run_virtlet_conformance(self, timeout=60 * 120,
                                log_file='virtlet_conformance.log',
                                report_name="report.xml"):
        if self.__config.k8s.run_extended_virtlet_conformance:
            ci_image = "cloud-images.ubuntu.com/xenial/current/" \
                       "xenial-server-cloudimg-amd64-disk1.img"
            cmd = (r"set -o pipefail; "
                   r"docker run --net=host {0} /virtlet-e2e-tests "
                   r"-include-cloud-init-tests -junitOutput {3} "
                   r"-image {2} -sshuser ubuntu -memoryLimit 1024 "
                   r"-alsologtostderr -cluster-url http://127.0.0.1:8080 "
                   r"-ginkgo.focus '\[Conformance\]' "
                   r"| tee {1}".format(
                    self.__config.k8s_deploy.kubernetes_virtlet_image,
                    log_file, ci_image, report_name))
        else:
            cmd = (r"set -o pipefail; "
                   r"docker run --net=host {0} /virtlet-e2e-tests "
                   r"-junitOutput {2} "
                   r"-alsologtostderr -cluster-url http://127.0.0.1:8080 "
                   r"-ginkgo.focus '\[Conformance\]' "
                   r"| tee {1}".format(
                    self.__config.k8s_deploy.kubernetes_virtlet_image,
                    log_file, report_name))
        LOG.info("Executing: {}".format(cmd))
        with self.__underlay.remote(
                node_name=self.controller_name) as remote:
            result = remote.check_call(cmd, timeout=timeout)
            stderr = result['stderr']
            stdout = result['stdout']
            LOG.info("Test results stdout: {}".format(stdout))
            LOG.info("Test results stderr: {}".format(stderr))
        return result

    def start_k8s_cncf_verification(self, timeout=60 * 180):
        """
            Build sonobuoy using golang docker image and install it in system
            Then generate sonobuoy verification manifest using gen command
            and wait for it to end using status annotation
            TODO (vjigulin): All sonobuoy methods can be improved if we define
            correct KUBECONFIG env variable
        """
        cncf_cmd =\
            'docker run --network host --name sonobuoy golang:1.11 bash -c ' \
            '"go get -d -v github.com/heptio/sonobuoy && ' \
            'go install -v github.com/heptio/sonobuoy" && ' \
            'docker cp sonobuoy:/go/bin/sonobuoy /usr/local/bin/ && ' \
            'docker rm sonobuoy && ' \
            'sonobuoy gen | kubectl apply -f -'

        self.controller_check_call(cncf_cmd, timeout=900)

        sonobuoy_pod = self.api.pods.get('sonobuoy', 'heptio-sonobuoy')
        sonobuoy_pod.wait_running()

        def sonobuoy_status():
            annotations = sonobuoy_pod.read().metadata.annotations
            json_status = annotations['sonobuoy.hept.io/status']
            status = yaml.safe_load(json_status)['status']
            if status != 'running':
                LOG.info("CNCF status: {}".format(json_status))
            return yaml.safe_load(json_status)['status']

        LOG.info("Waiting for CNCF to complete")
        helpers.wait(
            lambda: sonobuoy_status() == 'complete',
            interval=120, timeout=timeout,
            timeout_msg="Timeout for CNCF reached."
        )

    def determine_conformance_node(self, target):
        masters_fqdn = self._salt.get_pillar(
            tgt='I@kubernetes:master', pillar='linux:network:fqdn')
        node_names = [v for pillar in masters_fqdn for
                      k, v in pillar.items()]
        return [node_name for node_name
                in node_names
                if node_name.startswith(target)][0]

    def start_conformance_inside_pod(self, cnf_type='k8s', timeout=60 * 60):
        """
        Create conformance pod and wait for results
        :param cnf_type: k8s or virtlet. choose what conformance you want
        :param timeout:
        :return:
        """
        if cnf_type == 'k8s':
            pod_mark = 'conformance'
        elif cnf_type == 'virtlet':
            pod_mark = 'virtlet-conformance'
        else:
            LOG.error("Unknown conformance type or it even not set")
            raise RuntimeError("Unknown conformance type")
        conformance_cmd = "kubectl apply -f /srv/kubernetes/{}.yml" \
                          "".format(pod_mark)
        self.controller_check_call(conformance_cmd, timeout=900)

        cnf_pod = self.api.pods.get(pod_mark, pod_mark)
        cnf_pod.wait_running()

        pod = cnf_pod.read()
        target = "{}.".format(pod.spec.node_name)

        self.conformance_node = self.determine_conformance_node(target)

        def cnf_status():
            pod = cnf_pod.read()
            status = pod.status.phase
            LOG.info("Conformance status: {}".format(status))
            return status

        LOG.info("Waiting for Conformance to complete")
        helpers.wait(
            lambda: cnf_status() in ('Succeeded', 'Failed'),
            interval=120, timeout=timeout,
            timeout_msg="Timeout for Conformance reached."
        )

        pod = cnf_pod.read()
        status = pod.status.phase
        if status == 'Failed':
            describe = "kubectl describe po {0} -n {0}".format(pod_mark)
            LOG.info(self.controller_check_call(describe, timeout=30))
            raise RuntimeError("Conformance failed")

    def get_node_name(self, tgt):
        res = [node_name for node_name in
               self.__underlay.node_names() if tgt in node_name]
        assert len(res) > 0, 'Can not find node name by tgt {}'.format(tgt)
        return res[0]

    def move_file_to_root_folder(self, filepath):
        cmd = "mv {0} /root/".format(filepath)
        if self.conformance_node:
            short_name = self.conformance_node.split('.')[0]
            LOG.info("Managing results on {}".format(self.conformance_node))
            step = {'cmd': cmd, 'node_name': self.get_node_name(
                tgt=short_name)}
            LOG.info('Move {0} to /root/ on {1}'.format(
                filepath, self.conformance_node))
            self.execute_command(step, 'Move files')
        else:
            LOG.info("Node is not properly set")

    def extract_file_to_node(self, system='docker',
                             container='virtlet',
                             file_path='report.xml',
                             out_dir='.',
                             **kwargs):
        """
        Download file from docker or k8s container to node

        :param system: docker or k8s
        :param container: Full name of part of name
        :param file_path: File path in container
        :param kwargs: Used to control pod and namespace
        :param out_dir: Output directory
        :return:
        """
        with self.__underlay.remote(node_name=self.controller_name) as remote:
            if system == 'docker':
                cmd = ("docker ps --all | grep \"{0}\" |"
                       " awk '{{print $1}}'".format(container))
                result = remote.check_call(cmd, raise_on_err=False)
                if result['stdout']:
                    container_id = result['stdout'][0].strip()
                else:
                    LOG.info('No container found, skipping extraction...')
                    return
                cmd = "docker start {}".format(container_id)
                remote.check_call(cmd, raise_on_err=False)
                cmd = "docker cp \"{0}:/{1}\" \"{2}\"".format(
                    container_id, file_path, out_dir)
                remote.check_call(cmd, raise_on_err=False)
            else:
                # system is k8s
                pod_name = kwargs.get('pod_name')
                pod_namespace = kwargs.get('pod_namespace')
                cmd = 'kubectl cp \"{0}/{1}:/{2}\" \"{3}\"'.format(
                    pod_namespace, pod_name, file_path, out_dir)
                remote.check_call(cmd, raise_on_err=False)

    def download_k8s_logs(self, files):
        """
        Download JUnit report and conformance logs from cluster
        :param files:
        :return:
        """
        if self.conformance_node:
            node = self.conformance_node
        else:
            node = self.controller_name
        LOG.info("Trying to get logs at {}".format(node))
        master_host = self.__config.salt.salt_master_host
        with self.__underlay.remote(host=master_host) as r:
            for log_file in files:
                cmd = "scp -r \"{0}:/root/{1}\" /root/".format(
                    node, log_file)
                r.check_call(cmd, raise_on_err=True)
                LOG.info("Downloading the artifact {0}".format(log_file))
                r.download(destination=log_file, target=os.getcwd())
        self.store_server_version(os.path.join(os.getcwd(), 'env_k8s_version'))

    def combine_xunit(self, path, output):
        """
        Function to combine multiple xmls with test results to
        one.

        :param path: Path where xmls to combine located
        :param output: Path to xml file where output will stored
        :return:
        """
        if self.conformance_node:
            node = self.conformance_node
        else:
            node = self.controller_name
        LOG.info("Trying to combine xunit at {}".format(node))
        cmd = ("apt-get install python-setuptools -y; "
               "pip install "
               "https://github.com/mogaika/xunitmerge/archive/master.zip")
        LOG.debug('Installing xunitmerge')
        self._salt.cmd_run(tgt=node, cmd=cmd)
        LOG.debug('Merging xunit')
        cmd = ("cd {0}; arg=''; "
               "for i in $(ls | grep xml); "
               "do arg=\"$arg $i\"; done && "
               "xunitmerge $arg {1} || true".format(path, output))
        self._salt.cmd_run(tgt=node, cmd=cmd)

    def manage_cncf_archive(self):
        """
        Function to untar archive, move files that we are needs to the
        home folder, prepare it to downloading.
        Will generate files on controller node:
            e2e.log, junit_01.xml, cncf_results.tar.gz, version.txt
        :return:
        """

        cmd =\
            "rm -rf cncf_results.tar.gz result && " \
            "mkdir result && " \
            "mv *_sonobuoy_*.tar.gz cncf_results.tar.gz && " \
            "tar -C result -xzf cncf_results.tar.gz && " \
            "mv result/plugins/e2e/results/e2e.log . ; " \
            "mv result/plugins/e2e/results/junit_01.xml . ; " \
            "kubectl version > version.txt"

        self.controller_check_call(cmd, raise_on_err=False)

    @retry(100, exception=DevopsCalledProcessError, interval=20)
    def nslookup(self, host, src):
        """ Run nslookup on controller and return result """
        return self.controller_check_call("nslookup {0} {1}".format(host, src))

    @retry(100, exception=DevopsCalledProcessError, interval=20)
    def curl(self, url, *args):
        """
        Run curl on controller and return stdout

        :param url: url to curl
        :return: list of strings (with /n at end of every line)
        """
        args = list(args)
        args.append(url)
        cmd = "curl -s -S {}".format(
            " ".join(["'{}'".format(a.replace("'", "\\'")) for a in args]))
        result = self.controller_check_call(cmd)
        LOG.debug("{0}\nresult:\n{1}".format(cmd, result['stdout']))
        return result['stdout']

    def store_server_version(self, env_file_path):
        """Store Kubernetes server version in bash source file"""

        def digits(string):
            return ''.join(n for n in string if n.isdigit())

        ver = self.api.api_version.get_code()
        LOG.debug("Got Kubernetes server version:\n{0}".format(ver))

        env_version = ("export KUBE_SERVER_VERSION={0}.{1}\n"
                       "export KUBE_SERVER_GIT_VERSION={2}\n"
                       .format(digits(ver.major),
                               digits(ver.minor),
                               ver.git_version))

        LOG.info("Kubernetes server version is stored to {0}:\n{1}"
                 .format(env_file_path, env_version))
        with open(env_file_path, 'w') as kver:
            kver.write(env_version)


class K8SKubectlCli(object):
    """ Contain kubectl cli commands and api wrappers"""
    def __init__(self, manager):
        self._manager = manager

    def cli_run(self, namespace, name, image, port, replicas=1):
        cmd = "kubectl -n {0} run {1} --image={2} --port={3} --replicas={4}".\
            format(namespace, name, image, port, replicas)
        return self._manager.controller_check_call(cmd)

    def run(self, namespace, name, image, port, replicas=1):
        self.cli_run(namespace, name, image, port, replicas)
        return self._manager.api.deployments.get(
            namespace=namespace, name=name)

    def cli_expose(self, namespace, resource_type, resource_name,
                   service_name=None, port='', service_type='ClusterIP'):
        cmd = "kubectl -n {0} expose {1} {2} --port={3} --type={4}".format(
            namespace, resource_type, resource_name, port, service_type)
        if service_name is not None:
            cmd += " --name={}".format(service_name)
        return self._manager.controller_check_call(cmd)

    def expose(self, resource, service_name=None,
               port='', service_type='ClusterIP'):
        self.cli_expose(resource.namespace, resource.resource_type,
                        resource.name, service_name=service_name,
                        port=port, service_type=service_type)
        return self._manager.api.services.get(
            namespace=resource.namespace, name=service_name or resource.name)

    def cli_exec(self, namespace, pod_name, cmd, container=''):
        kubectl_cmd = "kubectl -n {0} exec --container={1} {2} -- {3}".format(
            namespace, container, pod_name, cmd)
        return self._manager.controller_check_call(kubectl_cmd)

    # def exec(...), except exec is statement in python
    def execute(self, pod, cmd, container=''):
        return self.cli_exec(pod.namespace, pod.name, cmd, container=container)

    def cli_annotate(self, namespace, resource_type, resource_name,
                     annotations, overwrite=False):
        cmd = "kubectl -n {0} annotate {1} {2} {3}".format(
            namespace, resource_type, resource_name, annotations)
        if overwrite:
            cmd += " --overwrite"
        return self._manager.controller_check_call(cmd)

    def annotate(self, resource, annotations, overwrite=False):
        return self.cli_annotate(resource.namespace, resource.resource_type,
                                 resource.name, annotations,
                                 overwrite=overwrite)


class K8SVirtlet(object):
    """ Contain virtlet-related methods"""
    def __init__(self, manager, namespace='kube-system'):
        self._manager = manager
        self._namespace = namespace

    def get_virtlet_node_pod(self, node_name):
        for pod in self._manager.api.pods.list(
                namespace=self._namespace, name_prefix='virtlet-'):
            if pod.read().spec.node_name == node_name:
                return pod
        return None

    def get_pod_dom_uuid(self, pod):
        uuid_name_map = self.virtlet_execute(
            pod.read().spec.node_name, 'virsh list --uuid --name')['stdout']
        for line in uuid_name_map:
            if line.rstrip().endswith("-{}".format(pod.name)):
                return line.split(" ")[0]
        raise Exception("Cannot detect uuid for pod {}".format(pod.name))

    def virsh_domstats(self, pod):
        """ get dict of vm stats """
        uuid = self.get_pod_dom_uuid(pod)
        result = self.virtlet_execute(
            pod.read().spec.node_name, 'virsh domstats {}'.format(uuid))
        stats = dict()
        for line in result['stdout']:
            if '=' in line:
                vals = line.strip().split('=')
                stats[vals[0]] = vals[1]
        return stats

    def virtlet_execute(self, node_name, cmd, container='libvirt'):
        """ execute command inside virtlet container """
        pod = self.get_virtlet_node_pod(node_name)
        return self._manager.kubectl.execute(pod, cmd, container)


class K8SSampleDeployment(object):
    """ Wrapper for deployment run=>expose=>check frequent combination """
    def __init__(self, manager, name,
                 namespace=None,
                 image='gcr.io/google-samples/node-hello:1.0',
                 port=8080,
                 replicas=2):
        namespace = namespace or manager.api.default_namespace

        self._manager = manager
        self._port = port
        self._deployment = \
            manager.kubectl.run(namespace, name,
                                image=image, port=port, replicas=replicas)
        self._index = 1  # used to generate svc name
        self._svc = None  # hold last created svc

    def wait_ready(self, timeout=300, interval=5):
        self._deployment.wait_ready(timeout=timeout, interval=interval)
        return self

    def svc(self):
        """ Return the last exposed service"""
        return self._svc

    def expose(self, service_type='ClusterIP'):
        service_name = "{0}-s{1}".format(self._deployment.name, self._index)
        self._index += 1
        self._svc = self._manager.kubectl.expose(
            self._deployment, port=self._port,
            service_name=service_name, service_type=service_type)
        return self._svc

    def curl(self, svc=None, external=False):
        if svc is None:
            svc = self.svc()
        url = "http://{0}:{1}".format(svc.get_ip(external), self._port)
        if external:
            return requests.get(url).text
        else:
            return self._manager.curl(url)

    def is_service_available(self, svc=None, external=False):
        return "Hello Kubernetes!" in self.curl(svc, external=external)

    def delete(self):
        for svc in self._manager.api.services.list_all(
                name_prefix="{}-s".format(self._deployment.name)):
            svc.delete()
        self._deployment.delete()
