Beispiel #1
0
    def __init__(self, name, start_calico=True, dind=True):
        self.name = name
        self.dind = dind
        self.workloads = set()

        # This variable is used to assert on destruction that this object was
        # cleaned up.  If not used as a context manager, users of this object
        self._cleaned = False

        if dind:
            docker.rm("-f", self.name, _ok_code=[0, 1])
            docker.run("--privileged", "-v", os.getcwd()+":/code", "--name",
                       self.name,
                       "-e", "DOCKER_DAEMON_ARGS="
                       "--kv-store=consul:%s:8500" % utils.get_ip(),
                       "-tid", "calico/dind")
            self.ip = docker.inspect("--format", "{{ .NetworkSettings.IPAddress }}",
                                     self.name).stdout.rstrip()

            self.ip6 = docker.inspect("--format",
                                      "{{ .NetworkSettings."
                                      "GlobalIPv6Address }}",
                                      self.name).stdout.rstrip()

            # Make sure docker is up
            docker_ps = partial(self.execute, "docker ps")
            retry_until_success(docker_ps, ex_class=CalledProcessError)
            self.execute("docker load --input /code/calico_containers/calico-node.tar && "
                         "docker load --input /code/calico_containers/busybox.tar")
        else:
            self.ip = get_ip()

        if start_calico:
            self.start_calico_node()
            self.assert_driver_up()
Beispiel #2
0
def wipe_etcd():
    _log.debug("Wiping etcd")
    # Delete /calico if it exists. This ensures each test has an empty data
    # store at start of day.
    curl_etcd(get_ip(), "calico", options=["-XDELETE"])

    # Disable Usage Reporting to usage.projectcalico.org
    # We want to avoid polluting analytics data with unit test noise
    curl_etcd(get_ip(),
              "calico/v1/config/UsageReportingEnabled",
              options=["-XPUT -d value=False"])
    curl_etcd(get_ip(),
              "calico/v1/config/LogSeverityScreen",
              options=["-XPUT -d value=debug"])
Beispiel #3
0
def wipe_etcd():
    _log.debug("Wiping etcd")
    # Delete /calico if it exists. This ensures each test has an empty data
    # store at start of day.
    curl_etcd(get_ip(), "calico", options=["-XDELETE"])

    # Disable Usage Reporting to usage.projectcalico.org
    # We want to avoid polluting analytics data with unit test noise
    curl_etcd(get_ip(),
              "calico/v1/config/UsageReportingEnabled",
              options=["-XPUT -d value=False"])
    curl_etcd(get_ip(),
              "calico/v1/config/LogSeverityScreen",
              options=["-XPUT -d value=debug"])
Beispiel #4
0
    def __init__(self, name):
        self.name = name
        self.workloads = set()

        # This variable is used to assert on destruction that this object was
        # cleaned up.  If not used as a context manager, users of this object
        self._cleaned = False

        log_and_run("docker rm -f %s || true" % self.name)
        log_and_run("docker run --privileged -tid"
                    "-v `pwd`/docker:/usr/local/bin/docker "
                    "-v %s:/code --name %s "
                    "calico/dind:libnetwork  --cluster-store=etcd://%s:2379" %
                    (os.getcwd(), self.name, utils.get_ip()))

        self.ip = log_and_run("docker inspect --format "
                              "'{{ .NetworkSettings.IPAddress }}' %s" %
                              self.name)

        # Make sure docker is up
        docker_ps = partial(self.execute, "docker ps")
        retry_until_success(docker_ps, ex_class=CalledProcessError, retries=10)

        self.execute("gunzip -c /code/calico-node.tgz | docker load")
        self.execute("gunzip -c /code/busybox.tgz | docker load")
        self.execute(
            "gunzip -c /code/calico-node-libnetwork.tgz | docker load")

        self.start_calico_node()
Beispiel #5
0
    def execute(self, command):
        """
        Pass a command into a host container.

        Raises a CommandExecError() if the command returns a non-zero
        return code.

        :param command:  The command to execute.
        :return: The output from the command with leading and trailing
        whitespace removed.
        """
        etcd_auth = "ETCD_AUTHORITY=%s:2379" % get_ip()
        # Export the environment, in case the command has multiple parts, e.g.
        # use of | or ;
        command = "export %s; %s" % (etcd_auth, command)

        if self.dind:
            command = self.escape_bash_single_quotes(command)
            command = "docker exec -it %s bash -c '%s'" % (self.name,
                                                           command)
        try:
            output = check_output(command, shell=True, stderr=STDOUT)
        except CalledProcessError as e:
            # Wrap the original exception with one that gives a better error
            # message (including command output).
            raise CommandExecError(e)
        else:
            return output.strip()
Beispiel #6
0
 def setUp(self):
     try:
         self.host.execute("docker rm -f calico-node")
     except CommandExecError:
         # Presumably calico-node wasn't running
         pass
     wipe_etcd(get_ip())
Beispiel #7
0
def test_converter(testname, fail_expected, error_text=None):
    """
    Convert a v1 object to v3, then apply the result and read it back.
    """
    test_converter.__name__ = testname
    # Let's start every test afresh
    wipe_etcd(get_ip())
    testdata = data[testname]

    # Convert data to V3 API using the tool under test
    rc = calicoctl("convert", data=testdata)
    if not fail_expected:
        logger.debug("Trying to convert manifest from V1 to V3")
        rc.assert_no_error()
        # Get the converted yaml and clean it up (remove fields we don't care about)
        converted_data = clean_calico_data(yaml.safe_load(rc.output))
        original_resource = rc

        # Apply the converted data
        rc = calicoctl("create", data=original_resource.output)
        logger.debug("Trying to create resource using converted manifest")
        rc.assert_no_error()
        rc = calicoctl("get %s %s -o yaml" % (converted_data['kind'], name(converted_data)))

        # Comparison here needs to be against cleaned versions of data to remove Creation Timestamp
        logger.debug("Comparing 'get'ted output with original converted yaml")
        cleaned_output = yaml.safe_dump(
            clean_calico_data(
                yaml.safe_load(rc.output),
                extra_keys_to_remove=['projectcalico.org/orchestrator', 'namespace']
            )
        )
        original_resource.assert_data(cleaned_output)
    else:
        rc.assert_error(error_text)
 def setUp(self):
     try:
         self.host.execute("docker rm -f calico-node")
     except CommandExecError:
         # Presumably calico-node wasn't running
         pass
     wipe_etcd(get_ip())
    def __init__(self, name):
        self.name = name
        self.workloads = set()

        # This variable is used to assert on destruction that this object was
        # cleaned up.  If not used as a context manager, users of this object
        self._cleaned = False

        log_and_run("docker rm -f %s || true" % self.name)
        log_and_run("docker run --privileged -tid"
                    "-v `pwd`/docker:/usr/local/bin/docker "
                    "-v %s:/code --name %s "
                    "calico/dind:libnetwork  --cluster-store=etcd://%s:2379" %
                    (os.getcwd(), self.name, utils.get_ip()))

        self.ip = log_and_run("docker inspect --format "
                              "'{{ .NetworkSettings.IPAddress }}' %s" % self.name)

        # Make sure docker is up
        docker_ps = partial(self.execute, "docker ps")
        retry_until_success(docker_ps, ex_class=CalledProcessError,
                            retries=10)

        self.execute("gunzip -c /code/calico-node.tgz | docker load")
        self.execute("gunzip -c /code/busybox.tgz | docker load")
        self.execute("gunzip -c /code/calico-node-libnetwork.tgz | docker load")

        self.start_calico_node()
Beispiel #10
0
    def __init__(self, name, start_calico=True, dind=True):
        self.name = name
        self.dind = dind
        self.workloads = set()

        # This variable is used to assert on destruction that this object was
        # cleaned up.  If not used as a context manager, users of this object
        self._cleaned = False

        if dind:
            # TODO use pydocker
            docker.rm("-f", self.name, _ok_code=[0, 1])
            docker.run("--privileged", "-v", os.getcwd()+":/code", "--name",
                       self.name,
                       "-tid", "calico/dind")
            self.ip = docker.inspect("--format", "{{ .NetworkSettings.IPAddress }}",
                                     self.name).stdout.rstrip()

            self.ip6 = docker.inspect("--format",
                                      "{{ .NetworkSettings."
                                      "GlobalIPv6Address }}",
                                      self.name).stdout.rstrip()

            # Make sure docker is up
            docker_ps = partial(self.execute, "docker ps")
            retry_until_success(docker_ps, ex_class=CalledProcessError,
                                retries=100)
            self.execute("docker load --input /code/calico_containers/calico-node.tar && "
                         "docker load --input /code/calico_containers/busybox.tar")
        else:
            self.ip = get_ip()

        if start_calico:
            self.start_calico_node()
 def setUp(self):
     """
     Clean up before every test.
     """
     self.ip = get_ip()
     # Delete /calico if it exists. This ensures each test has an empty data
     # store at start of day.
     subprocess.check_output("curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE" % self.ip, shell=True)
 def setUp(self):
     """
     Clean up before every test.
     """
     self.ip = get_ip()
     # Delete /calico if it exists. This ensures each test has an empty data
     # store at start of day.
     subprocess.check_output(
         "curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE"
         % self.ip, shell=True)
Beispiel #13
0
    def setUpClass(cls):
        wipe_etcd(get_ip())

        # Rough idea for setup
        #
        #    Network1                  Network2
        #
        #   container1                 container2
        #    foo = bar                  baz = bop
        #
        #   container3                 container4
        #    foo = bing                 foo = bar

        cls.hosts = []
        cls.host1 = DockerHost(
            "host1",
            additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
            post_docker_commands=POST_DOCKER_COMMANDS,
            start_calico=False,
            networking=NETWORKING_LIBNETWORK)
        cls.host1_hostname = cls.host1.execute("hostname")
        cls.hosts.append(cls.host1)
        cls.host2 = DockerHost(
            "host2",
            additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
            post_docker_commands=POST_DOCKER_COMMANDS,
            start_calico=False,
            networking=NETWORKING_LIBNETWORK)
        cls.host2_hostname = cls.host1.execute("hostname")
        cls.hosts.append(cls.host2)

        for host in cls.hosts:
            host.start_calico_node(
                options='--use-docker-networking-container-labels')

        cls.network1 = cls.host1.create_network("network1")
        cls.network2 = cls.host1.create_network("network2")

        cls.workload1_nw1_foo_bar = cls.host1.create_workload(
            "workload1",
            network=cls.network1,
            labels=["org.projectcalico.label.foo=bar"])
        cls.workload2_nw2_baz_bop = cls.host1.create_workload(
            "workload2",
            network=cls.network2,
            labels=["org.projectcalico.label.baz=bop"])
        cls.workload3_nw1_foo_bing = cls.host2.create_workload(
            "workload3",
            network=cls.network1,
            labels=["org.projectcalico.label.foo=bing"])
        cls.workload4_nw2_foo_bar = cls.host2.create_workload(
            "workload4",
            network=cls.network2,
            labels=["org.projectcalico.label.foo=bar"])
def test_empty_datastore(cmd):
    """
    Test dry-run and start when the etcdv2 datastore is empty.
    """
    wipe_etcdv2(get_ip())
    dump_etcdv2()
    rcu = calicoupgrade(cmd)
    logger.debug(
        "INFO: empty etcdv2 datastore: Expecting a non-zero" +
        "return code for calico-upgrade %s.", cmd)
    rcu.assert_error()
Beispiel #15
0
    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = get_ip()

        # Delete /calico if it exists. This ensures each test has an empty data
        # store at start of day.
        subprocess.check_output(
            "curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE"
            % self.ip, shell=True)

        # Log a newline to ensure that the first log appears on its own line.
        logger.info("")
Beispiel #16
0
    def setUpClass(cls):
        wipe_etcd(get_ip())

        # Rough idea for setup
        #
        #    Network1                  Network2
        #
        #   container1                 container2
        #    foo = bar                  baz = bop
        #
        #   container3                 container4
        #    foo = bing                 foo = bar

        cls.hosts = []
        cls.host1 = DockerHost(
                "host1",
                additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
                post_docker_commands=POST_DOCKER_COMMANDS,
                start_calico=False,
                networking=NETWORKING_LIBNETWORK)
        cls.host1_hostname = cls.host1.execute("hostname")
        cls.hosts.append(cls.host1)
        cls.host2 = DockerHost(
                "host2",
                additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
                post_docker_commands=POST_DOCKER_COMMANDS,
                start_calico=False,
                networking=NETWORKING_LIBNETWORK)
        cls.host2_hostname = cls.host1.execute("hostname")
        cls.hosts.append(cls.host2)

        for host in cls.hosts:
            host.start_calico_node(options='--use-docker-networking-container-labels')

        cls.network1 = cls.host1.create_network("network1")
        cls.network2 = cls.host1.create_network("network2")

        cls.workload1_nw1_foo_bar = cls.host1.create_workload(
                "workload1", network=cls.network1,
                labels=["org.projectcalico.label.foo=bar"])
        cls.workload2_nw2_baz_bop = cls.host1.create_workload(
                "workload2", network=cls.network2,
                labels=["org.projectcalico.label.baz=bop"])
        cls.workload3_nw1_foo_bing = cls.host2.create_workload(
                "workload3", network=cls.network1,
                labels=["org.projectcalico.label.foo=bing"])
        cls.workload4_nw2_foo_bar = cls.host2.create_workload(
                "workload4", network=cls.network2,
                labels=["org.projectcalico.label.foo=bar"])
Beispiel #17
0
    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = get_ip()

        # Delete /calico if it exists. This ensures each test has an empty data
        # store at start of day.
        subprocess.check_output(
            "curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE" %
            self.ip,
            shell=True)

        # Log a newline to ensure that the first log appears on its own line.
        logger.info("")
    def calicoctl(self, command):
        """
        Convenience function for abstracting away calling the calicoctl
        command.

        Raises a CommandExecError() if the command returns a non-zero
        return code.

        :param command:  The calicoctl command line parms as a single string.
        :return: The output from the command with leading and trailing
        whitespace removed.
        """
        command = "/code/calicoctl " + command
        etcd_auth = "ETCD_AUTHORITY=%s:2379" % get_ip()
        # Export the environment, in case the command has multiple parts, e.g.
        # use of | or ;
        command = "export %s; %s" % (etcd_auth, command)
        return self.execute(command)
Beispiel #19
0
    def calicoctl(self, command):
        """
        Convenience function for abstracting away calling the calicoctl
        command.

        Raises a CommandExecError() if the command returns a non-zero
        return code.

        :param command:  The calicoctl command line parms as a single string.
        :return: The output from the command with leading and trailing
        whitespace removed.
        """
        command = "/code/calicoctl " + command
        etcd_auth = "ETCD_AUTHORITY=%s:2379" % get_ip()
        # Export the environment, in case the command has multiple parts, e.g.
        # use of | or ;
        command = "export %s; %s" % (etcd_auth, command)
        return self.execute(command)
Beispiel #20
0
    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = get_ip()

        # Delete /calico if it exists. This ensures each test has an empty data
        # store at start of day.
        if ETCD_SCHEME == "https":
            # Etcd is running with SSL/TLS, require key/certificates
            subprocess.check_output(
                "curl --cacert %s --cert %s --key %s "
                "-sL https://%s:2379/v2/keys/calico?recursive=true -XDELETE"
                % (ETCD_CA, ETCD_CERT, ETCD_KEY, self.ip),
                shell=True)
        else:
            subprocess.check_output(
                "curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE"
                % self.ip, shell=True)

        # Log a newline to ensure that the first log appears on its own line.
        logger.info("")
Beispiel #21
0
    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = get_ip()

        # Delete /calico if it exists. This ensures each test has an empty data
        # store at start of day.
        if ETCD_SCHEME == "https":
            # Etcd is running with SSL/TLS, require key/certificates
            subprocess.check_output(
                "curl --cacert %s --cert %s --key %s "
                "-sL https://%s:2379/v2/keys/calico?recursive=true -XDELETE"
                % (ETCD_CA, ETCD_CERT, ETCD_KEY, self.ip),
                shell=True)
        else:
            subprocess.check_output(
                "curl -sL http://%s:2379/v2/keys/calico?recursive=true -XDELETE"
                % self.ip, shell=True)

        # Log a newline to ensure that the first log appears on its own line.
        logger.info("")
Beispiel #22
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.
import os
import subprocess
from unittest import TestCase

from tests.st.utils.utils import (get_ip, ETCD_SCHEME, ETCD_CA, ETCD_CERT,
                                  ETCD_KEY, debug_failures)
import logging

HOST_IPV6 = get_ip(v6=True)

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)

# Disable spammy logging from the sh module
sh_logger = logging.getLogger("sh")
sh_logger.setLevel(level=logging.CRITICAL)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """
    def setUp(self):
        """
Beispiel #23
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.
import json
import subprocess
from unittest import TestCase

from tests.st.utils.utils import (get_ip, ETCD_SCHEME, ETCD_CA, ETCD_CERT,
                                  ETCD_KEY, debug_failures, ETCD_HOSTNAME_SSL)
import logging

HOST_IPV6 = get_ip(v6=True)
HOST_IPV4 = get_ip()

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)

# Disable spammy logging from the sh module
sh_logger = logging.getLogger("sh")
sh_logger.setLevel(level=logging.CRITICAL)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """
    def setUp(self):
Beispiel #24
0
# 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 logging
from unittest import TestCase

from tests.st.utils.utils import (get_ip, wipe_etcd, calicoctl)

HOST_IPV4 = get_ip()

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """

    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = HOST_IPV4
logger = logging.getLogger(__name__)

POST_DOCKER_COMMANDS = ["docker load -i /code/calico-node.tgz",
                        "docker load -i /code/busybox.tgz",
                        "docker load -i /code/calico-node-libnetwork.tgz"]

if ETCD_SCHEME == "https":
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " \
                                "--cluster-store-opt kv.cacertfile=%s " \
                                "--cluster-store-opt kv.certfile=%s " \
                                "--cluster-store-opt kv.keyfile=%s " % \
                                (ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT,
                                 ETCD_KEY)
else:
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \
                                utils.get_ip()

class TestMainline(TestBase):
    def test_mainline(self):
        """
        Setup two endpoints on one host and check connectivity then teardown.
        """
        # TODO - add in IPv6 as part of this flow.
        with DockerHost('host',
                        additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
                        post_docker_commands=POST_DOCKER_COMMANDS,
                        start_calico=False) as host:
            host.start_calico_node("--libnetwork")

            # Set up two endpoints on one host
            network = host.create_network("testnet")
Beispiel #26
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.
import logging
from unittest import TestCase

from tests.st.utils.utils import (get_ip, wipe_etcdv2, wipe_etcdv3,
                                  set_version_etcdv2, set_ready_etcdv2,
                                  get_value_etcdv2)

HOST_IPV4 = get_ip()

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """
    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = HOST_IPV4
        self.wipe_etcdv2()
Beispiel #27
0
# 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 json
import yaml
import logging
import subprocess
from pprint import pformat
from unittest import TestCase

from deepdiff import DeepDiff

from tests.st.utils.utils import (get_ip, ETCD_SCHEME, ETCD_CA, ETCD_CERT,
                                  ETCD_KEY, debug_failures, ETCD_HOSTNAME_SSL)

HOST_IPV6 = get_ip(v6=True)
HOST_IPV4 = get_ip()

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)

# Disable spammy logging from the sh module
sh_logger = logging.getLogger("sh")
sh_logger.setLevel(level=logging.CRITICAL)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """
    def setUp(self):
Beispiel #28
0
# 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 subprocess
from unittest import TestCase

from tests.st.utils.utils import get_ip
import logging

HOST_IPV6 = get_ip(v6=True)

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)

# Disable spammy logging from the sh module
sh_logger = logging.getLogger("sh")
sh_logger.setLevel(level=logging.CRITICAL)


class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """
    def setUp(self):
        """
Beispiel #29
0
POST_DOCKER_COMMANDS = [
    "docker load -i /code/calico-node.tgz", "docker load -i /code/busybox.tgz",
    "docker load -i /code/calico-node-libnetwork.tgz"
]

if ETCD_SCHEME == "https":
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " \
                                "--cluster-store-opt kv.cacertfile=%s " \
                                "--cluster-store-opt kv.certfile=%s " \
                                "--cluster-store-opt kv.keyfile=%s " % \
                                (ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT,
                                 ETCD_KEY)
else:
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \
                                utils.get_ip()


class TestMainline(TestBase):
    def test_mainline(self):
        """
        Setup two endpoints on one host and check connectivity then teardown.
        """
        # TODO - add in IPv6 as part of this flow.
        with DockerHost('host',
                        additional_docker_options=ADDITIONAL_DOCKER_OPTIONS,
                        post_docker_commands=POST_DOCKER_COMMANDS,
                        start_calico=False) as host:
            host.start_calico_node("--libnetwork")

            # Set up two endpoints on one host
POST_DOCKER_COMMANDS = [
    "docker load -i /code/calico-node.tar",
    "docker load -i /code/busybox.tar",
    "docker load -i /code/workload.tar",
]

if ETCD_SCHEME == "https":
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " \
                                "--cluster-store-opt kv.cacertfile=%s " \
                                "--cluster-store-opt kv.certfile=%s " \
                                "--cluster-store-opt kv.keyfile=%s " % \
                                (ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT,
                                 ETCD_KEY)
else:
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \
                                get_ip()


class TestLibnetworkLabeling(TestBase):
    """
    Tests that labeling is correctly implemented in libnetwork.  Setup
    multiple networks and then run containers with labels and see that
    policy will allow and block traffic.
    """
    hosts = None
    host = None

    @classmethod
    def setUpClass(cls):
        wipe_etcd(get_ip())
    ETCD_CERT,
    ETCD_KEY,
    ETCD_HOSTNAME_SSL,
    ETCD_SCHEME,
    get_ip,
    check_bird_status,
)

if ETCD_SCHEME == "https":
    ADDITIONAL_DOCKER_OPTIONS = (
        "--cluster-store=etcd://%s:2379 "
        "--cluster-store-opt kv.cacertfile=%s "
        "--cluster-store-opt kv.certfile=%s "
        "--cluster-store-opt kv.keyfile=%s " % (ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT, ETCD_KEY)
    )
else:
    ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % get_ip()


def create_bgp_peer(host, scope, ip, asNum):
    assert scope in ("node", "global")
    node = host.get_hostname() if scope == "node" else ""
    testdata = {
        "apiVersion": "v1",
        "kind": "bgpPeer",
        "metadata": {"scope": scope, "node": node, "peerIP": ip},
        "spec": {"asNumber": asNum},
    }
    host.writefile("testfile.yaml", testdata)
    host.calicoctl("create -f testfile.yaml")