Esempio n. 1
0
    def test_add_ip(self):
        """
        Test adding multiple IPs per workload.
        """
        host = DockerHost('host')

        ip11 = "192.168.1.1"
        ip12 = "192.168.1.2"
        ip21 = "192.168.2.1"
        ip22 = "192.168.2.2"
        ip31 = "192.168.3.1"

        node1 = host.create_workload("node1", ip11)
        node2 = host.create_workload("node2")
        host.calicoctl("container add %s %s --interface=hello" % (node2, ip12))

        host.calicoctl("profile add TEST_GROUP")
        host.calicoctl("profile TEST_GROUP member add %s" % node1)
        host.calicoctl("profile TEST_GROUP member add %s" % node2)

        node1.assert_can_ping(ip12, retries=3)

        # Add two more addresses to node1 and one more to node2
        host.calicoctl("container node1 ip add %s" % ip21)
        host.calicoctl("container node1 ip add %s" % ip31)

        host.calicoctl("container %s ip add %s --interface=hello" % (node2, ip22))

        node1.assert_can_ping(ip22)
        node2.assert_can_ping(ip11)
        node2.assert_can_ping(ip21)
        node2.assert_can_ping(ip31)

        # Now stop and restart node 1 and node 2.
        host.execute("docker stop %s" % node1, use_powerstrip=True)
        host.execute("docker stop %s" % node2, use_powerstrip=True)
        host.execute("docker start %s" % node1, use_powerstrip=True)
        host.execute("docker start %s" % node2, use_powerstrip=True)

        # Test pings between the IPs.
        node1.assert_can_ping(ip12, retries=3)
        node1.assert_can_ping(ip22)
        node2.assert_can_ping(ip11)
        node2.assert_can_ping(ip21)
        node2.assert_can_ping(ip31)

        # Now remove and check pings to the removed addresses no longer work.
        host.calicoctl("container %s ip remove %s" % (node1, ip21))
        host.calicoctl("container %s ip remove %s --interface=hello" % (node2, ip22))
        node1.assert_can_ping(ip12)
        node2.assert_can_ping(ip11)
        with self.assertRaises(ErrorReturnCode):
            node1.assert_can_ping(ip22)
        with self.assertRaises(ErrorReturnCode):
            node2.assert_can_ping(ip21)
        node2.assert_can_ping(ip31)

        # Check that we can't remove addresses twice
        with self.assertRaises(ErrorReturnCode):
            host.calicoctl("container %s ip remove %s" % (node1, ip21))
    def test_profile_commands(self):
        """
        Test that the profile rule update command successfully updates.
        """
        host = DockerHost('host', start_calico=False)

        host.calicoctl("profile add TEST_PROFILE")

        json = ('{ "id": "TEST_PROFILE", '
                  '"inbound_rules": [ { "action": "allow", "src_tag": "TEST_PROFILE" }, '
                                     '{ "action": "deny" } ], '
                  '"outbound_rules": [ { "action": "deny" } ] }')

        calicoctl = "/code/dist/calicoctl %s"
        host.execute("echo '%s' | " % json + calicoctl % "profile TEST_PROFILE rule update")

        self.assertIn('1 deny', host.calicoctl("profile TEST_PROFILE rule show").stdout.rstrip())
        json_piece = '"outbound_rules": [\n    {\n      "action": "deny"'
        self.assertIn(json_piece, host.calicoctl("profile TEST_PROFILE rule json").stdout.rstrip())

        # Test that adding and removing a tag works.
        self.assertNotIn("TEST_TAG", self.show_tag(host))
        host.calicoctl("profile TEST_PROFILE tag add TEST_TAG")
        self.assertIn("TEST_TAG", self.show_tag(host))
        host.calicoctl("profile TEST_PROFILE tag remove TEST_TAG")
        self.assertNotIn("TEST_TAG", self.show_tag(host))
Esempio n. 3
0
    def __enter__(self):
        """
        Set up the route reflector clusters when entering context.
        :return: self.
        """
        # Construct the common environment variables passed in when starting
        # the route reflector.
        etcd_auth = "-e ETCD_AUTHORITY=%s:2379" % get_ip()

        # Create the route reflector hosts, grouped by redundancy.
        for ii in range(self.num_redundancy_groups):
            cluster_id = str(IPAddress(0xFF000001 + ii))
            redundancy_group = []
            for jj in range(self.num_in_redundancy_group):
                rr = DockerHost('RR.%d.%d' % (ii, jj), start_calico=False)
                ip = "-e IP=%s" % rr.ip
                rr.execute("docker load --input /code/routereflector.tar")

                # Check which type of etcd is being run, then invoke the
                # suggested curl command to add the RR entry to etcd.
                #
                # See https://github.com/projectcalico/calico-bird/tree/feature-ipinip/build_routereflector
                # for details.
                if os.getenv("ETCD_SCHEME", None) == "https":
                    # Etcd is running with SSL/TLS, pass the key values
                    rr.execute("docker run --privileged --net=host -d "
                               "--name rr %s "
                               "-e ETCD_AUTHORITY=%s:2379 "
                               "-e ETCD_CA_CERT_FILE=%s "
                               "-e ETCD_CERT_FILE=%s "
                               "-e ETCD_KEY_FILE=%s "
                               "-e ETCD_SCHEME=https "
                               "-v %s/certs:%s/certs "
                               "calico/routereflector" %
                               (ip, ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT,
                                ETCD_KEY, CHECKOUT_DIR, CHECKOUT_DIR))
                    rr.execute(
                        r'curl --cacert %s --cert %s --key %s '
                        r'-L https://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                        r'-XPUT -d value="{'
                        r'\"ip\":\"%s\",'
                        r'\"cluster_id\":\"%s\"'
                        r'}"' % (ETCD_CA, ETCD_CERT, ETCD_KEY,
                                 ETCD_HOSTNAME_SSL, rr.ip, rr.ip, cluster_id))

                else:
                    rr.execute("docker run --privileged --net=host -d "
                               "--name rr %s %s "
                               "calico/routereflector" % (etcd_auth, ip))
                    rr.execute(
                        r'curl -L http://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                        r'-XPUT -d value="{'
                        r'\"ip\":\"%s\",'
                        r'\"cluster_id\":\"%s\"'
                        r'}"' % (get_ip(), rr.ip, rr.ip, cluster_id))
                # Store the redundancy group.
                redundancy_group.append(rr)
            self.redundancy_groups.append(redundancy_group)

        return self
    def __enter__(self):
        """
        Set up the route reflector clusters when entering context.
        :return: self.
        """
        # Construct the common environment variables passed in when starting
        # the route reflector.
        etcd_auth = "-e ETCD_AUTHORITY=%s:2379" % get_ip()

        # Create the route reflector hosts, grouped by redundancy.
        for ii in range(self.num_redundancy_groups):
            cluster_id = str(IPAddress(0xFF000001 + ii))
            redundancy_group = []
            for jj in range(self.num_in_redundancy_group):
                rr = DockerHost('RR.%d.%d' % (ii, jj), start_calico=False)
                ip = "-e IP=%s" % rr.ip
                rr.execute("docker load --input /code/routereflector.tar")

                # Check which type of etcd is being run, then invoke the
                # suggested curl command to add the RR entry to etcd.
                #
                # See https://github.com/projectcalico/calico-bird/tree/feature-ipinip/build_routereflector
                # for details.
                if os.getenv("ETCD_SCHEME", None) == "https":
                    # Etcd is running with SSL/TLS, pass the key values
                    rr.execute("docker run --privileged --net=host -d "
                               "--name rr %s "
                               "-e ETCD_AUTHORITY=%s:2379 "
                               "-e ETCD_CA_CERT_FILE=%s "
                               "-e ETCD_CERT_FILE=%s "
                               "-e ETCD_KEY_FILE=%s "
                               "-e ETCD_SCHEME=https "
                               "-v %s/certs:%s/certs "
                               "calico/routereflector" %
                               (ip, ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT,
                                ETCD_KEY, CHECKOUT_DIR,CHECKOUT_DIR))
                    rr.execute(r'curl --cacert %s --cert %s --key %s '
                               r'-L https://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                               r'-XPUT -d value="{'
                                 r'\"ip\":\"%s\",'
                                 r'\"cluster_id\":\"%s\"'
                               r'}"' % (ETCD_CA, ETCD_CERT, ETCD_KEY,
                                        ETCD_HOSTNAME_SSL, rr.ip, rr.ip,
                                        cluster_id))

                else:
                    rr.execute("docker run --privileged --net=host -d "
                           "--name rr %s %s "
                           "calico/routereflector" % (etcd_auth, ip))
                    rr.execute(r'curl -L http://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                               r'-XPUT -d value="{'
                                 r'\"ip\":\"%s\",'
                                 r'\"cluster_id\":\"%s\"'
                               r'}"' % (get_ip(), rr.ip, rr.ip, cluster_id))
                # Store the redundancy group.
                redundancy_group.append(rr)
            self.redundancy_groups.append(redundancy_group)

        return self
    def test_multi_host(self):
        """
        Run a mainline multi-host test. Almost identical in function to the vagrant coreOS demo.
        """
        host1 = DockerHost('host1')
        host2 = DockerHost('host2')
        host1.start_etcd()

        host1_ip = docker.inspect("--format", "'{{ .NetworkSettings.IPAddress }}'", host1.name).stdout.rstrip()
        host2_ip = docker.inspect("--format", "'{{ .NetworkSettings.IPAddress }}'", host2.name).stdout.rstrip()

        etcd_port = "ETCD_AUTHORITY=%s:2379" % host1_ip
        calicoctl = etcd_port + " /code/dist/calicoctl %s"

        host1.listen(calicoctl % "reset || true")

        host1.listen(calicoctl % ("node --ip=%s" % host1_ip))
        host2.listen(calicoctl % ("node --ip=%s" % host2_ip))

        calico_port = "DOCKER_HOST=localhost:2377"

        # Wait for the Calico nodes to be created.
        sleep(3)

        host1.listen("%s docker run -e CALICO_IP=192.168.1.1 --name workload-A -tid busybox" % calico_port)
        host1.listen("%s docker run -e CALICO_IP=192.168.1.2 --name workload-B -tid busybox" % calico_port)
        host1.listen("%s docker run -e CALICO_IP=192.168.1.3 --name workload-C -tid busybox" % calico_port)

        host2.listen("%s docker run -e CALICO_IP=192.168.1.4 --name workload-D -tid busybox" % calico_port)
        host2.listen("%s docker run -e CALICO_IP=192.168.1.5 --name workload-E -tid busybox" % calico_port)

        host1.listen(calicoctl % "profile add PROF_A_C_E")
        host1.listen(calicoctl % "profile add PROF_B")
        host1.listen(calicoctl % "profile add PROF_D")

        host1.listen(calicoctl % "profile PROF_A_C_E member add workload-A")
        host1.listen(calicoctl % "profile PROF_B member add workload-B")
        host1.listen(calicoctl % "profile PROF_A_C_E member add workload-C")

        host2.listen(calicoctl % "profile PROF_D member add workload-D")
        host2.listen(calicoctl % "profile PROF_A_C_E member add workload-E")

        # Wait for the workload networking to converge.
        sleep(1)

        host1.execute("docker exec workload-A ping -c 4 192.168.1.3")

        try:
            host1.execute("docker exec workload-A ping -c 4 192.168.1.2")
            raise
        except ErrorReturnCode_1:
            pass

        try:
            host1.execute("docker exec workload-A ping -c 4 192.168.1.4")
            raise
        except ErrorReturnCode_1:
            pass

        host1.execute("docker exec workload-A ping -c 4 192.168.1.5")
    def test_duplicate_ips(self):
        """
        Start two workloads with the same IP on different hosts. Make sure they
        can be reached from all places even after one of them is deleted.
        """
        host1 = DockerHost('host1')
        host2 = DockerHost('host2')
        host3 = DockerHost('host3')

        # Set up three workloads on three hosts
        workload1 = host1.create_workload("workload1", "192.168.1.1")
        workload2 = host2.create_workload("workload2", "192.168.1.2")
        workload3 = host3.create_workload("workload3", "192.168.1.3")

        # Set up the workloads with duplicate IPs
        dup_ip = "192.168.1.4"
        dup1 = host1.create_workload("dup1", dup_ip)
        dup2 = host2.create_workload("dup2", dup_ip)

        host1.calicoctl("profile add TEST_PROFILE")

        # Add everyone to the same profile
        workload1_epid = host1.calicoctl("container %s endpoint-id show" % workload1).strip()
        host1.calicoctl("endpoint %s profile append TEST_PROFILE" % workload1_epid)

        dup1_epid = host1.calicoctl("container %s endpoint-id show" % dup1).strip()
        host1.calicoctl("endpoint %s profile append TEST_PROFILE" % dup1_epid)

        workload2_epid = host2.calicoctl("container %s endpoint-id show" % workload2).strip()
        host2.calicoctl("endpoint %s profile append TEST_PROFILE" % workload2_epid)

        dup2_epid = host2.calicoctl("container %s endpoint-id show" % dup2).strip()
        host2.calicoctl("endpoint %s profile append TEST_PROFILE" % dup2_epid)

        workload3_dpid = host3.calicoctl("container %s endpoint-id show" % workload3).strip()
        host3.calicoctl("endpoint %s profile append TEST_PROFILE" % workload3_dpid)

        # Check for standard connectivity
        workload1.assert_can_ping(dup_ip, retries=3)
        workload2.assert_can_ping(dup_ip, retries=3)
        workload3.assert_can_ping(dup_ip, retries=3)

        # Delete one of the duplciates.
        host2.execute("docker rm -f dup2")

        # Check standard connectivity still works.
        workload1.assert_can_ping(dup_ip, retries=3)
        workload2.assert_can_ping(dup_ip, retries=3)
        workload3.assert_can_ping(dup_ip, retries=3)
Esempio n. 7
0
 def test_diags(self):
     """
     Test that the diags command successfully uploads the diags file.
     """
     host = DockerHost('host')
     link = host.execute("/code/dist/calicoctl diags")
     assert "https://transfer.sh/" in link
    def test_no_powerstrip(self):
        """
        Test mainline functionality without using powerstrip.
        """
        host = DockerHost("host")

        host.calicoctl("profile add TEST_GROUP")

        # Remove the environment variable such that docker run does not utilize
        # powerstrip.
        node1 = host.create_workload("node1", use_powerstrip=False)
        node2 = host.create_workload("node2", use_powerstrip=False)

        # Attempt to configure the nodes with the same profiles.  This will fail
        # since we didn't use powerstrip to create the nodes.
        with self.assertRaises(ErrorReturnCode):
            host.calicoctl("profile TEST_GROUP member add %s" % node1)
        with self.assertRaises(ErrorReturnCode):
            host.calicoctl("profile TEST_GROUP member add %s" % node2)

        # Add the nodes to Calico networking.
        ip1, ip2 = "192.168.1.1", "192.168.1.2"
        host.calicoctl("container add %s %s" % (node1, ip1))
        host.calicoctl("container add %s %s" % (node2, ip2))

        # Now add the profiles.
        host.calicoctl("profile TEST_GROUP member add %s" % node1)
        host.calicoctl("profile TEST_GROUP member add %s" % node2)

        # Inspect the nodes (ensure this works without powerstrip)
        host.execute("docker inspect %s" % node1)
        host.execute("docker inspect %s" % node2)

        # Check it works
        node1.assert_can_ping(ip1, retries=3)
        node1.assert_can_ping(ip2)
        node2.assert_can_ping(ip1)
        node2.assert_can_ping(ip2)

        # Test the teardown commands
        host.calicoctl("profile remove TEST_GROUP")
        host.calicoctl("container remove %s" % node1)
        host.calicoctl("container remove %s" % node2)
        host.calicoctl("pool remove 192.168.0.0/16")
        host.calicoctl("node stop")
    def __enter__(self):
        """
        Set up the route reflector clusters when entering context.
        :return: self.
        """
        # Construct the common environment variables passed in when starting
        # the route reflector.
        etcd_auth = "-e ETCD_AUTHORITY=%s:2379" % get_ip()

        # Create the route reflector hosts, grouped by redundancy.
        for ii in range(self.num_redundancy_groups):
            cluster_id = str(IPAddress(0xFF000001 + ii))
            redundancy_group = []
            for jj in range(self.num_in_redundancy_group):
                rr = DockerHost('RR.%d.%d' % (ii, jj), start_calico=False)
                ip = "-e IP=%s" % rr.ip
                rr.execute(
                    "docker load --input /code/calico_containers/routereflector.tar"
                )
                rr.execute("docker run --privileged --net=host -d "
                           "--name rr %s %s "
                           "calico/routereflector" % (etcd_auth, ip))

                # Invoke the suggested curl command to add the RR entry to
                # etcd.
                #
                # See https://github.com/projectcalico/calico-bird/tree/feature-ipinip/build_routereflector
                # for details.
                rr.execute(
                    r'curl -L http://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                    r'-XPUT -d value="{'
                    r'\"ip\":\"%s\",'
                    r'\"cluster_id\":\"%s\"'
                    r'}"' % (get_ip(), rr.ip, rr.ip, cluster_id))

                # Store the redundancy group.
                redundancy_group.append(rr)
            self.redundancy_groups.append(redundancy_group)

        return self
    def __enter__(self):
        """
        Set up the route reflector clusters when entering context.
        :return: self.
        """
        # Construct the common environment variables passed in when starting
        # the route reflector.
        etcd_auth = "-e ETCD_AUTHORITY=%s:2379" % get_ip()

        # Create the route reflector hosts, grouped by redundancy.
        for ii in range(self.num_redundancy_groups):
            cluster_id = str(IPAddress(0xFF000001 + ii))
            redundancy_group = []
            for jj in range(self.num_in_redundancy_group):
                rr = DockerHost('RR.%d.%d' % (ii, jj), start_calico=False)
                ip = "-e IP=%s" % rr.ip
                rr.execute("docker load --input /code/calico_containers/routereflector.tar")
                rr.execute("docker run --privileged --net=host -d "
                           "--name rr %s %s "
                           "calico/routereflector" % (etcd_auth, ip))

                # Invoke the suggested curl command to add the RR entry to
                # etcd.
                #
                # See https://github.com/projectcalico/calico-bird/tree/feature-ipinip/build_routereflector
                # for details.
                rr.execute(r'curl -L http://%s:2379/v2/keys/calico/bgp/v1/rr_v4/%s '
                           r'-XPUT -d value="{'
                             r'\"ip\":\"%s\",'
                             r'\"cluster_id\":\"%s\"'
                           r'}"' % (get_ip(), rr.ip, rr.ip, cluster_id))

                # Store the redundancy group.
                redundancy_group.append(rr)
            self.redundancy_groups.append(redundancy_group)

        return self
Esempio n. 11
0
    def run_mainline(self, ip1, ip2):
        """
        Setup two endpoints on one host and check connectivity.
        """
        host = DockerHost('host')
        host.start_etcd()

        host_ip = docker.inspect("--format", "'{{ .NetworkSettings.IPAddress }}'", host.name).stdout.rstrip()
        etcd_port = "ETCD_AUTHORITY=%s:2379" % host_ip
        calicoctl = etcd_port + " /code/dist/calicoctl %s"
        calico_port = "DOCKER_HOST=localhost:2377"

        host.execute("docker run --rm  -v `pwd`:/target jpetazzo/nsenter", _ok_code=[0, 1])

        host.execute(calicoctl % "node --ip=127.0.0.1")
        host.execute(calicoctl % "profile add TEST_GROUP")

        # Wait for powerstrip to come up.
        for i in range(5):
            try:
                host.listen("%s docker ps" % calico_port)
                break
            except ErrorReturnCode:
                if i == 4:
                    raise AssertionError("Powerstrip failed to come up.")
                else:
                    sleep(1)

        host.listen("%s docker run -e CALICO_IP=%s -tid --name=node1 busybox" % (calico_port, ip1))
        host.listen("%s docker run -e CALICO_IP=%s -tid --name=node2 busybox" % (calico_port, ip2))

        # Perform a docker inspect to extract the configured IP addresses.
        node1_ip = host.execute("%s docker inspect --format '{{ .NetworkSettings.IPAddress }}' node1" % calico_port).stdout.rstrip()
        node2_ip = host.execute("%s docker inspect --format '{{ .NetworkSettings.IPAddress }}' node2" % calico_port).stdout.rstrip()

        # Configure the nodes with the same profiles.
        host.listen(calicoctl % "profile TEST_GROUP member add node1")
        host.listen(calicoctl % "profile TEST_GROUP member add node2")

        node1_pid = host.execute("docker inspect --format {{.State.Pid}} node1").stdout.rstrip()
        node2_pid = host.execute("docker inspect --format {{.State.Pid}} node2").stdout.rstrip()

        for i in range(10):
            try:
                host.listen("./nsenter -t %s ping %s -c 1 -W 1" % (node1_pid, node2_ip))
                break
            except ErrorReturnCode:
                if i == 9:
                    raise AssertionError("Network failed to come up.")
                else:
                    sleep(1)

        # Check connectivity.
        host.execute("./nsenter -t %s ping %s -c 1" % (node1_pid, node1_ip))
        host.execute("./nsenter -t %s ping %s -c 1" % (node1_pid, node2_ip))
        host.execute("./nsenter -t %s ping %s -c 1" % (node2_pid, node1_ip))
        host.execute("./nsenter -t %s ping %s -c 1" % (node2_pid, node2_ip))

        # Test calicoctl teardown commands.
        host.execute(calicoctl % "profile remove TEST_GROUP")
        host.execute(calicoctl % "container remove node1")
        host.execute(calicoctl % "container remove node2")
        host.execute(calicoctl % "pool remove 192.168.0.0/16")
        host.execute(calicoctl % "node stop")