Exemple #1
0
    def process(self, data):
        """Process the given data received from the cloud-config userdata.

        It knows to process only lists and dicts.
        """
        if not isinstance(data, (list, dict)):
            raise exception.CloudbaseInitException(
                "Can't process the type of data %r" % type(data))

        osutils = osutils_factory.get_os_utils()

        for item in data:
            group_name = None
            group_users = []

            if isinstance(item, six.string_types):
                group_name = item
            elif isinstance(item, dict):
                try:
                    group_name = list(item.keys())[0]
                    group_users = item.get(group_name, [])
                except Exception:
                    LOG.error("Group details could not be parsed")
                    raise
            else:
                raise exception.CloudbaseInitException(
                    "Unrecognized type '%r' in group definition" % type(item))

            if not group_name:
                LOG.warning("Group name cannot be empty")
                continue

            try:
                if not osutils.group_exists(group_name):
                    osutils.create_group(group_name)
                else:
                    LOG.warning("Group '%s' already exists" % group_name)
                for group_user in group_users:
                    osutils.add_user_to_local_group(group_user, group_name)
            except Exception as exc:
                raise exception.CloudbaseInitException(
                    "Group '%s' could not be configured. Exception code: %s" %
                    (group_name, exc))

        return False
Exemple #2
0
    def seek(self, offset):
        high = wintypes.DWORD(offset >> 32)
        low = wintypes.DWORD(offset & 0xFFFFFFFF)

        ret_val = kernel32.SetFilePointer(self._handle, low,
                                          ctypes.byref(high),
                                          self.FILE_BEGIN)
        if ret_val == self.INVALID_SET_FILE_POINTER:
            raise exception.CloudbaseInitException("Seek error")
Exemple #3
0
 def set_service_start_mode(self, service_name, start_mode):
     # TODO(alexpilotti): Handle the "Delayed Start" case
     service = self._get_service(service_name)
     (ret_val,) = service.ChangeStartMode(start_mode)
     if ret_val != 0:
         raise exception.CloudbaseInitException(
             'Setting service %(service_name)s start mode failed with '
             'return value: %(ret_val)d' % {'service_name': service_name,
                                            'ret_val': ret_val})
Exemple #4
0
 def stop_service(self, service_name):
     LOG.debug('Stopping service %s', service_name)
     service = self._get_service(service_name)
     (ret_val,) = service.StopService()
     if ret_val != 0:
         raise exception.CloudbaseInitException(
             'Stopping service %(service_name)s failed with return value:'
             ' %(ret_val)d' % {'service_name': service_name,
                               'ret_val': ret_val})
def set_current_bcd_device_to_boot_partition():
    current_store = _get_current_bcd_store()

    success, = current_store.SetDeviceElement(Type=BCDOSLOADER_DEVICE_OSDEVICE,
                                              DeviceType=BOOT_DEVICE,
                                              AdditionalOptions="")
    if not success:
        raise exception.CloudbaseInitException(
            "Cannot set device element: %s" % BCDOSLOADER_DEVICE_OSDEVICE)

    success, = current_store.SetDeviceElement(
        Type=BCDLIBRARY_DEVICE_APPLICATION_DEVICE,
        DeviceType=BOOT_DEVICE,
        AdditionalOptions="")
    if not success:
        raise exception.CloudbaseInitException(
            "Cannot set device element: %s" %
            BCDLIBRARY_DEVICE_APPLICATION_DEVICE)
Exemple #6
0
    def _get_logical_drives(self):
        buf_size = self.MAX_PATH
        buf = ctypes.create_unicode_buffer(buf_size + 1)
        buf_len = kernel32.GetLogicalDriveStringsW(buf_size, buf)
        if not buf_len:
            raise exception.CloudbaseInitException(
                "GetLogicalDriveStringsW failed")

        return self._split_str_buf_list(buf, buf_len)
def enable_auto_recovery(enable):
    current_store = _get_current_bcd_store()

    success, = current_store.SetBooleanElement(
        BCDLIBRARY_BOOLEAN_AUTO_RECOVERY_ENABLED, enable)
    if not success:
        raise exception.CloudbaseInitException(
            "Cannot set boolean element: %s" %
            BCDLIBRARY_BOOLEAN_AUTO_RECOVERY_ENABLED)
Exemple #8
0
    def _get_credentials(self, shared_data):
        user_name = shared_data.get(constants.SHARED_DATA_USERNAME)
        if not user_name:
            raise exception.CloudbaseInitException(
                "Cannot execute plugin as the username has not been set in "
                "the plugins shared data")

        password = shared_data.get(constants.SHARED_DATA_PASSWORD)
        if not password:
            raise exception.CloudbaseInitException(
                "Cannot execute plugin as the password has not been set in the"
                " plugins shared data")

        # For security reasons unset the password in the shared_data
        # as it is currently not needed by other plugins
        shared_data[constants.SHARED_DATA_PASSWORD] = None

        return (user_name, password)
def _name2idx(name):
    """Get the position of a network interface by its name."""
    match = re.search(r"eth(\d+)", name, re.I)
    if not match:
        raise exception.CloudbaseInitException(
            "invalid NetworkDetails name {!r}"
            .format(name)
        )
    return int(match.group(1))
Exemple #10
0
 def get_physical_path(self):
     buf = ctypes.create_unicode_buffer(1024)
     bufLen = wintypes.DWORD(ctypes.sizeof(buf))
     ret_val = virtdisk.GetVirtualDiskPhysicalPath(self._handle,
                                                   ctypes.byref(bufLen),
                                                   buf)
     if ret_val:
         raise exception.CloudbaseInitException(
             "Cannot get virtual disk physical path")
     return buf.value
Exemple #11
0
 def _get_user_info(self, username, level):
     try:
         return win32net.NetUserGetInfo(None, username, level)
     except win32net.error as ex:
         if ex.args[0] == self.NERR_UserNotFound:
             raise exception.ItemNotFoundException("User not found: %s" %
                                                   username)
         else:
             raise exception.CloudbaseInitException(
                 "Failed to get user info: %s" % ex.args[2])
Exemple #12
0
    def set_network_adapter_mtu(self, mac_address, mtu):
        if not self.check_os_version(6, 0):
            raise exception.CloudbaseInitException(
                'Setting the MTU is currently not supported on Windows XP '
                'and Windows Server 2003')

        iface_index_list = [
            net_addr["interface_index"]
            for net_addr in network.get_adapter_addresses()
            if net_addr["mac_address"] == mac_address
        ]

        if not iface_index_list:
            raise exception.CloudbaseInitException(
                'Network interface with MAC address "%s" not found' %
                mac_address)
        else:
            iface_index = iface_index_list[0]

            LOG.debug(
                'Setting MTU for interface "%(mac_address)s" with '
                'value "%(mtu)s"', {
                    'mac_address': mac_address,
                    'mtu': mtu
                })

            base_dir = self._get_system_dir()
            netsh_path = os.path.join(base_dir, 'netsh.exe')

            args = [
                netsh_path, "interface", "ipv4", "set", "subinterface",
                str(iface_index),
                "mtu=%s" % mtu, "store=persistent"
            ]
            (out, err, ret_val) = self.execute_process(args, shell=False)
            if ret_val:
                raise exception.CloudbaseInitException(
                    'Setting MTU for interface "%(mac_address)s" with '
                    'value "%(mtu)s" failed' % {
                        'mac_address': mac_address,
                        'mtu': mtu
                    })
Exemple #13
0
 def _get_timezone_info(self):
     keyname = os.path.join(REG_TIME_ZONES, self._name)
     try:
         with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, keyname) as key:
             return self._unpack_timezone_info(key)
     except WindowsError as exc:
         if exc.errno == NOT_FOUND:
             raise exception.CloudbaseInitException(
                 "Timezone %r not found" % self._name)
         else:
             raise
Exemple #14
0
    def _get_goal_state(self, force_update=False):
        if not self._goal_state or force_update:
            self._goal_state = self._wire_server_request(
                "machine?comp=goalstate").GoalState

        expected_state = self._goal_state.Machine.ExpectedState
        if expected_state != GOAL_STATE_STARTED:
            raise exception.CloudbaseInitException(
                "Invalid machine expected state: %s" % expected_state)

        return self._goal_state
Exemple #15
0
    def change_password_next_logon(self, username):
        """Force the given user to change the password at next logon."""
        user_info = self._get_user_info(username, 4)
        user_info["flags"] &= ~win32netcon.UF_DONT_EXPIRE_PASSWD
        user_info["password_expired"] = 1

        try:
            win32net.NetUserSetInfo(None, username, 4, user_info)
        except win32net.error as ex:
            raise exception.CloudbaseInitException(
                "Setting password expiration failed: %s" % ex.args[2])
    def open(self):
        if self._handle:
            self.close()

        handle = kernel32.CreateFileW(ctypes.c_wchar_p(self._path),
                                      self.GENERIC_READ, self.FILE_SHARE_READ,
                                      0, self.OPEN_EXISTING,
                                      self.FILE_ATTRIBUTE_READONLY, 0)
        if handle == self.INVALID_HANDLE_VALUE:
            raise exception.CloudbaseInitException('Cannot open file')
        self._handle = handle
def _run_bcdedit(bcdedit_args):
    args = ["bcdedit.exe"] + bcdedit_args
    osutils = osutils_factory.get_os_utils()
    (out, err, ret_val) = osutils.execute_system32_process(args)
    if ret_val:
        raise exception.CloudbaseInitException(
            'bcdedit failed.\nOutput: %(out)s\nError:'
            ' %(err)s' % {
                'out': out,
                'err': err
            })
Exemple #18
0
def _socket_addr_to_str(socket_addr):
    addr_str_len = wintypes.DWORD(256)
    addr_str = ctypes.create_unicode_buffer(256)

    ret_val = ws2_32.WSAAddressToStringW(socket_addr.lpSockaddr,
                                         socket_addr.iSockaddrLength, None,
                                         addr_str, ctypes.byref(addr_str_len))
    if ret_val:
        raise exception.CloudbaseInitException(
            "WSAAddressToStringW failed: %s" % ws2_32.WSAGetLastError())

    return addr_str.value
Exemple #19
0
def get_metadata_service():
    # Return the first service that loads correctly
    cl = classloader.ClassLoader()
    for class_path in CONF.metadata_services:
        service = cl.load_class(class_path)()
        try:
            if service.load():
                return service
        except Exception as ex:
            LOG.error("Failed to load metadata service '%s'" % class_path)
            LOG.exception(ex)
    raise exception.CloudbaseInitException("No available service found")
Exemple #20
0
 def _get_network_config_parser(self, parser_type):
     parsers = {
         self.NETWORK_LINK_TYPE_PHY: self._parse_physical_config_item,
         self.NETWORK_LINK_TYPE_BOND: self._parse_bond_config_item,
         self.NETWORK_LINK_TYPE_VLAN: self._parse_vlan_config_item,
         self.NETWORK_SERVICE_NAMESERVER: self._parse_nameserver_config_item
     }
     parser = parsers.get(parser_type)
     if not parser:
         raise exception.CloudbaseInitException(
             "Network config parser '%s' does not exist", parser_type)
     return parser
Exemple #21
0
    def create_user_logon_session(self, username, password, domain='.',
                                  load_profile=True):
        token = wintypes.HANDLE()
        ret_val = advapi32.LogonUserW(six.text_type(username),
                                      six.text_type(domain),
                                      six.text_type(password), 2, 0,
                                      ctypes.byref(token))
        if not ret_val:
            raise exception.CloudbaseInitException("User logon failed")

        if load_profile:
            pi = Win32_PROFILEINFO()
            pi.dwSize = ctypes.sizeof(Win32_PROFILEINFO)
            pi.lpUserName = six.text_type(username)
            ret_val = userenv.LoadUserProfileW(token, ctypes.byref(pi))
            if not ret_val:
                kernel32.CloseHandle(token)
                raise exception.CloudbaseInitException(
                    "Cannot load user profile")

        return token
Exemple #22
0
    def set_ntp_client_config(self, ntp_host):
        base_dir = self._get_system_dir()
        w32tm_path = os.path.join(base_dir, "w32tm.exe")

        args = [w32tm_path, '/config', '/manualpeerlist:%s' % ntp_host,
                '/syncfromflags:manual', '/update']

        (out, err, ret_val) = self.execute_process(args, False)
        if ret_val:
            raise exception.CloudbaseInitException(
                'w32tm failed to configure NTP.\nOutput: %(out)s\nError:'
                ' %(err)s' % {'out': out, 'err': err})
Exemple #23
0
    def add_static_route(self, destination, mask, next_hop, interface_index,
                         metric):
        if not isinstance(next_hop, six.text_type):
            next_hop = next_hop.decode('utf-8')

        args = ['ROUTE', 'ADD', destination, 'MASK', mask,
                next_hop]
        (out, err, ret_val) = self.execute_process(args)
        # Cannot use the return value to determine the outcome
        if ret_val or err:
            raise exception.CloudbaseInitException(
                'Unable to add route: %s' % err)
Exemple #24
0
    def add_user_to_local_group(self, username, groupname):

        lmi = Win32_LOCALGROUP_MEMBERS_INFO_3()
        lmi.lgrmi3_domainandname = six.text_type(username)

        ret_val = netapi32.NetLocalGroupAddMembers(0, six.text_type(groupname),
                                                   3, ctypes.addressof(lmi), 1)

        if ret_val == self.NERR_GroupNotFound:
            raise exception.CloudbaseInitException('Group not found')
        elif ret_val == self.ERROR_ACCESS_DENIED:
            raise exception.CloudbaseInitException('Access denied')
        elif ret_val == self.ERROR_NO_SUCH_MEMBER:
            raise exception.CloudbaseInitException('Username not found')
        elif ret_val == self.ERROR_MEMBER_IN_ALIAS:
            # The user is already a member of the group
            pass
        elif ret_val == self.ERROR_INVALID_MEMBER:
            raise exception.CloudbaseInitException('Invalid user')
        elif ret_val != 0:
            raise exception.CloudbaseInitException('Unknown error')
Exemple #25
0
 def _delete_static_route(self, network):
     """Delete a route from the operating system."""
     try:
         osutils = osutils_factory.get_os_utils()
         LOG.debug('Deleting route for network: %s', network)
         args = ['ROUTE', 'DELETE', network]
         (out, err, ret_val) = osutils.execute_process(args)
         if ret_val or err:
             raise exception.CloudbaseInitException(
                 'Failed to delete route: %s' % err)
     except Exception as ex:
         LOG.exception(ex)
Exemple #26
0
    def _extract_files_from_iso(self, iso_file_path):
        args = [CONF.bsdtar_path, '-xf', iso_file_path,
                '-C', self.target_path]
        (out, err, exit_code) = self._osutils.execute_process(args, False)

        if exit_code:
            raise exception.CloudbaseInitException(
                'Failed to execute "bsdtar" from path "%(bsdtar_path)s" with '
                'exit code: %(exit_code)s\n%(out)s\n%(err)s' % {
                    'bsdtar_path': CONF.bsdtar_path,
                    'exit_code': exit_code,
                    'out': out, 'err': err})
Exemple #27
0
    def set_static_network_config(self, mac_address, address, netmask,
                                  broadcast, gateway, dnsnameservers):
        conn = wmi.WMI(moniker='//./root/cimv2')

        query = conn.query("SELECT * FROM Win32_NetworkAdapter WHERE "
                           "MACAddress = '{}'".format(mac_address))
        if not len(query):
            raise exception.CloudbaseInitException(
                "Network adapter not found")

        adapter_config = query[0].associators(
            wmi_result_class='Win32_NetworkAdapterConfiguration')[0]

        LOG.debug("Setting static IP address")
        (ret_val,) = adapter_config.EnableStatic([address], [netmask])
        if ret_val > 1:
            raise exception.CloudbaseInitException(
                "Cannot set static IP address on network adapter (%d)",
                ret_val)
        reboot_required = (ret_val == 1)

        if gateway:
            LOG.debug("Setting static gateways")
            (ret_val,) = adapter_config.SetGateways([gateway], [1])
            if ret_val > 1:
                raise exception.CloudbaseInitException(
                    "Cannot set gateway on network adapter (%d)",
                    ret_val)
            reboot_required = reboot_required or ret_val == 1

        if dnsnameservers:
            LOG.debug("Setting static DNS servers")
            (ret_val,) = adapter_config.SetDNSServerSearchOrder(dnsnameservers)
            if ret_val > 1:
                raise exception.CloudbaseInitException(
                    "Cannot set DNS on network adapter (%d)",
                    ret_val)
            reboot_required = reboot_required or ret_val == 1

        return reboot_required
Exemple #28
0
    def _preprocess_options(self):
        self._searched_types = set(CONF.config_drive_types)
        self._searched_locations = set(CONF.config_drive_locations)

        # Deprecation backward compatibility.
        if CONF.config_drive_raw_hhd:
            self._searched_types.add("iso")
            self._searched_locations.add("hdd")
        if CONF.config_drive_cdrom:
            self._searched_types.add("iso")
            self._searched_locations.add("cdrom")
        if CONF.config_drive_vfat:
            self._searched_types.add("vfat")
            self._searched_locations.add("hdd")

        # Check for invalid option values.
        if self._searched_types | CD_TYPES != CD_TYPES:
            raise exception.CloudbaseInitException(
                "Invalid Config Drive types %s", self._searched_types)
        if self._searched_locations | CD_LOCATIONS != CD_LOCATIONS:
            raise exception.CloudbaseInitException(
                "Invalid Config Drive locations %s", self._searched_locations)
 def get_geometry(self):
     if not self._geom:
         geom = Win32_DiskGeometry()
         bytes_returned = wintypes.DWORD()
         ret_val = kernel32.DeviceIoControl(
             self._handle, self.IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0,
             ctypes.byref(geom), ctypes.sizeof(geom),
             ctypes.byref(bytes_returned), 0)
         if not ret_val:
             raise exception.CloudbaseInitException(
                 "Cannot get disk geometry")
         self._geom = geom
     return self._geom
Exemple #30
0
    def _get_credentials(service, shared_data):
        user_name = shared_data.get(constants.SHARED_DATA_USERNAME,
                                    CONF.username)
        if not user_name:
            raise exception.CloudbaseInitException(
                "Cannot execute plugin as the username has not been set in "
                "the plugins shared data, nor it was found in config file.")

        password = shared_data.get(constants.SHARED_DATA_PASSWORD)
        if not password:
            password = service.get_admin_password()
            if not password:
                raise exception.CloudbaseInitException(
                    "Cannot execute plugin as the password has not been set "
                    "in the plugins shared data, nor it was retrieved "
                    "from the metadata service.")

        # For security reasons unset the password in the shared_data
        # as it is currently not needed by other plugins
        shared_data[constants.SHARED_DATA_PASSWORD] = None

        return user_name, password