def _delete_dir(dir_path, dir_type):
     try:
         EdgeUtils.delete_dir(dir_path)
     except OSError as ex:
         msg = 'Error deleting {0} directory {1}'.format(dir_type, dir_path)
         log.error(msg)
         raise edgectl.errors.EdgeFileAccessError(msg, dir_path)
 def _create_dir(dir_path, dir_type):
     try:
         EdgeUtils.mkdir_if_needed(dir_path)
     except OSError as ex:
         msg = 'Error creating {0} directory {1}'.format(dir_type, dir_path)
         log.error(msg)
         raise edgectl.errors.EdgeFileAccessError(msg, dir_path)
Exemple #3
0
 def _insert_file_in_volume_mount(self, volume_name, host_src_file,
                                  volume_dest_file_name):
     """
     Use volume introspection to place files into the host mountpoint in order
     to work around issues with Docker filesystem operations on Windows
     Hyper-V containers and container mountpoints
     """
     try:
         volume_name = (volume_name.split('/'))[-1]
         volume_info = self._client.api.inspect_volume(volume_name)
         EdgeUtils.copy_files(
             host_src_file.replace('\\\\', '\\'),
             os.path.join(volume_info['Mountpoint'].replace('\\\\', '\\'),
                          volume_dest_file_name))
     except docker.errors.APIError as docker_ex:
         msg = 'Docker volume inspect failed for: {0}'.format(volume_name)
         logging.error(msg)
         print(docker_ex)
         raise edgectl.errors.EdgeDeploymentError(msg, docker_ex)
     except (OSError, IOError) as ex_os:
         msg = 'File IO error seen copying files to volume: {0}. ' \
               'Errno: {1}, Error {2}'.format(volume_name, str(ex_os.errno), ex_os.strerror)
         logging.error(msg)
         print(ex_os)
         raise edgectl.errors.EdgeDeploymentError(msg, ex_os)
Exemple #4
0
    def test_get_hostname_raises_ioerror_when_getfqdn_raises_ioerror(
            self, mock_hostname):
        """ Tests invocation of API get_hostname raises IOError when getfqdn raises IOError"""
        # arrange
        mock_hostname.side_effect = IOError('getfqdn IO error')

        # act, assert
        with self.assertRaises(IOError):
            EdgeUtils.get_hostname()
Exemple #5
0
    def test_mkdir_if_needed_when_dir_does_not_exist(self, mock_mkdirs):
        """ Test a valid invocation of API mkdir_if_needed when dir to be made does not exist """
        # arrange
        dir_path = 'blah'

        # act
        EdgeUtils.mkdir_if_needed(dir_path)

        # assert
        mock_mkdirs.assert_called_with(dir_path)
Exemple #6
0
    def test_copy_files_raises_oserror_when_cop2_raises_oserror(
            self, mock_copy):
        """ Tests invocation of API copy_files raises OSError when copy2 raises OSError"""
        # arrange
        src_path = 'src'
        dest_path = 'dest'
        mock_copy.side_effect = OSError('copy2 OS error')

        # act, assert
        with self.assertRaises(OSError):
            EdgeUtils.copy_files(src_path, dest_path)
Exemple #7
0
    def test_copy_files_valid(self, mock_copy):
        """ Test a valid invocation of API copy_files """
        # arrange
        src_path = 'src'
        dest_path = 'dest'

        # act
        EdgeUtils.copy_files(src_path, dest_path)

        # assert
        mock_copy.assert_called_with(src_path, dest_path)
Exemple #8
0
    def test_delete_dir_raises_oserror_when_rmtree_fails(
            self, mock_exists, mock_rmtree):
        """ Tests invocation of API delete_dir raises OSError when rmtree raises OSError"""
        # arrange
        dir_path = 'blah'
        mock_exists.return_value = True
        mock_rmtree.side_effect = OSError('rmtree error')

        # act, assert
        with self.assertRaises(OSError):
            EdgeUtils.delete_dir(dir_path)
Exemple #9
0
    def test_mkdir_if_needed_when_dir_exists(self, mock_mkdirs):
        """ Test a valid invocation of API mkdir_if_needed when dir to be made already exists """
        # arrange
        dir_path = 'blah'
        mock_mkdirs.side_effect = OSError(errno.EEXIST, 'Directory exists.')

        # act
        EdgeUtils.mkdir_if_needed(dir_path)

        # assert
        mock_mkdirs.assert_called_with(dir_path)
Exemple #10
0
    def test_mkdir_if_needed_raises_oserror_when_mkdir_fails(
            self, mock_mkdirs):
        """ Tests invocation of API mkdir_if_needed raises OSError when makedirs raises OSError"""
        # arrange
        dir_path = 'blah'
        mock_mkdirs.side_effect = OSError(errno.EACCES,
                                          'Directory permission error')

        # act, assert
        with self.assertRaises(OSError):
            EdgeUtils.mkdir_if_needed(dir_path)
Exemple #11
0
    def test_delete_dir_execute_onerror_callback(self, mock_chmod,
                                                 mock_unlink):
        """ Test rmtree onerror callback invocation"""
        # arrange
        dir_path = 'blah'
        ignored = 0

        # act
        EdgeUtils._remove_readonly_callback(ignored, dir_path, ignored)

        # assert
        mock_chmod.assert_called_with(dir_path, stat.S_IWRITE)
        mock_unlink.assert_called_with(dir_path)
Exemple #12
0
    def test_delete_dir_when_dir_does_not_exist(self, mock_exists,
                                                mock_rmtree):
        """ Test a valid invocation of API delete_dir when dir to be deleted does not exist"""
        # arrange
        dir_path = 'blah'
        mock_exists.return_value = False

        # act
        EdgeUtils.delete_dir(dir_path)

        # assert
        mock_exists.assert_called_with(dir_path)
        mock_rmtree.assert_not_called()
Exemple #13
0
    def test_delete_dir_when_dir_exists(self, mock_exists, mock_rmtree):
        """ Test a valid invocation of API delete_dir when dir to be deleted exists"""
        # arrange
        dir_path = 'blah'
        mock_exists.return_value = True

        # act
        EdgeUtils.delete_dir(dir_path)

        # assert
        mock_exists.assert_called_with(dir_path)
        mock_rmtree.assert_called_with(
            dir_path, onerror=EdgeUtils._remove_readonly_callback)
Exemple #14
0
    def _prompt_password(cert_type, bypass_options, config_file_setting):
        options_str = ''
        options_len = len(bypass_options)
        index = 0
        for option in bypass_options:
            options_str += option
            if index < options_len - 1:
                options_str += ' or '
            else:
                options_str += '.'
            index += 1

        config_file_setting = '"security.certificates.<option>.' + config_file_setting + '"'
        print('\n',
              '\n********************************************************************************'
              '\nPlease enter a passphrase for the', cert_type, 'private key.',
              '\n\nTo prevent this prompt from appearing, input the required passphrase',
              '\nor generate the private key without a passphrase.',
              '\n\n When using the command line options to setup the IoT Edge runtime:',
              '\n - Enter the passphrase via the command line options:',
              '\n  ', options_str,
              '\n - When opting not to use a passphrase, use command line option:',
              '\n   --auto-cert-gen-force-no-passwords.',
              '\n\n When using the --config-file to setup the runtime:',
              '\n - Set the input passphrase file via JSON configuration item:',
              '\n  ', config_file_setting,
              '\n - When opting not to use a passphrase, set JSON configuration item:',
              '\n   "security.certificates.<option>.forceNoPasswords" to true.'
              '\n********************************************************************************')
        return EdgeUtils.prompt_password(cert_type,
                                         EdgeCertUtil.MIN_PASSPHRASE_LENGTH,
                                         EdgeCertUtil.MAX_PASSPHRASE_LENGTH)
Exemple #15
0
 def test_sanitize_registry(self):
     """ Test a valid invocation of API sanitize_registry_data """
     result = EdgeUtils.sanitize_registry_data('test_address',
                                               'test_username',
                                               'test_password')
     pattern = re.compile(
         r'^Address: test_address, Username: test_username, Password:[\*]+$'
     )
     self.assertTrue(pattern.match(result))
Exemple #16
0
    def test_sanitize_connection_string(self):
        """ Test a valid invocation of API sanitize_connection_string """
        result = EdgeUtils.sanitize_connection_string(
            'HostName=aa;DeviceId=bb;SharedAccessKey=cc')
        pattern = re.compile(
            r'^HostName=aa;DeviceId=bb;SharedAccessKey=[\*]+$')
        self.assertTrue(pattern.match(result))

        result = EdgeUtils.sanitize_connection_string(
            'HostName=aa;DeviceId=bb;sharedaccesskey=cc')
        pattern = re.compile(
            r'^HostName=aa;DeviceId=bb;sharedaccesskey=[\*]+$')
        self.assertTrue(pattern.match(result))

        result = EdgeUtils.sanitize_connection_string(
            'HostName=aaa;DeviceId=bbb')
        pattern = re.compile(r'^HostName=aaa;DeviceId=bbb+$')
        self.assertTrue(pattern.match(result))
Exemple #17
0
    def test_get_hostname_valid(self, mock_hostname):
        """ Test a valid invocation of API get_hostname """
        # arrange
        hostname = 'test_hostname'
        mock_hostname.return_value = hostname
        # act
        result = EdgeUtils.get_hostname()

        # assert
        mock_hostname.assert_called_with()
        self.assertEqual(hostname, result)
Exemple #18
0
 def __str__(self):
     result = 'Schema Version:\t\t' + self.schema_version + '\n'
     conn_str = EdgeUtils.sanitize_connection_string(self.connection_string)
     result += 'Connection String:\t' + conn_str + '\n'
     result += 'Config Directory:\t' + self.config_dir + '\n'
     result += 'Home Directory:\t\t' + self.home_dir + '\n'
     result += 'Hostname:\t\t' + self.hostname + '\n'
     result += 'Log Level:\t\t' + self.log_level + '\n'
     if self.certificate_config:
         result += str(self.certificate_config)
     if self.deployment_config:
         result += str(self.deployment_config)
     return result
Exemple #19
0
    def test_check_if_file_exists_returns_true(self, mock_exists, mock_isfile):
        """ Test a valid invocation of API check_if_file_exists """
        # arrange #1
        file_path = 'blah'
        mock_exists.return_value = True
        mock_isfile.return_value = True

        # act
        result = EdgeUtils.check_if_file_exists(file_path)

        # assert
        mock_exists.assert_called_with(file_path)
        mock_isfile.assert_called_with(file_path)
        self.assertTrue(result)
Exemple #20
0
    def test_check_if_dir_exists_returns_true(self, mock_exists, mock_isdir):
        """ Test a valid invocation of API check_if_directory_exists """
        # arrange #1
        dir_path = 'blah'
        mock_exists.return_value = True
        mock_isdir.return_value = True

        # act
        result = EdgeUtils.check_if_directory_exists(dir_path)

        # assert
        mock_exists.assert_called_with(dir_path)
        mock_isdir.assert_called_with(dir_path)
        self.assertTrue(result)
Exemple #21
0
    def test_check_if_dir_exists_returns_false_path_is_none(
            self, mock_exists, mock_isdir):
        """ Test a valid invocation of API check_if_directory_exists """

        # arrange
        dir_path = None

        # act
        result = EdgeUtils.check_if_directory_exists(dir_path)

        # assert
        mock_exists.assert_not_called()
        mock_isdir.assert_not_called()
        self.assertFalse(result)
Exemple #22
0
 def __str__(self):
     result = 'Deployment Type:\t' + self.deployment_type + '\n'
     result += 'Docker Engine URI:\t' + self.uri + '\n'
     result += 'Edge Agent Image:\t' + self.edge_image + '\n'
     result += 'Registries:' + '\n'
     for registry in self.registries:
         result += '\t\t\t'
         reg_str = EdgeUtils.sanitize_registry_data(registry[EC.REGISTRY_ADDRESS_KEY],
                                                    registry[EC.REGISTRY_USERNAME_KEY],
                                                    registry[EC.REGISTRY_PASSWORD_KEY])
         result += reg_str + '\n'
     result += 'Logging Driver:\t\t' + self.logging_driver + '\n'
     options = self.logging_options
     for key in options:
         result += '\t\t\t' + str(key) + ': ' + options[key] + '\n'
     return result
Exemple #23
0
    def _set_dca_file(self, kwargs, file_key):
        """Helper method to store one of the many device CA certificate and
           private key files required to operate the Edge as a gateway.

        Args:
            kwargs (dict): User supplied KW args
            file_key (str): Key to retrieve and store the file

        Raises:
            ValueError if retrieved file path is None or if the file does not exist.
        """
        file_path = kwargs[file_key]
        if EdgeUtils.check_if_file_exists(file_path):
            self._dca_files_dict[file_key] = file_path
        else:
            raise ValueError('Invalid {0} file: {1}'.format(
                file_key, file_path))
Exemple #24
0
    def _parse_login_options(self, args):
        is_valid = self._parse_command_options_common(args)
        if is_valid:
            try:
                self.edge_config.deployment_config.add_registry(
                    args.address, args.username, args.password)
            except ValueError as ex:
                log.error('%s', str(ex))
                msg = EdgeUtils.sanitize_registry_data(args.address,
                                                       args.username,
                                                       args.password)
                log.error('Error setting login data: [%s].', msg)
                raise edgectl.errors.EdgeError('Error setting login data', ex)

            EdgeHostPlatform.install_edge_by_json_data(self.edge_config, False)
            config_file = EdgeHostPlatform.get_host_config_file_path()
            log.info('The runtime configuration file %s was updated with' \
                     ' the credentials for registry: %s', config_file, args.address)
        return is_valid
    def parse(self, ignored=None):
        args = self._input_args
        try:
            defaults_json = EdgeDefault.get_default_settings_json()
            cs = args.connection_string
            if cs is None or len(cs) == 0:
                raise ValueError('Please specify the device connection string' \
                                 ' using the --connection-string option')

            config = EdgeHostConfig()
            config.schema_version = defaults_json[EC.SCHEMA_KEY]
            config.connection_string = cs

            cfg_src = EdgeConfigDirInputSource.USER_PROVIDED
            cfg_dir_opt = EdgeHostPlatform.choose_platform_config_dir(args.edge_config_dir, cfg_src)

            config.config_dir = cfg_dir_opt[0]
            config.config_dir_source = cfg_dir_opt[1]

            home_dir = args.edge_home_dir
            if home_dir is None:
                home_dir = EdgeHostPlatform.get_home_dir()
            config.home_dir = home_dir

            hostname = args.edge_hostname
            if hostname is None:
                hostname = EdgeUtils.get_hostname()
            config.hostname = hostname

            log_level = args.runtime_log_level
            if log_level is None:
                log_level = EdgeDefault.get_default_runtime_log_level()
            config.log_level = log_level

            upstream_protocol = args.upstream_protocol
            if upstream_protocol is None:
                config.upstream_protocol = EdgeUpstreamProtocol.NONE
            else:
                config.upstream_protocol = upstream_protocol

            deploy_cfg = None
            if self._deployment_type == EC.DEPLOYMENT_DOCKER:
                deploy_cfg = EdgeDeploymentConfigDocker()
                docker_deploy_data = \
                    defaults_json[EC.DEPLOYMENT_KEY][EC.DEPLOYMENT_DOCKER_KEY]
                registries = args.docker_registries
                if registries is None:
                    registries = docker_deploy_data[EC.REGISTRIES_KEY]
                    for registry in registries:
                        deploy_cfg.add_registry(registry[EC.REGISTRY_ADDRESS_KEY],
                                                registry[EC.REGISTRY_USERNAME_KEY],
                                                registry[EC.REGISTRY_PASSWORD_KEY])
                else:
                    idx = 0
                    address = ''
                    username = ''
                    password = ''
                    for item in registries:
                        if idx == 0:
                            address = item
                        elif idx == 1:
                            username = item
                        else:
                            password = item
                            deploy_cfg.add_registry(address, username, password)
                        idx = (idx + 1) % 3

                image = args.image
                if image is None:
                    image = docker_deploy_data[EC.EDGE_RUNTIME_IMAGE_KEY]
                deploy_cfg.edge_image = image

                uri = args.docker_uri
                if uri is None:
                    uri = EdgeHostPlatform.get_docker_uri()
                deploy_cfg.uri = uri

                docker_log_cfg = docker_deploy_data[EC.DOCKER_LOGGING_OPTS_KEY]
                deploy_cfg.logging_driver = \
                    docker_log_cfg[EC.DOCKER_LOGGING_DRIVER_KEY]
                driver_log_opts = \
                    docker_log_cfg[EC.DOCKER_LOGGING_DRIVER_OPTS_KEY]
                for opt_key, opt_val in list(driver_log_opts.items()):
                    deploy_cfg.add_logging_option(opt_key, opt_val)

            if deploy_cfg is None:
                raise ValueError('Unsupported deployment type: %s', self._deployment_type)

            config.deployment_config = deploy_cfg

            subj_dict = {}
            if args.country:
                subj_dict[EC.SUBJECT_COUNTRY_KEY] = args.country
            if args.state:
                subj_dict[EC.SUBJECT_STATE_KEY] = args.state
            if args.locality:
                subj_dict[EC.SUBJECT_LOCALITY_KEY] = args.locality
            if args.organization:
                subj_dict[EC.SUBJECT_ORGANIZATION_KEY] = args.organization
            if args.organization_unit:
                subj_dict[EC.SUBJECT_ORGANIZATION_UNIT_KEY] = args.organization_unit
            if args.common_name:
                subj_dict[EC.SUBJECT_COMMON_NAME_KEY] = args.common_name

            cert_config = EdgeCertConfig()
            cert_config.set_options(args.auto_cert_gen_force_no_passwords,
                                    subj_dict,
                                    owner_ca_cert_file=args.owner_ca_cert_file,
                                    device_ca_cert_file=args.device_ca_cert_file,
                                    device_ca_chain_cert_file=args.device_ca_chain_cert_file,
                                    device_ca_private_key_file=args.device_ca_private_key_file,
                                    device_ca_passphrase=args.device_ca_passphrase,
                                    device_ca_passphrase_file=args.device_ca_passphrase_file,
                                    agent_ca_passphrase=args.agent_ca_passphrase,
                                    agent_ca_passphrase_file=args.agent_ca_passphrase_file)
            config.certificate_config = cert_config
            return config
        except ValueError as ex_value:
            log.error('Error parsing user input data: %s.', str(ex_value))
            raise edgectl.errors.EdgeValueError('Error parsing user input data')
Exemple #26
0
 def test_prompt_password(self, mock_getpass):
     """ Test a valid invocation of API prompt_password """
     valid_pass = '******'
     mock_getpass.return_value = valid_pass
     result = EdgeUtils.prompt_password('test password', 5, 8)
     self.assertTrue(valid_pass, result)