Exemple #1
0
    def _register_public_key_file_with_ssh_server(self, ssh_client_container_config, ssh_client_container_home_directory, ssh_host_config, host_is_container):
        """
        This function assumes that the ssh client container has a public key file in its ssh_client_container_home_directory.
        It copies that file to the ssh_server and adds the public key into the authorized keys file.
        It also adds the ssh_server to the known hosts file on the client machine.
        The server can be a container or a normal machine in the network.
        """

        ssh_server_machine_id = ssh_host_config.machine_id
        ssh_server_host_connection = self.connections.get_connection(ssh_server_machine_id)
        repository_machine_ssh_dir = ssh_host_config.ssh_dir

        container_name = ssh_client_container_config.container_name
        container_host_connection = self._get_container_host_connection(container_name)

        # COPY AND REGISTER THE PUBLIC KEY WITH repositoryMachine
        public_key_file = _get_public_key_filename(container_name)
        source_file = ssh_client_container_home_directory.joinpath(public_key_file)
        target_file = repository_machine_ssh_dir.joinpath(public_key_file)

        ssh_port = 22
        if host_is_container:
            print('----- Grant container ' + container_name + ' SSH access to container ' + ssh_host_config.container_conf.container_name + ' on machine ' + ssh_server_machine_id)
            ssh_port = ssh_host_config.container_ssh_port
            dockerutil.container_to_container_copy(container_host_connection, ssh_client_container_config, ssh_server_host_connection, ssh_host_config.container_conf, source_file, target_file)
        else:
            print('----- Grant container ' + container_name + ' SSH access to machine ' + ssh_server_machine_id)
            dockerutil.containertorcopy(container_host_connection, ssh_client_container_config, ssh_server_host_connection, source_file, target_file)

        # add the key file to authorized_keys
        authorized_keys_file = repository_machine_ssh_dir.joinpath('authorized_keys')
        # Remove previously appended public keys from the given container and append the
        # new public key to the authorized_keys file.
        # - print file without lines containing machine name string, then append new key to end of file
        command = (
            'cat {0} | grep -v {1} >> {2}/keys_temp &&'
            'mv -f {2}/keys_temp {0} &&'
            'cat {2}/{3} >> {0}'
        ).format(
            authorized_keys_file,
            container_name,
            repository_machine_ssh_dir,
            public_key_file)

        if host_is_container:
            dockerutil.run_command_in_container(ssh_server_host_connection, ssh_host_config.container_conf, command)
        else:
            ssh_server_host_connection.run_command(command)

        # Add the repository machine as known host to prevent the authentication request on the first run
        _accept_remote_container_host_key(
            container_host_connection, 
            ssh_client_container_config, 
            ssh_server_host_connection.info.host_name, 
            ssh_port,
            ssh_server_host_connection.info.user_name
        )
Exemple #2
0
def _add_known_ssh_host(client_container_host_connection, client_container_config, ssh_host_name, ssh_port):
    """
    Uses the ssh-keyscan command to add the public key of an ssh server to the known_hosts file of the
    given container.
    """
    known_hosts_file = PurePosixPath('~/.ssh/known_hosts')
    dockerutil.run_command_in_container(
        client_container_host_connection,
        client_container_config,
        'ssh-keyscan -p {0} {1} >> {2}'.format(ssh_port, ssh_host_name, known_hosts_file)
    )
Exemple #3
0
    def _grant_jenkins_master_ssh_access_to_jenkins_windows_slave(self, slave_host_connection ):

        master_config = self.config.jenkins_master_host_config.container_conf
        master_container = master_config.container_name
        print(("----- Grant {0} ssh access to {1}").format(master_container, slave_host_connection.info.host_name))

        # configure the script for adding an authorized key to the bitwise ssh server on the
        # windows machine
        authorized_keys_script = 'updateAuthorizedKeys.bat'
        full_authorized_keys_script = _SCRIPT_DIR.joinpath(authorized_keys_script)

        master_connection = self._get_jenkins_master_host_connection()
        public_key_file_master = config_data.JENKINS_HOME_JENKINS_MASTER_CONTAINER.joinpath('.ssh/' + _get_public_key_filename(master_container) )
        public_key = dockerutil.run_command_in_container(
            master_connection,
            master_config,
            'cat {0}'.format(public_key_file_master)
        )[0]

        configure_file(str(full_authorized_keys_script) + '.in', full_authorized_keys_script, {
            '@PUBLIC_KEY@' : public_key,
            '@JENKINS_MASTER_CONTAINER@' : master_container,
            '@SLAVE_MACHINE_USER@' : slave_host_connection.info.user_name,
        })

        # copy the script to the windows slave machine
        ssh_dir = PureWindowsPath('C:/Users/' + slave_host_connection.info.user_name + '/.ssh')
        full_script_path_on_slave = ssh_dir.joinpath(full_authorized_keys_script.name)
        slave_host_connection.sftp_client.put(str(full_authorized_keys_script), str(full_script_path_on_slave))

        # call the script
        try:
            call_script_command = '{0} {1}'.format(full_script_path_on_slave, slave_host_connection.info.user_password)
            slave_host_connection.run_command(call_script_command, print_command=True)
        except Exception as err:
            print(
                "Error: Updating the authorized ssh keys on "
                + slave_host_connection.info.host_name + " failed. Was the password correct?")
            raise err

        # clean up the generated script because of the included password
        os.remove(str(full_authorized_keys_script))

        # Wait a little until the bitvise ssh server is ready to accept the key file.
        # This can possibly fail on slower machines.
        time.sleep(1)

        # Add the slave to the known hosts
        try:
            _accept_remote_container_host_key(
                master_connection, 
                master_config, 
                slave_host_connection.info.host_name, 
                22, 
                slave_host_connection.info.user_name
                )
        except Exception as err:
            # This is not really clean but I can not think of a better solution now.
            print("When this call fails, it is possible that the waiting time before using the ssh connection to the Bitvise SSH server is too short.")
            raise err
Exemple #4
0
def _create_rsa_key_file_pair_on_container(connection, container_conf, container_home_directory):
    # copy the scripts that does the job to the container
    dockerutil.copy_textfile_to_container(
        connection,
        container_conf,
        _SCRIPT_DIR.joinpath(_CREATEKEYPAIR_SCRIPT),
        container_home_directory.joinpath(_CREATEKEYPAIR_SCRIPT)
    )

    # This will create the key-pair on the container.
    # We need to do this in the container or ssh will not accept the private key file.
    dockerutil.run_command_in_container(
        connection,
        container_conf,
        '/bin/bash ' + str(container_home_directory.joinpath(_CREATEKEYPAIR_SCRIPT)) + ' ' + container_conf.container_name
        )
Exemple #5
0
    def _grant_container_access_to_https_repositories(self, container_conf, container_home_directory, https_repository_host_config):
        """
        This function adds the credentials of the given https based repository accesses to the git credential store of that container.
        """
        container_name = container_conf.container_name
        container_host_connection = self._get_container_host_connection(container_name)

        # Add the credentials for the repository to the jenkins-git-credentials file.
        credential_file = container_home_directory.joinpath(_GIT_CREDENTIALS_STORE)
        command = 'echo https://{0}:{1}@{2} >> {3}'.format(
            https_repository_host_config.user_name,
            https_repository_host_config.user_password,
            https_repository_host_config.host_name,
            credential_file
        )
        dockerutil.run_command_in_container(
            container_host_connection,
            container_conf,
            command
        )