Exemple #1
0
def salt_secondary_master(request, salt_factories):
    #
    # Enable a secondary Salt master so we can disable follow_symlinks
    #
    publish_port = ports.get_unused_localhost_port()
    ret_port = ports.get_unused_localhost_port()

    config_defaults = {
        "open_mode": True,
        "transport": request.config.getoption("--transport"),
    }
    config_overrides = {
        "interface": "127.0.0.1",
        "fileserver_followsymlinks": False,
        "publish_port": publish_port,
        "ret_port": ret_port,
    }

    factory = salt_factories.salt_master_daemon(
        "secondary-master",
        defaults=config_defaults,
        overrides=config_overrides,
        extra_cli_arguments_after_first_start_failure=["--log-level=debug"],
    )
    with factory.started(start_timeout=120):
        yield factory
Exemple #2
0
def master_config(root_dir, transport):
    master_conf = salt.config.master_config("")
    master_conf["transport"] = transport
    master_conf["id"] = "master"
    master_conf["root_dir"] = str(root_dir)
    master_conf["sock_dir"] = str(root_dir)
    master_conf["interface"] = "127.0.0.1"
    master_conf["publish_port"] = ports.get_unused_localhost_port()
    master_conf["ret_port"] = ports.get_unused_localhost_port()
    master_conf["pki_dir"] = str(root_dir / "pki")
    os.makedirs(master_conf["pki_dir"])
    salt.crypt.gen_keys(master_conf["pki_dir"], "master", 4096)
    minions_keys = os.path.join(master_conf["pki_dir"], "minions")
    os.makedirs(minions_keys)
    yield master_conf
Exemple #3
0
 def apply_pre_start_states(self, salt_call_cli, testclass, username):
     # pylint: disable=access-member-before-definition
     if self.listen_port in self.check_ports:
         self.check_ports.remove(self.listen_port)
     if self.listen_port in self.listen_ports:
         self.listen_ports.remove(self.listen_port)
     # pylint: enable=access-member-before-definition
     self.listen_port = ports.get_unused_localhost_port()
     self.check_ports.append(self.listen_port)
     self.listen_ports.append(self.listen_port)
     url = "ssh://{username}@127.0.0.1:{port}/~/repo.git".format(
         username=testclass.username, port=self.listen_port)
     url_extra_repo = "ssh://{username}@127.0.0.1:{port}/~/extra_repo.git".format(
         username=testclass.username, port=self.listen_port)
     home = "/root/.ssh"
     testclass.ext_opts = {
         "url":
         url,
         "url_extra_repo":
         url_extra_repo,
         "privkey_nopass":
         os.path.join(home, testclass.id_rsa_nopass),
         "pubkey_nopass":
         os.path.join(home, testclass.id_rsa_nopass + ".pub"),
         "privkey_withpass":
         os.path.join(home, testclass.id_rsa_withpass),
         "pubkey_withpass":
         os.path.join(home, testclass.id_rsa_withpass + ".pub"),
         "passphrase":
         testclass.passphrase,
     }
     ret = salt_call_cli.run(
         "state.apply",
         mods="git_pillar.ssh",
         pillar={
             "git_pillar": {
                 "git_ssh": testclass.git_ssh,
                 "id_rsa_nopass": testclass.id_rsa_nopass,
                 "id_rsa_withpass": testclass.id_rsa_withpass,
                 "sshd_bin": self.get_script_path(),
                 "sshd_port": self.listen_port,
                 "sshd_config_dir": str(self.config_dir),
                 "master_user": username,
                 "user": testclass.username,
             }
         },
         _timeout=240,
     )
     if ret.returncode != 0:
         pytest.fail("Failed to apply the 'git_pillar.ssh' state")
     if next(iter(ret.data.values()))["result"] is not True:
         pytest.fail("Failed to apply the 'git_pillar.ssh' state")
    def __attrs_post_init__(self):
        """
        Post attrs initialization routines.
        """
        if self.authorized_keys is None:
            self.authorized_keys = []
        if self.sshd_config_dict is None:
            self.sshd_config_dict = {}
        if self.listen_address is None:
            self.listen_address = "127.0.0.1"
        if self.listen_port is None:
            self.listen_port = ports.get_unused_localhost_port()
        self.check_ports = [self.listen_port]
        if isinstance(self.config_dir, str):
            self.config_dir = pathlib.Path(self.config_dir)
        elif not isinstance(self.config_dir, pathlib.Path):
            # A py local path?
            self.config_dir = pathlib.Path(self.config_dir.strpath)
        self.config_dir.chmod(0o0700)
        authorized_keys_file = self.config_dir / "authorized_keys"

        # Let's generate the client key
        self.client_key = self._generate_client_ecdsa_key()
        with open("{}.pub".format(self.client_key)) as rfh:
            pubkey = rfh.read().strip()
            log.debug("SSH client pub key: %r", pubkey)
            self.authorized_keys.append(pubkey)

        # Write the authorized pub keys to file
        with open(str(authorized_keys_file), "w") as wfh:
            wfh.write("\n".join(self.authorized_keys))

        authorized_keys_file.chmod(0o0600)

        with open(str(authorized_keys_file)) as rfh:
            log.debug("AuthorizedKeysFile contents:\n%s", rfh.read())

        _default_config = {
            "ListenAddress": self.listen_address,
            "PermitRootLogin": "******" if running_username() == "root" else "no",
            "ChallengeResponseAuthentication": "no",
            "PasswordAuthentication": "no",
            "PubkeyAuthentication": "yes",
            "PrintMotd": "no",
            "PidFile": self.config_dir / "sshd.pid",
            "AuthorizedKeysFile": authorized_keys_file,
        }
        if self.sshd_config_dict:
            _default_config.update(self.sshd_config_dict)
        self.sshd_config = _default_config
        self._write_config()
        super().__attrs_post_init__()
Exemple #5
0
 def __attrs_post_init__(self):
     """
     Post attrs initialization routines.
     """
     self.store = deque(maxlen=10000)
     self.address = "tcp://127.0.0.1:{}".format(
         ports.get_unused_localhost_port())
     self.running_event = threading.Event()
     self.running_thread = threading.Thread(target=self._run)
     self.cleanup_thread = threading.Thread(target=self._cleanup)
     self.sentinel = msgpack.dumps(None)
     self.sentinel_event = threading.Event()
     self.auth_event_handlers = weakref.WeakValueDictionary()
Exemple #6
0
    def apply_pre_start_states(self, salt_call_cli, testclass, root_dir):
        if self.listen_port in self.check_ports:
            self.check_ports.remove(self.listen_port)
        if self.listen_port in self.listen_ports:
            self.listen_ports.remove(self.listen_port)
        self.listen_port = ports.get_unused_localhost_port()
        self.check_ports.append(self.listen_port)
        self.listen_ports.append(self.listen_port)

        config_dir = os.path.join(root_dir, "config")
        git_dir = os.path.join(root_dir, "git")
        testclass.repo_dir = repo_dir = os.path.join(git_dir, "repos")
        venv_dir = os.path.join(root_dir, "venv")
        uwsgi_bin = os.path.join(venv_dir, "bin", "uwsgi")

        pillar = {
            "git_pillar": {
                "config_dir": config_dir,
                "git_dir": git_dir,
                "venv_dir": venv_dir,
                "root_dir": root_dir,
                "uwsgi_port": self.listen_port,
            }
        }

        # Different libexec dir for git backend on Debian and FreeBSD-based systems
        if salt.utils.platform.is_freebsd():
            git_core = "/usr/local/libexec/git-core"
        else:
            git_core = "/usr/libexec/git-core"
        if not os.path.exists(git_core):
            git_core = "/usr/lib/git-core"

        if not os.path.exists(git_core):
            pytest.fail(
                "{} not found. Either git is not installed, or the test "
                "class needs to be updated.".format(git_core)
            )

        pillar["git_pillar"]["git-http-backend"] = os.path.join(
            git_core, "git-http-backend"
        )

        ret = salt_call_cli.run(
            "state.apply", mods="git_pillar.http.uwsgi", pillar=pillar, _timeout=120
        )
        if ret.returncode != 0:
            pytest.fail("Failed to apply the 'git_pillar.http.uwsgi' state")
        if next(iter(ret.data.values()))["result"] is not True:
            pytest.fail("Failed to apply the 'git_pillar.http.uwsgi' state")
Exemple #7
0
def datagram_server():
    logger = logging.getLogger("test_logstash_logger")
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    port = ports.get_unused_localhost_port()
    handler = DatagramLogstashHandler("127.0.0.1", port)
    try:
        server.bind(("127.0.0.1", port))
        server.settimeout(2)
        logger.setLevel(logging.DEBUG)
        logger.addHandler(handler)
        yield server
    finally:
        logger.removeHandler(handler)
        server.close()
Exemple #8
0
    def setUpClass(cls):
        ret_port = ports.get_unused_localhost_port()
        publish_port = ports.get_unused_localhost_port()
        tcp_master_pub_port = ports.get_unused_localhost_port()
        tcp_master_pull_port = ports.get_unused_localhost_port()
        tcp_master_publish_pull = ports.get_unused_localhost_port()
        tcp_master_workers = ports.get_unused_localhost_port()
        cls.master_config = cls.get_temp_config(
            "master",
            **{
                "transport": "tcp",
                "auto_accept": True,
                "ret_port": ret_port,
                "publish_port": publish_port,
                "tcp_master_pub_port": tcp_master_pub_port,
                "tcp_master_pull_port": tcp_master_pull_port,
                "tcp_master_publish_pull": tcp_master_publish_pull,
                "tcp_master_workers": tcp_master_workers,
            }
        )

        cls.minion_config = cls.get_temp_config(
            "minion",
            **{
                "transport": "tcp",
                "master_ip": "127.0.0.1",
                "auth_timeout": 1,
                "master_port": ret_port,
                "master_uri": "tcp://127.0.0.1:{}".format(ret_port),
            }
        )

        cls.process_manager = salt.utils.process.ProcessManager(
            name="ReqServer_ProcessManager"
        )

        cls.server_channel = salt.channel.server.PubServerChannel.factory(
            cls.master_config
        )
        cls.server_channel.pre_fork(cls.process_manager)

        # we also require req server for auth
        cls.req_server_channel = salt.channel.server.ReqServerChannel.factory(
            cls.master_config
        )
        cls.req_server_channel.pre_fork(cls.process_manager)
        cls.io_loop = salt.ext.tornado.ioloop.IOLoop()
        cls.stop = threading.Event()
        cls.req_server_channel.post_fork(cls._handle_payload, io_loop=cls.io_loop)
        cls.server_thread = threading.Thread(
            target=run_loop_in_thread,
            args=(
                cls.io_loop,
                cls.stop,
            ),
        )
        cls.server_thread.start()
Exemple #9
0
def salt_message_client():
    io_loop_mock = MagicMock(spec=salt.ext.tornado.ioloop.IOLoop)
    io_loop_mock.call_later.side_effect = lambda *args, **kwargs: (args, kwargs
                                                                   )

    client = salt.transport.tcp.MessageClient(
        {},
        "127.0.0.1",
        ports.get_unused_localhost_port(),
        io_loop=io_loop_mock)

    try:
        yield client
    finally:
        client.close()
Exemple #10
0
 def setUpClass(cls):
     overrides = {
         "publish_port": ports.get_unused_localhost_port(),
         "ret_port": ports.get_unused_localhost_port(),
         "tcp_master_pub_port": ports.get_unused_localhost_port(),
         "tcp_master_pull_port": ports.get_unused_localhost_port(),
         "tcp_master_publish_pull": ports.get_unused_localhost_port(),
         "tcp_master_workers": ports.get_unused_localhost_port(),
         "runtests_conn_check_port": ports.get_unused_localhost_port(),
         "runtests_log_port": ports.get_unused_localhost_port(),
     }
     overrides["pytest_engine_port"] = overrides["runtests_conn_check_port"]
     temp_config = AdaptedConfigurationTestCaseMixin.get_temp_config(
         "master", **overrides)
     cls.root_dir = temp_config["root_dir"]
     cls.config_dir = os.path.dirname(temp_config["conf_file"])
     if temp_config["transport"] == "tcp":
         raise SkipTest("Test only applicable to the ZMQ transport")
Exemple #11
0
def zmq_server():
    logger = logging.getLogger("test_logstash_logger")
    context = zmq.Context()
    server = context.socket(zmq.SUB)
    port = ports.get_unused_localhost_port()
    handler = ZMQLogstashHander("tcp://127.0.0.1:{}".format(port))
    try:
        server.setsockopt(zmq.SUBSCRIBE, b"")
        server.bind("tcp://127.0.0.1:{}".format(port))

        logger.setLevel(logging.DEBUG)
        logger.addHandler(handler)
        yield server
    finally:
        logger.removeHandler(handler)
        server.close()
        context.term()
Exemple #12
0
async def test_ipc_connect_sync_wrapped(io_loop, tmp_path):
    """
    Ensure IPCMessageSubscriber.connect gets wrapped by
    salt.utils.asynchronous.SyncWrapper.
    """
    if salt.utils.platform.is_windows():
        socket_path = ports.get_unused_localhost_port()
    else:
        socket_path = str(tmp_path / "noexist.ipc")
    subscriber = salt.utils.asynchronous.SyncWrapper(
        salt.transport.ipc.IPCMessageSubscriber,
        args=(socket_path, ),
        kwargs={"io_loop": io_loop},
        loop_kwarg="io_loop",
    )
    with pytest.raises(salt.ext.tornado.iostream.StreamClosedError):
        # Don't `await subscriber.connect()`, that's the purpose of the SyncWrapper
        subscriber.connect()
Exemple #13
0
    def apply_pre_start_states(self, salt_call_cli, testclass, root_dir):
        if self.listen_port in self.check_ports:
            self.check_ports.remove(self.listen_port)
        if self.listen_port in self.listen_ports:
            self.listen_ports.remove(self.listen_port)
        self.listen_port = ports.get_unused_localhost_port()
        self.check_ports.append(self.listen_port)
        self.listen_ports.append(self.listen_port)

        config_dir = os.path.join(root_dir, "config")
        git_dir = os.path.join(root_dir, "git")
        url = "http://127.0.0.1:{port}/repo.git".format(port=self.listen_port)
        url_extra_repo = "http://127.0.0.1:{port}/extra_repo.git".format(
            port=self.listen_port)
        ext_opts = {"url": url, "url_extra_repo": url_extra_repo}
        # Add auth params if present (if so this will trigger the spawned
        # server to turn on HTTP basic auth).
        for credential_param in ("user", "password"):
            if hasattr(testclass, credential_param):
                ext_opts[credential_param] = getattr(testclass,
                                                     credential_param)
        testclass.ext_opts = ext_opts
        testclass.nginx_port = self.listen_port

        auth_enabled = hasattr(testclass, "username") and hasattr(
            testclass, "password")
        pillar = {
            "git_pillar": {
                "config_dir": config_dir,
                "git_dir": git_dir,
                "uwsgi_port": self.uwsgi_port,
                "nginx_port": self.listen_port,
                "auth_enabled": auth_enabled,
            }
        }

        ret = salt_call_cli.run("state.apply",
                                mods="git_pillar.http.nginx",
                                pillar=pillar)
        if ret.returncode != 0:
            pytest.fail("Failed to apply the 'git_pillar.http.nginx' state")
        if next(iter(ret.data.values()))["result"] is not True:
            pytest.fail("Failed to apply the 'git_pillar.http.nginx' state")
Exemple #14
0
def vault_port():
    return ports.get_unused_localhost_port()
Exemple #15
0
def pypi_server_port():
    return ports.get_unused_localhost_port()
Exemple #16
0
def sdb_etcd_port():
    return ports.get_unused_localhost_port()
def echo_server_port():
    return ports.get_unused_localhost_port()
Exemple #18
0
 def _default_log_port(self):
     return ports.get_unused_localhost_port()
Exemple #19
0
def netapi_port():
    return get_unused_localhost_port()
Exemple #20
0
    def test_cache_remote_file(self):
        """
        cp.cache_file
        """
        nginx_port = ports.get_unused_localhost_port()
        url_prefix = "http://localhost:{}/".format(nginx_port)
        temp_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
        self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)
        nginx_root_dir = os.path.join(temp_dir, "root")
        nginx_conf_dir = os.path.join(temp_dir, "conf")
        nginx_conf = os.path.join(nginx_conf_dir, "nginx.conf")
        nginx_pidfile = os.path.join(nginx_conf_dir, "nginx.pid")
        file_contents = "Hello world!"

        for dirname in (nginx_root_dir, nginx_conf_dir):
            os.makedirs(dirname)

        # Write the temp file
        with salt.utils.files.fopen(
                os.path.join(nginx_root_dir, "actual_file"), "w") as fp_:
            fp_.write(salt.utils.stringutils.to_str(file_contents))

        # Write the nginx config
        with salt.utils.files.fopen(nginx_conf, "w") as fp_:
            fp_.write(
                textwrap.dedent(
                    salt.utils.stringutils.to_str("""\
                user root;
                worker_processes 1;
                error_log {nginx_conf_dir}/server_error.log;
                pid {nginx_pidfile};

                events {{
                    worker_connections 1024;
                }}

                http {{
                    include       /etc/nginx/mime.types;
                    default_type  application/octet-stream;

                    access_log {nginx_conf_dir}/access.log;
                    error_log {nginx_conf_dir}/error.log;

                    server {{
                        listen {nginx_port} default_server;
                        server_name cachefile.local;
                        root {nginx_root_dir};

                        location ~ ^/301$ {{
                            return 301 /actual_file;
                        }}

                        location ~ ^/302$ {{
                            return 302 /actual_file;
                        }}
                    }}
                }}""".format(**locals()))))

        self.run_function("cmd.run", [["nginx", "-c", nginx_conf]],
                          python_shell=False)
        with salt.utils.files.fopen(nginx_pidfile) as fp_:
            nginx_pid = int(fp_.read().strip())
            nginx_proc = psutil.Process(pid=nginx_pid)
            self.addCleanup(nginx_proc.send_signal, signal.SIGQUIT)

        for code in ("", "301", "302"):
            url = url_prefix + (code or "actual_file")
            log.debug("attempting to cache %s", url)
            ret = self.run_function("cp.cache_file", [url])
            self.assertTrue(ret)
            with salt.utils.files.fopen(ret) as fp_:
                cached_contents = salt.utils.stringutils.to_unicode(fp_.read())
                self.assertEqual(cached_contents, file_contents)
def master(salt_factories):
    defaults = {"rest_tornado": {"port": ports.get_unused_localhost_port(), "disable_ssl": True}}
    factory = salt_factories.salt_master_daemon(random_string("master-"), defaults=defaults)
    with factory.started():
        yield factory