files.new_contents: # Copyright 2015 Tigera, 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 copy
  import netaddr
  import yaml
  from nose_parameterized import parameterized
  
  from tests.st.test_base import TestBase
  from tests.st.utils.docker_host import DockerHost, CLUSTER_STORE_DOCKER_OPTIONS
  from tests.st.utils.exceptions import CommandExecError
  from tests.st.utils.utils import assert_network, assert_profile, \
      assert_number_endpoints, get_profile_name
  
  POST_DOCKER_COMMANDS = ["docker load -i /code/calico-node.tar",
                          "docker load -i /code/busybox.tar",
                          "docker load -i /code/workload.tar"]
  
  
  class MultiHostMainline(TestBase):
      @parameterized.expand([
          #"tags",
          ("rules.tags", False),
          ("rules.tags", True),
          #"rules.protocol.icmp",
          #"rules.ip.addr",
          #"rules.ip.net",
          #"rules.selector",
          #"rules.tcp.port",
          #"rules.udp.port",
      ])
      def test_multi_host(self, test_type, simulate_gce_routing):
          """
          Run a mainline multi-host test.
          Because multihost tests are slow to setup, this tests most mainline
          functionality in a single test.
          - Create two hosts
          - Create a network using the default IPAM driver, and a workload on
            each host assigned to that network.
          - Create a network using the Calico IPAM driver, and a workload on
            each host assigned to that network.
          - Check that hosts on the same network can ping each other.
          - Check that hosts on different networks cannot ping each other.
          - Modify the profile rules
          - Check that connectivity has changed to match the profile we set up
          - Re-apply the original profile
          - Check that connectivity goes back to what it was originally.
          """
          with DockerHost("host1",
                          additional_docker_options=CLUSTER_STORE_DOCKER_OPTIONS,
                          post_docker_commands=POST_DOCKER_COMMANDS,
                          simulate_gce_routing=simulate_gce_routing,
                          start_calico=False) as host1, \
                  DockerHost("host2",
                             additional_docker_options=CLUSTER_STORE_DOCKER_OPTIONS,
                             post_docker_commands=POST_DOCKER_COMMANDS,
                             simulate_gce_routing=simulate_gce_routing,
                             start_calico=False) as host2:
              (n1_workloads, n2_workloads, networks) = \
                  self._setup_workloads(host1, host2, simulate_gce_routing)
  
              # Get the original profiles:
              output = host1.calicoctl("get profile -o yaml")
              original_profiles = yaml.safe_load(output)
              # Make a copy of the profiles to mess about with.
              new_profiles = copy.deepcopy(original_profiles)
  
              if test_type == "tags":
                  profile0_tag = new_profiles[0]['metadata']['tags'][0]
                  profile1_tag = new_profiles[1]['metadata']['tags'][0]
                  # Make a new profiles dict where the two networks have each
                  # other in their tags list
                  new_profiles[0]['metadata']['tags'].append(profile1_tag)
                  new_profiles[1]['metadata']['tags'].append(profile0_tag)
  
                  self._apply_new_profile(new_profiles, host1)
                  # Check everything can contact everything else now
                  self.assert_connectivity(retries=2,
                                           pass_list=n1_workloads + n2_workloads)
  
              elif test_type == "rules.tags":
                  profile0_tag = new_profiles[0]['metadata']['tags'][0]
                  profile1_tag = new_profiles[1]['metadata']['tags'][0]
                  rule0 = {'action': 'allow',
                           'source':
                               {'tag': profile1_tag}}
                  rule1 = {'action': 'allow',
                           'source':
  
  
  [... the rest is omitted ...]
files.new_path: tests/st/policy/test_profile.py
files.old_contents: # Copyright 2015 Tigera, 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 copy
  import netaddr
  import yaml
  from nose_parameterized import parameterized
  
  from tests.st.test_base import TestBase
  from tests.st.utils.docker_host import DockerHost, CLUSTER_STORE_DOCKER_OPTIONS
  from tests.st.utils.exceptions import CommandExecError
  from tests.st.utils.utils import assert_network, assert_profile, \
      assert_number_endpoints, get_profile_name
  
  POST_DOCKER_COMMANDS = ["docker load -i /code/calico-node.tar",
                          "docker load -i /code/busybox.tar",
                          "docker load -i /code/workload.tar"]
  
  
  class MultiHostMainline(TestBase):
      @parameterized.expand([
          #"tags",
          "rules.tags",
          #"rules.protocol.icmp",
          #"rules.ip.addr",
          #"rules.ip.net",
          #"rules.selector",
          #"rules.tcp.port",
          #"rules.udp.port",
      ])
      def test_multi_host(self, test_type):
          """
          Run a mainline multi-host test.
          Because multihost tests are slow to setup, this tests most mainline
          functionality in a single test.
          - Create two hosts
          - Create a network using the default IPAM driver, and a workload on
            each host assigned to that network.
          - Create a network using the Calico IPAM driver, and a workload on
            each host assigned to that network.
          - Check that hosts on the same network can ping each other.
          - Check that hosts on different networks cannot ping each other.
          - Modify the profile rules
          - Check that connectivity has changed to match the profile we set up
          - Re-apply the original profile
          - Check that connectivity goes back to what it was originally.
          """
          with DockerHost("host1",
                          additional_docker_options=CLUSTER_STORE_DOCKER_OPTIONS,
                          post_docker_commands=POST_DOCKER_COMMANDS,
                          start_calico=False) as host1, \
                  DockerHost("host2",
                             additional_docker_options=CLUSTER_STORE_DOCKER_OPTIONS,
                             post_docker_commands=POST_DOCKER_COMMANDS,
                             start_calico=False) as host2:
              (n1_workloads, n2_workloads, networks) = \
                  self._setup_workloads(host1, host2)
  
              # Get the original profiles:
              output = host1.calicoctl("get profile -o yaml")
              original_profiles = yaml.safe_load(output)
              # Make a copy of the profiles to mess about with.
              new_profiles = copy.deepcopy(original_profiles)
  
              if test_type == "tags":
                  profile0_tag = new_profiles[0]['metadata']['tags'][0]
                  profile1_tag = new_profiles[1]['metadata']['tags'][0]
                  # Make a new profiles dict where the two networks have each
                  # other in their tags list
                  new_profiles[0]['metadata']['tags'].append(profile1_tag)
                  new_profiles[1]['metadata']['tags'].append(profile0_tag)
  
                  self._apply_new_profile(new_profiles, host1)
                  # Check everything can contact everything else now
                  self.assert_connectivity(retries=2,
                                           pass_list=n1_workloads + n2_workloads)
  
              elif test_type == "rules.tags":
                  profile0_tag = new_profiles[0]['metadata']['tags'][0]
                  profile1_tag = new_profiles[1]['metadata']['tags'][0]
                  rule0 = {'action': 'allow',
                           'source':
                               {'tag': profile1_tag}}
                  rule1 = {'action': 'allow',
                           'source':
                               {'tag': profile0_tag}}
                  new_profiles[0]['spec']['ingress'].append(rule0)
                  new_profiles[1]['spec']['ingress'].append(rule1)
                  self._apply_new_profile(new_pro
  
  [... the rest is omitted ...]
files.old_path: tests/st/policy/test_profile.py
files.new_contents: # Copyright (c) 2015-2017 Tigera, Inc. All rights reserved.
  #
  # 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 logging
  import json
  import os
  import uuid
  import yaml
  from functools import partial
  from subprocess import CalledProcessError, Popen, PIPE
  
  from log_analyzer import LogAnalyzer, FELIX_LOG_FORMAT, TIMESTAMP_FORMAT
  from network import DockerNetwork
  from tests.st.utils.exceptions import CommandExecError
  from utils import get_ip, log_and_run, retry_until_success, ETCD_SCHEME, \
      ETCD_CA, ETCD_KEY, ETCD_CERT, ETCD_HOSTNAME_SSL
  from workload import Workload
  
  logger = logging.getLogger(__name__)
  # We want to default CHECKOUT_DIR if either the ENV var is unset
  # OR its set to an empty string.
  CHECKOUT_DIR = os.getenv("HOST_CHECKOUT_DIR", "")
  if CHECKOUT_DIR == "":
      CHECKOUT_DIR = os.getcwd()
  
  NODE_CONTAINER_NAME = os.getenv("NODE_CONTAINER_NAME", "calico/node:latest")
  
  if ETCD_SCHEME == "https":
      CLUSTER_STORE_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:
      CLUSTER_STORE_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \
                                  get_ip()
  
  class DockerHost(object):
      """
      A host container which will hold workload containers to be networked by
      Calico.
  
      :param calico_node_autodetect_ip: When set to True, the test framework
      will not perform IP detection, and will run `calicoctl node` without
      explicitly passing in a value for --ip. This means calico-node will be
      forced to do its IP detection.
      :param override_hostname: When set to True, the test framework will
      choose an alternate hostname for the host which it will pass to all
      calicoctl components as the HOSTNAME environment variable.  If set
      to False, the HOSTNAME environment is not explicitly set.
      """
  
      # A static list of Docker networks that are created by the tests.  This
      # list covers all Docker hosts.
      docker_networks = []
  
      def __init__(self, name, start_calico=True, dind=True,
                   additional_docker_options="",
                   post_docker_commands=["docker load -i /code/calico-node.tar",
                                         "docker load -i /code/busybox.tar"],
                   calico_node_autodetect_ip=False,
                   simulate_gce_routing=False,
                   override_hostname=False):
          self.name = name
          self.dind = dind
          self.workloads = set()
          self.ip = None
          self.log_analyzer = None
          """
          An IP address value to pass to calicoctl as `--ip`. If left as None,
          no value will be passed, forcing calicoctl to do auto-detection.
          """
  
          self.ip6 = None
          """
          An IPv6 address value to pass to calicoctl as `--ipv6`. If left as
          None, no value will be passed.
          """
  
          self.override_hostname = None if not override_hostname else \
              uuid.uuid1().hex[:16]
          """
          Create an arbitrary hostname if we want to override.
          """
  
          # 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
          # must invoke cleanup.
          self._cleaned = False
  
          docker_args = "--privileged -tid " \
                        "-v /lib/mod
  
  [... the rest is omitted ...]
files.new_path: tests/st/utils/docker_host.py
files.old_contents: # Copyright (c) 2015-2017 Tigera, Inc. All rights reserved.
  #
  # 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 logging
  import json
  import os
  import uuid
  import yaml
  from functools import partial
  from subprocess import CalledProcessError, Popen, PIPE
  
  from log_analyzer import LogAnalyzer, FELIX_LOG_FORMAT, TIMESTAMP_FORMAT
  from network import DockerNetwork
  from tests.st.utils.exceptions import CommandExecError
  from utils import get_ip, log_and_run, retry_until_success, ETCD_SCHEME, \
      ETCD_CA, ETCD_KEY, ETCD_CERT, ETCD_HOSTNAME_SSL
  from workload import Workload
  
  logger = logging.getLogger(__name__)
  # We want to default CHECKOUT_DIR if either the ENV var is unset
  # OR its set to an empty string.
  CHECKOUT_DIR = os.getenv("HOST_CHECKOUT_DIR", "")
  if CHECKOUT_DIR == "":
      CHECKOUT_DIR = os.getcwd()
  
  NODE_CONTAINER_NAME = os.getenv("NODE_CONTAINER_NAME", "calico/node:latest")
  
  if ETCD_SCHEME == "https":
      CLUSTER_STORE_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:
      CLUSTER_STORE_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \
                                  get_ip()
  
  class DockerHost(object):
      """
      A host container which will hold workload containers to be networked by
      Calico.
  
      :param calico_node_autodetect_ip: When set to True, the test framework
      will not perform IP detection, and will run `calicoctl node` without
      explicitly passing in a value for --ip. This means calico-node will be
      forced to do its IP detection.
      :param override_hostname: When set to True, the test framework will
      choose an alternate hostname for the host which it will pass to all
      calicoctl components as the HOSTNAME environment variable.  If set
      to False, the HOSTNAME environment is not explicitly set.
      """
  
      # A static list of Docker networks that are created by the tests.  This
      # list covers all Docker hosts.
      docker_networks = []
  
      def __init__(self, name, start_calico=True, dind=True,
                   additional_docker_options="",
                   post_docker_commands=["docker load -i /code/calico-node.tar",
                                         "docker load -i /code/busybox.tar"],
                   calico_node_autodetect_ip=False,
                   override_hostname=False):
          self.name = name
          self.dind = dind
          self.workloads = set()
          self.ip = None
          self.log_analyzer = None
          """
          An IP address value to pass to calicoctl as `--ip`. If left as None,
          no value will be passed, forcing calicoctl to do auto-detection.
          """
  
          self.ip6 = None
          """
          An IPv6 address value to pass to calicoctl as `--ipv6`. If left as
          None, no value will be passed.
          """
  
          self.override_hostname = None if not override_hostname else \
              uuid.uuid1().hex[:16]
          """
          Create an arbitrary hostname if we want to override.
          """
  
          # 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
          # must invoke cleanup.
          self._cleaned = False
  
          docker_args = "--privileged -tid " \
                        "-v /lib/modules:/lib/modules " \
                       
  
  [... the rest is omitted ...]
files.old_path: tests/st/utils/docker_host.py