diff options
author | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:32 +0000 |
---|---|---|
committer | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:32 +0000 |
commit | a73c1da43a113ab268679faaf67bc59882d570d8 (patch) | |
tree | ce681f8bb3c0b303034a46e97907504d5cfe5d0d | |
parent | ca86205e7dc386f0a9d7a709fd2f096f4523e758 (diff) | |
download | ansible-a73c1da43a113ab268679faaf67bc59882d570d8.tar.gz |
Migrated to ansible.windows
324 files changed, 0 insertions, 40886 deletions
diff --git a/lib/ansible/module_utils/csharp/Ansible.Service.cs b/lib/ansible/module_utils/csharp/Ansible.Service.cs deleted file mode 100644 index be0f3db3f3..0000000000 --- a/lib/ansible/module_utils/csharp/Ansible.Service.cs +++ /dev/null @@ -1,1341 +0,0 @@ -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Text; -using Ansible.Privilege; - -namespace Ansible.Service -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct ENUM_SERVICE_STATUSW - { - public string lpServiceName; - public string lpDisplayName; - public SERVICE_STATUS ServiceStatus; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct QUERY_SERVICE_CONFIGW - { - public ServiceType dwServiceType; - public ServiceStartType dwStartType; - public ErrorControl dwErrorControl; - [MarshalAs(UnmanagedType.LPWStr)] public string lpBinaryPathName; - [MarshalAs(UnmanagedType.LPWStr)] public string lpLoadOrderGroup; - public Int32 dwTagId; - public IntPtr lpDependencies; // Can't rely on marshaling as dependencies are delimited by \0. - [MarshalAs(UnmanagedType.LPWStr)] public string lpServiceStartName; - [MarshalAs(UnmanagedType.LPWStr)] public string lpDisplayName; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SC_ACTION - { - public FailureAction Type; - public UInt32 Delay; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_DELAYED_AUTO_START_INFO - { - public bool fDelayedAutostart; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct SERVICE_DESCRIPTIONW - { - [MarshalAs(UnmanagedType.LPWStr)] public string lpDescription; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_FAILURE_ACTIONS_FLAG - { - public bool fFailureActionsOnNonCrashFailures; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct SERVICE_FAILURE_ACTIONSW - { - public UInt32 dwResetPeriod; - [MarshalAs(UnmanagedType.LPWStr)] public string lpRebootMsg; - [MarshalAs(UnmanagedType.LPWStr)] public string lpCommand; - public UInt32 cActions; - public IntPtr lpsaActions; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_LAUNCH_PROTECTED_INFO - { - public LaunchProtection dwLaunchProtected; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_PREFERRED_NODE_INFO - { - public UInt16 usPreferredNode; - public bool fDelete; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_PRESHUTDOWN_INFO - { - public UInt32 dwPreshutdownTimeout; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct SERVICE_REQUIRED_PRIVILEGES_INFOW - { - // Can't rely on marshaling as privileges are delimited by \0. - public IntPtr pmszRequiredPrivileges; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_SID_INFO - { - public ServiceSidInfo dwServiceSidType; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_STATUS - { - public ServiceType dwServiceType; - public ServiceStatus dwCurrentState; - public ControlsAccepted dwControlsAccepted; - public UInt32 dwWin32ExitCode; - public UInt32 dwServiceSpecificExitCode; - public UInt32 dwCheckPoint; - public UInt32 dwWaitHint; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_STATUS_PROCESS - { - public ServiceType dwServiceType; - public ServiceStatus dwCurrentState; - public ControlsAccepted dwControlsAccepted; - public UInt32 dwWin32ExitCode; - public UInt32 dwServiceSpecificExitCode; - public UInt32 dwCheckPoint; - public UInt32 dwWaitHint; - public UInt32 dwProcessId; - public ServiceFlags dwServiceFlags; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_TRIGGER - { - public TriggerType dwTriggerType; - public TriggerAction dwAction; - public IntPtr pTriggerSubtype; - public UInt32 cDataItems; - public IntPtr pDataItems; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_TRIGGER_SPECIFIC_DATA_ITEM - { - public TriggerDataType dwDataType; - public UInt32 cbData; - public IntPtr pData; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SERVICE_TRIGGER_INFO - { - public UInt32 cTriggers; - public IntPtr pTriggers; - public IntPtr pReserved; - } - - public enum ConfigInfoLevel : uint - { - SERVICE_CONFIG_DESCRIPTION = 0x00000001, - SERVICE_CONFIG_FAILURE_ACTIONS = 0x00000002, - SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 0x00000003, - SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 0x00000004, - SERVICE_CONFIG_SERVICE_SID_INFO = 0x00000005, - SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 0x00000006, - SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007, - SERVICE_CONFIG_TRIGGER_INFO = 0x00000008, - SERVICE_CONFIG_PREFERRED_NODE = 0x00000009, - SERVICE_CONFIG_LAUNCH_PROTECTED = 0x0000000c, - } - } - - internal class NativeMethods - { - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool ChangeServiceConfigW( - SafeHandle hService, - ServiceType dwServiceType, - ServiceStartType dwStartType, - ErrorControl dwErrorControl, - string lpBinaryPathName, - string lpLoadOrderGroup, - IntPtr lpdwTagId, - string lpDependencies, - string lpServiceStartName, - string lpPassword, - string lpDisplayName); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool ChangeServiceConfig2W( - SafeHandle hService, - NativeHelpers.ConfigInfoLevel dwInfoLevel, - IntPtr lpInfo); - - [DllImport("Advapi32.dll", SetLastError = true)] - public static extern bool CloseServiceHandle( - IntPtr hSCObject); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeServiceHandle CreateServiceW( - SafeHandle hSCManager, - string lpServiceName, - string lpDisplayName, - ServiceRights dwDesiredAccess, - ServiceType dwServiceType, - ServiceStartType dwStartType, - ErrorControl dwErrorControl, - string lpBinaryPathName, - string lpLoadOrderGroup, - IntPtr lpdwTagId, - string lpDependencies, - string lpServiceStartName, - string lpPassword); - - [DllImport("Advapi32.dll", SetLastError = true)] - public static extern bool DeleteService( - SafeHandle hService); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool EnumDependentServicesW( - SafeHandle hService, - UInt32 dwServiceState, - SafeMemoryBuffer lpServices, - UInt32 cbBufSize, - out UInt32 pcbBytesNeeded, - out UInt32 lpServicesReturned); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeServiceHandle OpenSCManagerW( - string lpMachineName, - string lpDatabaseNmae, - SCMRights dwDesiredAccess); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeServiceHandle OpenServiceW( - SafeHandle hSCManager, - string lpServiceName, - ServiceRights dwDesiredAccess); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool QueryServiceConfigW( - SafeHandle hService, - IntPtr lpServiceConfig, - UInt32 cbBufSize, - out UInt32 pcbBytesNeeded); - - [DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool QueryServiceConfig2W( - SafeHandle hservice, - NativeHelpers.ConfigInfoLevel dwInfoLevel, - IntPtr lpBuffer, - UInt32 cbBufSize, - out UInt32 pcbBytesNeeded); - - [DllImport("Advapi32.dll", SetLastError = true)] - public static extern bool QueryServiceStatusEx( - SafeHandle hService, - UInt32 InfoLevel, - IntPtr lpBuffer, - UInt32 cbBufSize, - out UInt32 pcbBytesNeeded); - } - - internal class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public UInt32 BufferLength { get; internal set; } - - public SafeMemoryBuffer() : base(true) { } - public SafeMemoryBuffer(int cb) : base(true) - { - BufferLength = (UInt32)cb; - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - public SafeMemoryBuffer(IntPtr handle) : base(true) - { - base.SetHandle(handle); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - internal class SafeServiceHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeServiceHandle() : base(true) { } - public SafeServiceHandle(IntPtr handle) : base(true) { this.handle = handle; } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - return NativeMethods.CloseServiceHandle(handle); - } - } - - [Flags] - public enum ControlsAccepted : uint - { - None = 0x00000000, - Stop = 0x00000001, - PauseContinue = 0x00000002, - Shutdown = 0x00000004, - ParamChange = 0x00000008, - NetbindChange = 0x00000010, - HardwareProfileChange = 0x00000020, - PowerEvent = 0x00000040, - SessionChange = 0x00000080, - PreShutdown = 0x00000100, - } - - public enum ErrorControl : uint - { - Ignore = 0x00000000, - Normal = 0x00000001, - Severe = 0x00000002, - Critical = 0x00000003, - } - - public enum FailureAction : uint - { - None = 0x00000000, - Restart = 0x00000001, - Reboot = 0x00000002, - RunCommand = 0x00000003, - } - - public enum LaunchProtection : uint - { - None = 0, - Windows = 1, - WindowsLight = 2, - AntimalwareLight = 3, - } - - [Flags] - public enum SCMRights : uint - { - Connect = 0x00000001, - CreateService = 0x00000002, - EnumerateService = 0x00000004, - Lock = 0x00000008, - QueryLockStatus = 0x00000010, - ModifyBootConfig = 0x00000020, - AllAccess = 0x000F003F, - } - - [Flags] - public enum ServiceFlags : uint - { - None = 0x0000000, - RunsInSystemProcess = 0x00000001, - } - - [Flags] - public enum ServiceRights : uint - { - QueryConfig = 0x00000001, - ChangeConfig = 0x00000002, - QueryStatus = 0x00000004, - EnumerateDependents = 0x00000008, - Start = 0x00000010, - Stop = 0x00000020, - PauseContinue = 0x00000040, - Interrogate = 0x00000080, - UserDefinedControl = 0x00000100, - Delete = 0x00010000, - ReadControl = 0x00020000, - WriteDac = 0x00040000, - WriteOwner = 0x00080000, - AllAccess = 0x000F01FF, - AccessSystemSecurity = 0x01000000, - } - - public enum ServiceStartType : uint - { - BootStart = 0x00000000, - SystemStart = 0x00000001, - AutoStart = 0x00000002, - DemandStart = 0x00000003, - Disabled = 0x00000004, - - // Not part of ChangeServiceConfig enumeration but built by the Srvice class for the StartType property. - AutoStartDelayed = 0x1000000 - } - - [Flags] - public enum ServiceType : uint - { - KernelDriver = 0x00000001, - FileSystemDriver = 0x00000002, - Adapter = 0x00000004, - RecognizerDriver = 0x00000008, - Driver = KernelDriver | FileSystemDriver | RecognizerDriver, - Win32OwnProcess = 0x00000010, - Win32ShareProcess = 0x00000020, - Win32 = Win32OwnProcess | Win32ShareProcess, - UserProcess = 0x00000040, - UserOwnprocess = Win32OwnProcess | UserProcess, - UserShareProcess = Win32ShareProcess | UserProcess, - UserServiceInstance = 0x00000080, - InteractiveProcess = 0x00000100, - PkgService = 0x00000200, - } - - public enum ServiceSidInfo : uint - { - None, - Unrestricted, - Restricted = 3, - } - - public enum ServiceStatus : uint - { - Stopped = 0x00000001, - StartPending = 0x00000002, - StopPending = 0x00000003, - Running = 0x00000004, - ContinuePending = 0x00000005, - PausePending = 0x00000006, - Paused = 0x00000007, - } - - public enum TriggerAction : uint - { - ServiceStart = 0x00000001, - ServiceStop = 0x000000002, - } - - public enum TriggerDataType : uint - { - Binary = 00000001, - String = 0x00000002, - Level = 0x00000003, - KeywordAny = 0x00000004, - KeywordAll = 0x00000005, - } - - public enum TriggerType : uint - { - DeviceInterfaceArrival = 0x00000001, - IpAddressAvailability = 0x00000002, - DomainJoin = 0x00000003, - FirewallPortEvent = 0x00000004, - GroupPolicy = 0x00000005, - NetworkEndpoint = 0x00000006, - Custom = 0x00000014, - } - - public class ServiceManagerException : System.ComponentModel.Win32Exception - { - private string _msg; - - public ServiceManagerException(string message) : this(Marshal.GetLastWin32Error(), message) { } - public ServiceManagerException(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2} - 0x{2:X8})", message, base.Message, errorCode); - } - - public override string Message { get { return _msg; } } - public static explicit operator ServiceManagerException(string message) - { - return new ServiceManagerException(message); - } - } - - public class Action - { - public FailureAction Type; - public UInt32 Delay; - } - - public class FailureActions - { - public UInt32? ResetPeriod = null; // Get is always populated, can be null on set to preserve existing. - public string RebootMsg = null; - public string Command = null; - public List<Action> Actions = null; - - public FailureActions() { } - - internal FailureActions(NativeHelpers.SERVICE_FAILURE_ACTIONSW actions) - { - ResetPeriod = actions.dwResetPeriod; - RebootMsg = actions.lpRebootMsg; - Command = actions.lpCommand; - Actions = new List<Action>(); - - int actionLength = Marshal.SizeOf(typeof(NativeHelpers.SC_ACTION)); - for (int i = 0; i < actions.cActions; i++) - { - IntPtr actionPtr = IntPtr.Add(actions.lpsaActions, i * actionLength); - - NativeHelpers.SC_ACTION rawAction = (NativeHelpers.SC_ACTION)Marshal.PtrToStructure( - actionPtr, typeof(NativeHelpers.SC_ACTION)); - - Actions.Add(new Action() - { - Type = rawAction.Type, - Delay = rawAction.Delay, - }); - } - } - } - - public class TriggerItem - { - public TriggerDataType Type; - public object Data; // Can be string, List<string>, byte, byte[], or Int64 depending on Type. - - public TriggerItem() { } - - internal TriggerItem(NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM dataItem) - { - Type = dataItem.dwDataType; - - byte[] itemBytes = new byte[dataItem.cbData]; - Marshal.Copy(dataItem.pData, itemBytes, 0, itemBytes.Length); - - switch (dataItem.dwDataType) - { - case TriggerDataType.String: - string value = Encoding.Unicode.GetString(itemBytes, 0, itemBytes.Length); - - if (value.EndsWith("\0\0")) - { - // Multistring with a delimiter of \0 and terminated with \0\0. - Data = new List<string>(value.Split(new char[1] { '\0' }, StringSplitOptions.RemoveEmptyEntries)); - } - else - // Just a single string with null character at the end, strip it off. - Data = value.Substring(0, value.Length - 1); - break; - case TriggerDataType.Level: - Data = itemBytes[0]; - break; - case TriggerDataType.KeywordAll: - case TriggerDataType.KeywordAny: - Data = BitConverter.ToUInt64(itemBytes, 0); - break; - default: - Data = itemBytes; - break; - } - } - } - - public class Trigger - { - // https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_trigger - public const string NAMED_PIPE_EVENT_GUID = "1f81d131-3fac-4537-9e0c-7e7b0c2f4b55"; - public const string RPC_INTERFACE_EVENT_GUID = "bc90d167-9470-4139-a9ba-be0bbbf5b74d"; - public const string DOMAIN_JOIN_GUID = "1ce20aba-9851-4421-9430-1ddeb766e809"; - public const string DOMAIN_LEAVE_GUID = "ddaf516e-58c2-4866-9574-c3b615d42ea1"; - public const string FIREWALL_PORT_OPEN_GUID = "b7569e07-8421-4ee0-ad10-86915afdad09"; - public const string FIREWALL_PORT_CLOSE_GUID = "a144ed38-8e12-4de4-9d96-e64740b1a524"; - public const string MACHINE_POLICY_PRESENT_GUID = "659fcae6-5bdb-4da9-b1ff-ca2a178d46e0"; - public const string NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID = "4f27f2de-14e2-430b-a549-7cd48cbc8245"; - public const string NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID = "cc4ba62a-162e-4648-847a-b6bdf993e335"; - public const string USER_POLICY_PRESENT_GUID = "54fb46c8-f089-464c-b1fd-59d1b62c3b50"; - - public TriggerType Type; - public TriggerAction Action; - public Guid SubType; - public List<TriggerItem> DataItems = new List<TriggerItem>(); - - public Trigger() { } - - internal Trigger(NativeHelpers.SERVICE_TRIGGER trigger) - { - Type = trigger.dwTriggerType; - Action = trigger.dwAction; - SubType = (Guid)Marshal.PtrToStructure(trigger.pTriggerSubtype, typeof(Guid)); - - int dataItemLength = Marshal.SizeOf(typeof(NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM)); - for (int i = 0; i < trigger.cDataItems; i++) - { - IntPtr dataPtr = IntPtr.Add(trigger.pDataItems, i * dataItemLength); - - var dataItem = (NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM)Marshal.PtrToStructure( - dataPtr, typeof(NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM)); - - DataItems.Add(new TriggerItem(dataItem)); - } - } - } - - public class Service : IDisposable - { - private const UInt32 SERVICE_NO_CHANGE = 0xFFFFFFFF; - - private SafeServiceHandle _scmHandle; - private SafeServiceHandle _serviceHandle; - private SafeMemoryBuffer _rawServiceConfig; - private NativeHelpers.SERVICE_STATUS_PROCESS _statusProcess; - - private NativeHelpers.QUERY_SERVICE_CONFIGW _ServiceConfig - { - get - { - return (NativeHelpers.QUERY_SERVICE_CONFIGW)Marshal.PtrToStructure( - _rawServiceConfig.DangerousGetHandle(), typeof(NativeHelpers.QUERY_SERVICE_CONFIGW)); - } - } - - // ServiceConfig - public string ServiceName { get; private set; } - - public ServiceType ServiceType - { - get { return _ServiceConfig.dwServiceType; } - set { ChangeServiceConfig(serviceType: value); } - } - - public ServiceStartType StartType - { - get - { - ServiceStartType startType = _ServiceConfig.dwStartType; - if (startType == ServiceStartType.AutoStart) - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_DELAYED_AUTO_START_INFO>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_DELAYED_AUTO_START_INFO); - - if (value.fDelayedAutostart) - startType = ServiceStartType.AutoStartDelayed; - } - - return startType; - } - set - { - ServiceStartType newStartType = value; - bool delayedStart = false; - if (value == ServiceStartType.AutoStartDelayed) - { - newStartType = ServiceStartType.AutoStart; - delayedStart = true; - } - - ChangeServiceConfig(startType: newStartType); - - var info = new NativeHelpers.SERVICE_DELAYED_AUTO_START_INFO() - { - fDelayedAutostart = delayedStart, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, info); - } - } - - public ErrorControl ErrorControl - { - get { return _ServiceConfig.dwErrorControl; } - set { ChangeServiceConfig(errorControl: value); } - } - - public string Path - { - get { return _ServiceConfig.lpBinaryPathName; } - set { ChangeServiceConfig(binaryPath: value); } - } - - public string LoadOrderGroup - { - get { return _ServiceConfig.lpLoadOrderGroup; } - set { ChangeServiceConfig(loadOrderGroup: value); } - } - - public List<string> DependentOn - { - get - { - StringBuilder deps = new StringBuilder(); - IntPtr depPtr = _ServiceConfig.lpDependencies; - - bool wasNull = false; - while (true) - { - // Get the current char at the pointer and add it to the StringBuilder. - byte[] charBytes = new byte[sizeof(char)]; - Marshal.Copy(depPtr, charBytes, 0, charBytes.Length); - depPtr = IntPtr.Add(depPtr, charBytes.Length); - char currentChar = BitConverter.ToChar(charBytes, 0); - deps.Append(currentChar); - - // If the previous and current char is \0 exit the loop. - if (currentChar == '\0' && wasNull) - break; - wasNull = currentChar == '\0'; - } - - return new List<string>(deps.ToString().Split(new char[1] { '\0' }, - StringSplitOptions.RemoveEmptyEntries)); - } - set { ChangeServiceConfig(dependencies: value); } - } - - public IdentityReference Account - { - get - { - if (_ServiceConfig.lpServiceStartName == null) - // User services don't have the start name specified and will be null. - return null; - else if (_ServiceConfig.lpServiceStartName == "LocalSystem") - // Special string used for the SYSTEM account, this is the same even for different localisations. - return (NTAccount)new SecurityIdentifier("S-1-5-18").Translate(typeof(NTAccount)); - else - return new NTAccount(_ServiceConfig.lpServiceStartName); - } - set - { - string startName = null; - string pass = null; - - if (value != null) - { - // Create a SID and convert back from a SID to get the Netlogon form regardless of the input - // specified. - SecurityIdentifier accountSid = (SecurityIdentifier)value.Translate(typeof(SecurityIdentifier)); - NTAccount accountName = (NTAccount)accountSid.Translate(typeof(NTAccount)); - string[] accountSplit = accountName.Value.Split(new char[1] { '\\' }, 2); - - // SYSTEM, Local Service, Network Service - List<string> serviceAccounts = new List<string> { "S-1-5-18", "S-1-5-19", "S-1-5-20" }; - - // Well known service accounts and MSAs should have no password set. Explicitly blank out the - // existing password to ensure older passwords are no longer stored by Windows. - if (serviceAccounts.Contains(accountSid.Value) || accountSplit[1].EndsWith("$")) - pass = ""; - - // The SYSTEM account uses this special string to specify that account otherwise use the original - // NTAccount value in case it is in a custom format (not Netlogon) for a reason. - if (accountSid.Value == serviceAccounts[0]) - startName = "LocalSystem"; - else - startName = value.Translate(typeof(NTAccount)).Value; - } - - ChangeServiceConfig(startName: startName, password: pass); - } - } - - public string Password { set { ChangeServiceConfig(password: value); } } - - public string DisplayName - { - get { return _ServiceConfig.lpDisplayName; } - set { ChangeServiceConfig(displayName: value); } - } - - // ServiceConfig2 - - public string Description - { - get - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_DESCRIPTIONW>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_DESCRIPTION); - - return value.lpDescription; - } - set - { - var info = new NativeHelpers.SERVICE_DESCRIPTIONW() - { - lpDescription = value, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_DESCRIPTION, info); - } - } - - public FailureActions FailureActions - { - get - { - using (SafeMemoryBuffer b = QueryServiceConfig2( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS)) - { - NativeHelpers.SERVICE_FAILURE_ACTIONSW value = (NativeHelpers.SERVICE_FAILURE_ACTIONSW) - Marshal.PtrToStructure(b.DangerousGetHandle(), typeof(NativeHelpers.SERVICE_FAILURE_ACTIONSW)); - - return new FailureActions(value); - } - } - set - { - // dwResetPeriod and lpsaActions must be set together, we need to read the existing config if someone - // wants to update 1 or the other but both aren't explicitly defined. - UInt32? resetPeriod = value.ResetPeriod; - List<Action> actions = value.Actions; - if ((resetPeriod != null && actions == null) || (resetPeriod == null && actions != null)) - { - FailureActions existingValue = this.FailureActions; - - if (resetPeriod != null && existingValue.Actions.Count == 0) - throw new ArgumentException( - "Cannot set FailureAction ResetPeriod without explicit Actions and no existing Actions"); - else if (resetPeriod == null) - resetPeriod = (UInt32)existingValue.ResetPeriod; - - if (actions == null) - actions = existingValue.Actions; - } - - var info = new NativeHelpers.SERVICE_FAILURE_ACTIONSW() - { - dwResetPeriod = resetPeriod == null ? 0 : (UInt32)resetPeriod, - lpRebootMsg = value.RebootMsg, - lpCommand = value.Command, - cActions = actions == null ? 0 : (UInt32)actions.Count, - lpsaActions = IntPtr.Zero, - }; - - // null means to keep the existing actions whereas an empty list deletes the actions. - if (actions == null) - { - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS, info); - return; - } - - int actionLength = Marshal.SizeOf(typeof(NativeHelpers.SC_ACTION)); - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer(actionLength * actions.Count)) - { - info.lpsaActions = buffer.DangerousGetHandle(); - HashSet<string> privileges = new HashSet<string>(); - - for (int i = 0; i < actions.Count; i++) - { - IntPtr actionPtr = IntPtr.Add(info.lpsaActions, i * actionLength); - NativeHelpers.SC_ACTION action = new NativeHelpers.SC_ACTION() - { - Delay = actions[i].Delay, - Type = actions[i].Type, - }; - Marshal.StructureToPtr(action, actionPtr, false); - - // Need to make sure the SeShutdownPrivilege is enabled when adding a reboot failure action. - if (action.Type == FailureAction.Reboot) - privileges.Add("SeShutdownPrivilege"); - } - - using (new PrivilegeEnabler(true, privileges.ToList().ToArray())) - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS, info); - } - } - } - - public bool FailureActionsOnNonCrashFailures - { - get - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_FAILURE_ACTIONS_FLAG>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS_FLAG); - - return value.fFailureActionsOnNonCrashFailures; - } - set - { - var info = new NativeHelpers.SERVICE_FAILURE_ACTIONS_FLAG() - { - fFailureActionsOnNonCrashFailures = value, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, info); - } - } - - public ServiceSidInfo ServiceSidInfo - { - get - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_SID_INFO>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_SERVICE_SID_INFO); - - return value.dwServiceSidType; - } - set - { - var info = new NativeHelpers.SERVICE_SID_INFO() - { - dwServiceSidType = value, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_SERVICE_SID_INFO, info); - } - } - - public List<string> RequiredPrivileges - { - get - { - using (SafeMemoryBuffer buffer = QueryServiceConfig2( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO)) - { - var value = (NativeHelpers.SERVICE_REQUIRED_PRIVILEGES_INFOW)Marshal.PtrToStructure( - buffer.DangerousGetHandle(), typeof(NativeHelpers.SERVICE_REQUIRED_PRIVILEGES_INFOW)); - - int structLength = Marshal.SizeOf(value); - int stringLength = ((int)buffer.BufferLength - structLength) / sizeof(char); - - if (stringLength > 0) - { - string privilegesString = Marshal.PtrToStringUni(value.pmszRequiredPrivileges, stringLength); - return new List<string>(privilegesString.Split(new char[1] { '\0' }, - StringSplitOptions.RemoveEmptyEntries)); - } - else - return new List<string>(); - } - } - set - { - string privilegeString = String.Join("\0", value ?? new List<string>()) + "\0\0"; - - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer(Marshal.StringToHGlobalUni(privilegeString))) - { - var info = new NativeHelpers.SERVICE_REQUIRED_PRIVILEGES_INFOW() - { - pmszRequiredPrivileges = buffer.DangerousGetHandle(), - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, info); - } - } - } - - public UInt32 PreShutdownTimeout - { - get - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_PRESHUTDOWN_INFO>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_PRESHUTDOWN_INFO); - - return value.dwPreshutdownTimeout; - } - set - { - var info = new NativeHelpers.SERVICE_PRESHUTDOWN_INFO() - { - dwPreshutdownTimeout = value, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_PRESHUTDOWN_INFO, info); - } - } - - public List<Trigger> Triggers - { - get - { - List<Trigger> triggers = new List<Trigger>(); - - using (SafeMemoryBuffer b = QueryServiceConfig2( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_TRIGGER_INFO)) - { - var value = (NativeHelpers.SERVICE_TRIGGER_INFO)Marshal.PtrToStructure( - b.DangerousGetHandle(), typeof(NativeHelpers.SERVICE_TRIGGER_INFO)); - - int triggerLength = Marshal.SizeOf(typeof(NativeHelpers.SERVICE_TRIGGER)); - for (int i = 0; i < value.cTriggers; i++) - { - IntPtr triggerPtr = IntPtr.Add(value.pTriggers, i * triggerLength); - var trigger = (NativeHelpers.SERVICE_TRIGGER)Marshal.PtrToStructure(triggerPtr, - typeof(NativeHelpers.SERVICE_TRIGGER)); - - triggers.Add(new Trigger(trigger)); - } - } - - return triggers; - } - set - { - var info = new NativeHelpers.SERVICE_TRIGGER_INFO() - { - cTriggers = value == null ? 0 : (UInt32)value.Count, - pTriggers = IntPtr.Zero, - pReserved = IntPtr.Zero, - }; - - if (info.cTriggers == 0) - { - try - { - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_TRIGGER_INFO, info); - } - catch (ServiceManagerException e) - { - // Can fail with ERROR_INVALID_PARAMETER if no triggers were already set on the service, just - // continue as the service is what we want it to be. - if (e.NativeErrorCode != 87) - throw; - } - return; - } - - // Due to the dynamic nature of the trigger structure(s) we need to manually calculate the size of the - // data items on each trigger if present. This also serializes the raw data items to bytes here. - int structDataLength = 0; - int dataLength = 0; - Queue<byte[]> dataItems = new Queue<byte[]>(); - foreach (Trigger trigger in value) - { - if (trigger.DataItems == null || trigger.DataItems.Count == 0) - continue; - - foreach (TriggerItem dataItem in trigger.DataItems) - { - structDataLength += Marshal.SizeOf(typeof(NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM)); - - byte[] dataItemBytes; - Type dataItemType = dataItem.Data.GetType(); - if (dataItemType == typeof(byte)) - dataItemBytes = new byte[1] { (byte)dataItem.Data }; - else if (dataItemType == typeof(byte[])) - dataItemBytes = (byte[])dataItem.Data; - else if (dataItemType == typeof(UInt64)) - dataItemBytes = BitConverter.GetBytes((UInt64)dataItem.Data); - else if (dataItemType == typeof(string)) - dataItemBytes = Encoding.Unicode.GetBytes((string)dataItem.Data + "\0"); - else if (dataItemType == typeof(List<string>)) - dataItemBytes = Encoding.Unicode.GetBytes( - String.Join("\0", (List<string>)dataItem.Data) + "\0"); - else - throw new ArgumentException(String.Format("Trigger data type '{0}' not a value type", - dataItemType.Name)); - - dataLength += dataItemBytes.Length; - dataItems.Enqueue(dataItemBytes); - } - } - - using (SafeMemoryBuffer triggerBuffer = new SafeMemoryBuffer( - value.Count * Marshal.SizeOf(typeof(NativeHelpers.SERVICE_TRIGGER)))) - using (SafeMemoryBuffer triggerGuidBuffer = new SafeMemoryBuffer( - value.Count * Marshal.SizeOf(typeof(Guid)))) - using (SafeMemoryBuffer dataItemBuffer = new SafeMemoryBuffer(structDataLength)) - using (SafeMemoryBuffer dataBuffer = new SafeMemoryBuffer(dataLength)) - { - info.pTriggers = triggerBuffer.DangerousGetHandle(); - - IntPtr triggerPtr = triggerBuffer.DangerousGetHandle(); - IntPtr guidPtr = triggerGuidBuffer.DangerousGetHandle(); - IntPtr dataItemPtr = dataItemBuffer.DangerousGetHandle(); - IntPtr dataPtr = dataBuffer.DangerousGetHandle(); - - foreach (Trigger trigger in value) - { - int dataCount = trigger.DataItems == null ? 0 : trigger.DataItems.Count; - var rawTrigger = new NativeHelpers.SERVICE_TRIGGER() - { - dwTriggerType = trigger.Type, - dwAction = trigger.Action, - pTriggerSubtype = guidPtr, - cDataItems = (UInt32)dataCount, - pDataItems = dataCount == 0 ? IntPtr.Zero : dataItemPtr, - }; - guidPtr = StructureToPtr(trigger.SubType, guidPtr); - - for (int i = 0; i < rawTrigger.cDataItems; i++) - { - byte[] dataItemBytes = dataItems.Dequeue(); - var rawTriggerData = new NativeHelpers.SERVICE_TRIGGER_SPECIFIC_DATA_ITEM() - { - dwDataType = trigger.DataItems[i].Type, - cbData = (UInt32)dataItemBytes.Length, - pData = dataPtr, - }; - Marshal.Copy(dataItemBytes, 0, dataPtr, dataItemBytes.Length); - dataPtr = IntPtr.Add(dataPtr, dataItemBytes.Length); - - dataItemPtr = StructureToPtr(rawTriggerData, dataItemPtr); - } - - triggerPtr = StructureToPtr(rawTrigger, triggerPtr); - } - - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_TRIGGER_INFO, info); - } - } - } - - public UInt16? PreferredNode - { - get - { - try - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_PREFERRED_NODE_INFO>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_PREFERRED_NODE); - - return value.usPreferredNode; - } - catch (ServiceManagerException e) - { - // If host has no NUMA support this will fail with ERROR_INVALID_PARAMETER - if (e.NativeErrorCode == 0x00000057) // ERROR_INVALID_PARAMETER - return null; - - throw; - } - } - set - { - var info = new NativeHelpers.SERVICE_PREFERRED_NODE_INFO(); - if (value == null) - info.fDelete = true; - else - info.usPreferredNode = (UInt16)value; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_PREFERRED_NODE, info); - } - } - - public LaunchProtection LaunchProtection - { - get - { - var value = QueryServiceConfig2<NativeHelpers.SERVICE_LAUNCH_PROTECTED_INFO>( - NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_LAUNCH_PROTECTED); - - return value.dwLaunchProtected; - } - set - { - var info = new NativeHelpers.SERVICE_LAUNCH_PROTECTED_INFO() - { - dwLaunchProtected = value, - }; - ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel.SERVICE_CONFIG_LAUNCH_PROTECTED, info); - } - } - - // ServiceStatus - public ServiceStatus State { get { return _statusProcess.dwCurrentState; } } - - public ControlsAccepted ControlsAccepted { get { return _statusProcess.dwControlsAccepted; } } - - public UInt32 Win32ExitCode { get { return _statusProcess.dwWin32ExitCode; } } - - public UInt32 ServiceExitCode { get { return _statusProcess.dwServiceSpecificExitCode; } } - - public UInt32 Checkpoint { get { return _statusProcess.dwCheckPoint; } } - - public UInt32 WaitHint { get { return _statusProcess.dwWaitHint; } } - - public UInt32 ProcessId { get { return _statusProcess.dwProcessId; } } - - public ServiceFlags ServiceFlags { get { return _statusProcess.dwServiceFlags; } } - - public Service(string name) : this(name, ServiceRights.AllAccess) { } - - public Service(string name, ServiceRights access) : this(name, access, SCMRights.Connect) { } - - public Service(string name, ServiceRights access, SCMRights scmAccess) - { - ServiceName = name; - _scmHandle = OpenSCManager(scmAccess); - _serviceHandle = NativeMethods.OpenServiceW(_scmHandle, name, access); - if (_serviceHandle.IsInvalid) - throw new ServiceManagerException(String.Format("Failed to open service '{0}'", name)); - - Refresh(); - } - - private Service(SafeServiceHandle scmHandle, SafeServiceHandle serviceHandle, string name) - { - ServiceName = name; - _scmHandle = scmHandle; - _serviceHandle = serviceHandle; - - Refresh(); - } - - // EnumDependentServices - public List<string> DependedBy - { - get - { - UInt32 bytesNeeded = 0; - UInt32 numServices = 0; - NativeMethods.EnumDependentServicesW(_serviceHandle, 3, new SafeMemoryBuffer(IntPtr.Zero), 0, - out bytesNeeded, out numServices); - - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer((int)bytesNeeded)) - { - if (!NativeMethods.EnumDependentServicesW(_serviceHandle, 3, buffer, bytesNeeded, out bytesNeeded, - out numServices)) - { - throw new ServiceManagerException("Failed to enumerated dependent services"); - } - - List<string> dependents = new List<string>(); - Type enumType = typeof(NativeHelpers.ENUM_SERVICE_STATUSW); - for (int i = 0; i < numServices; i++) - { - var service = (NativeHelpers.ENUM_SERVICE_STATUSW)Marshal.PtrToStructure( - IntPtr.Add(buffer.DangerousGetHandle(), i * Marshal.SizeOf(enumType)), enumType); - - dependents.Add(service.lpServiceName); - } - - return dependents; - } - } - } - - public static Service Create(string name, string binaryPath, string displayName = null, - ServiceType serviceType = ServiceType.Win32OwnProcess, - ServiceStartType startType = ServiceStartType.DemandStart, ErrorControl errorControl = ErrorControl.Normal, - string loadOrderGroup = null, List<string> dependencies = null, string startName = null, - string password = null) - { - SafeServiceHandle scmHandle = OpenSCManager(SCMRights.CreateService | SCMRights.Connect); - - if (displayName == null) - displayName = name; - - string depString = null; - if (dependencies != null && dependencies.Count > 0) - depString = String.Join("\0", dependencies) + "\0\0"; - - SafeServiceHandle serviceHandle = NativeMethods.CreateServiceW(scmHandle, name, displayName, - ServiceRights.AllAccess, serviceType, startType, errorControl, binaryPath, - loadOrderGroup, IntPtr.Zero, depString, startName, password); - - if (serviceHandle.IsInvalid) - throw new ServiceManagerException(String.Format("Failed to create new service '{0}'", name)); - - return new Service(scmHandle, serviceHandle, name); - } - - public void Delete() - { - if (!NativeMethods.DeleteService(_serviceHandle)) - throw new ServiceManagerException("Failed to delete service"); - Dispose(); - } - - public void Dispose() - { - if (_serviceHandle != null) - _serviceHandle.Dispose(); - - if (_scmHandle != null) - _scmHandle.Dispose(); - GC.SuppressFinalize(this); - } - - public void Refresh() - { - UInt32 bytesNeeded; - NativeMethods.QueryServiceConfigW(_serviceHandle, IntPtr.Zero, 0, out bytesNeeded); - - _rawServiceConfig = new SafeMemoryBuffer((int)bytesNeeded); - if (!NativeMethods.QueryServiceConfigW(_serviceHandle, _rawServiceConfig.DangerousGetHandle(), bytesNeeded, - out bytesNeeded)) - { - throw new ServiceManagerException("Failed to query service config"); - } - - NativeMethods.QueryServiceStatusEx(_serviceHandle, 0, IntPtr.Zero, 0, out bytesNeeded); - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer((int)bytesNeeded)) - { - if (!NativeMethods.QueryServiceStatusEx(_serviceHandle, 0, buffer.DangerousGetHandle(), bytesNeeded, - out bytesNeeded)) - { - throw new ServiceManagerException("Failed to query service status"); - } - - _statusProcess = (NativeHelpers.SERVICE_STATUS_PROCESS)Marshal.PtrToStructure( - buffer.DangerousGetHandle(), typeof(NativeHelpers.SERVICE_STATUS_PROCESS)); - } - } - - private void ChangeServiceConfig(ServiceType serviceType = (ServiceType)SERVICE_NO_CHANGE, - ServiceStartType startType = (ServiceStartType)SERVICE_NO_CHANGE, - ErrorControl errorControl = (ErrorControl)SERVICE_NO_CHANGE, string binaryPath = null, - string loadOrderGroup = null, List<string> dependencies = null, string startName = null, - string password = null, string displayName = null) - { - string depString = null; - if (dependencies != null && dependencies.Count > 0) - depString = String.Join("\0", dependencies) + "\0\0"; - - if (!NativeMethods.ChangeServiceConfigW(_serviceHandle, serviceType, startType, errorControl, binaryPath, - loadOrderGroup, IntPtr.Zero, depString, startName, password, displayName)) - { - throw new ServiceManagerException("Failed to change service config"); - } - - Refresh(); - } - - private void ChangeServiceConfig2(NativeHelpers.ConfigInfoLevel infoLevel, object info) - { - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer(Marshal.SizeOf(info))) - { - Marshal.StructureToPtr(info, buffer.DangerousGetHandle(), false); - - if (!NativeMethods.ChangeServiceConfig2W(_serviceHandle, infoLevel, buffer.DangerousGetHandle())) - throw new ServiceManagerException("Failed to change service config"); - } - } - - private static SafeServiceHandle OpenSCManager(SCMRights desiredAccess) - { - SafeServiceHandle handle = NativeMethods.OpenSCManagerW(null, null, desiredAccess); - if (handle.IsInvalid) - throw new ServiceManagerException("Failed to open SCManager"); - - return handle; - } - - private T QueryServiceConfig2<T>(NativeHelpers.ConfigInfoLevel infoLevel) - { - using (SafeMemoryBuffer buffer = QueryServiceConfig2(infoLevel)) - return (T)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(T)); - } - - private SafeMemoryBuffer QueryServiceConfig2(NativeHelpers.ConfigInfoLevel infoLevel) - { - UInt32 bytesNeeded = 0; - NativeMethods.QueryServiceConfig2W(_serviceHandle, infoLevel, IntPtr.Zero, 0, out bytesNeeded); - - SafeMemoryBuffer buffer = new SafeMemoryBuffer((int)bytesNeeded); - if (!NativeMethods.QueryServiceConfig2W(_serviceHandle, infoLevel, buffer.DangerousGetHandle(), bytesNeeded, - out bytesNeeded)) - { - throw new ServiceManagerException(String.Format("QueryServiceConfig2W({0}) failed", - infoLevel.ToString())); - } - - return buffer; - } - - private static IntPtr StructureToPtr(object structure, IntPtr ptr) - { - Marshal.StructureToPtr(structure, ptr, false); - return IntPtr.Add(ptr, Marshal.SizeOf(structure)); - } - - ~Service() { Dispose(); } - } -} diff --git a/lib/ansible/modules/windows/async_status.ps1 b/lib/ansible/modules/windows/async_status.ps1 deleted file mode 100644 index 1ce3ff40f3..0000000000 --- a/lib/ansible/modules/windows/async_status.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$results = @{changed=$false} - -$parsed_args = Parse-Args $args -$jid = Get-AnsibleParam $parsed_args "jid" -failifempty $true -resultobj $results -$mode = Get-AnsibleParam $parsed_args "mode" -Default "status" -ValidateSet "status","cleanup" - -# parsed in from the async_status action plugin -$async_dir = Get-AnsibleParam $parsed_args "_async_dir" -type "path" -failifempty $true - -$log_path = [System.IO.Path]::Combine($async_dir, $jid) - -If(-not $(Test-Path $log_path)) -{ - Fail-Json @{ansible_job_id=$jid; started=1; finished=1} "could not find job at '$async_dir'" -} - -If($mode -eq "cleanup") { - Remove-Item $log_path -Recurse - Exit-Json @{ansible_job_id=$jid; erased=$log_path} -} - -# NOT in cleanup mode, assume regular status mode -# no remote kill mode currently exists, but probably should -# consider log_path + ".pid" file and also unlink that above - -$data = $null -Try { - $data_raw = Get-Content $log_path - - # TODO: move this into module_utils/powershell.ps1? - $jss = New-Object System.Web.Script.Serialization.JavaScriptSerializer - $data = $jss.DeserializeObject($data_raw) -} -Catch { - If(-not $data_raw) { - # file not written yet? That means it is running - Exit-Json @{results_file=$log_path; ansible_job_id=$jid; started=1; finished=0} - } - Else { - Fail-Json @{ansible_job_id=$jid; results_file=$log_path; started=1; finished=1} "Could not parse job output: $data" - } -} - -If (-not $data.ContainsKey("started")) { - $data['finished'] = 1 - $data['ansible_job_id'] = $jid -} -ElseIf (-not $data.ContainsKey("finished")) { - $data['finished'] = 0 -} - -Exit-Json $data diff --git a/lib/ansible/modules/windows/setup.ps1 b/lib/ansible/modules/windows/setup.ps1 deleted file mode 100644 index 5064723986..0000000000 --- a/lib/ansible/modules/windows/setup.ps1 +++ /dev/null @@ -1,516 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Function Get-CustomFacts { - [cmdletBinding()] - param ( - [Parameter(mandatory=$false)] - $factpath = $null - ) - - if (Test-Path -Path $factpath) { - $FactsFiles = Get-ChildItem -Path $factpath | Where-Object -FilterScript {($PSItem.PSIsContainer -eq $false) -and ($PSItem.Extension -eq '.ps1')} - - foreach ($FactsFile in $FactsFiles) { - $out = & $($FactsFile.FullName) - $result.ansible_facts.Add("ansible_$(($FactsFile.Name).Split('.')[0])", $out) - } - } - else - { - Add-Warning $result "Non existing path was set for local facts - $factpath" - } -} - -Function Get-MachineSid { - # The Machine SID is stored in HKLM:\SECURITY\SAM\Domains\Account and is - # only accessible by the Local System account. This method get's the local - # admin account (ends with -500) and lops it off to get the machine sid. - - $machine_sid = $null - - try { - $admins_sid = "S-1-5-32-544" - $admin_group = ([Security.Principal.SecurityIdentifier]$admins_sid).Translate([Security.Principal.NTAccount]).Value - - Add-Type -AssemblyName System.DirectoryServices.AccountManagement - $principal_context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine) - $group_principal = New-Object -TypeName System.DirectoryServices.AccountManagement.GroupPrincipal($principal_context, $admin_group) - $searcher = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalSearcher($group_principal) - $groups = $searcher.FindOne() - - foreach ($user in $groups.Members) { - $user_sid = $user.Sid - if ($user_sid.Value.EndsWith("-500")) { - $machine_sid = $user_sid.AccountDomainSid.Value - break - } - } - } catch { - #can fail for any number of reasons, if it does just return the original null - Add-Warning -obj $result -message "Error during machine sid retrieval: $($_.Exception.Message)" - } - - return $machine_sid -} - -$cim_instances = @{} - -Function Get-LazyCimInstance([string]$instance_name, [string]$namespace="Root\CIMV2") { - if(-not $cim_instances.ContainsKey($instance_name)) { - $cim_instances[$instance_name] = $(Get-CimInstance -Namespace $namespace -ClassName $instance_name) - } - - return $cim_instances[$instance_name] -} - -$result = @{ - ansible_facts = @{ } - changed = $false -} - -$grouped_subsets = @{ - min=[System.Collections.Generic.List[string]]@('date_time','distribution','dns','env','local','platform','powershell_version','user') - network=[System.Collections.Generic.List[string]]@('all_ipv4_addresses','all_ipv6_addresses','interfaces','windows_domain', 'winrm') - hardware=[System.Collections.Generic.List[string]]@('bios','memory','processor','uptime','virtual') - external=[System.Collections.Generic.List[string]]@('facter') -} - -# build "all" set from everything mentioned in the group- this means every value must be in at least one subset to be considered legal -$all_set = [System.Collections.Generic.HashSet[string]]@() - -foreach($kv in $grouped_subsets.GetEnumerator()) { - [void] $all_set.UnionWith($kv.Value) -} - -# dynamically create an "all" subset now that we know what should be in it -$grouped_subsets['all'] = [System.Collections.Generic.List[string]]$all_set - -# start with all, build up gather and exclude subsets -$gather_subset = [System.Collections.Generic.HashSet[string]]$grouped_subsets.all -$explicit_subset = [System.Collections.Generic.HashSet[string]]@() -$exclude_subset = [System.Collections.Generic.HashSet[string]]@() - -$params = Parse-Args $args -supports_check_mode $true -$factpath = Get-AnsibleParam -obj $params -name "fact_path" -type "path" -$gather_subset_source = Get-AnsibleParam -obj $params -name "gather_subset" -type "list" -default "all" - -foreach($item in $gather_subset_source) { - if(([string]$item).StartsWith("!")) { - $item = ([string]$item).Substring(1) - if($item -eq "all") { - $all_minus_min = [System.Collections.Generic.HashSet[string]]@($all_set) - [void] $all_minus_min.ExceptWith($grouped_subsets.min) - [void] $exclude_subset.UnionWith($all_minus_min) - } - elseif($grouped_subsets.ContainsKey($item)) { - [void] $exclude_subset.UnionWith($grouped_subsets[$item]) - } - elseif($all_set.Contains($item)) { - [void] $exclude_subset.Add($item) - } - # NB: invalid exclude values are ignored, since that's what posix setup does - } - else { - if($grouped_subsets.ContainsKey($item)) { - [void] $explicit_subset.UnionWith($grouped_subsets[$item]) - } - elseif($all_set.Contains($item)) { - [void] $explicit_subset.Add($item) - } - else { - # NB: POSIX setup fails on invalid value; we warn, because we don't implement the same set as POSIX - # and we don't have platform-specific config for this... - Add-Warning $result "invalid value $item specified in gather_subset" - } - } -} - -[void] $gather_subset.ExceptWith($exclude_subset) -[void] $gather_subset.UnionWith($explicit_subset) - -$ansible_facts = @{ - gather_subset=@($gather_subset_source) - module_setup=$true -} - -$osversion = [Environment]::OSVersion - -if ($osversion.Version -lt [version]"6.2") { - # Server 2008, 2008 R2, and Windows 7 are not tested in CI and we want to let customers know about it before - # removing support altogether. - $version_string = "{0}.{1}" -f ($osversion.Version.Major, $osversion.Version.Minor) - $msg = "Windows version '$version_string' will no longer be supported or tested in the next Ansible release" - Add-DeprecationWarning -obj $result -message $msg -version "2.11" -} - -if($gather_subset.Contains('all_ipv4_addresses') -or $gather_subset.Contains('all_ipv6_addresses')) { - $netcfg = Get-LazyCimInstance Win32_NetworkAdapterConfiguration - - # TODO: split v4/v6 properly, return in separate keys - $ips = @() - Foreach ($ip in $netcfg.IPAddress) { - If ($ip) { - $ips += $ip - } - } - - $ansible_facts += @{ - ansible_ip_addresses = $ips - } -} - -if($gather_subset.Contains('bios')) { - $win32_bios = Get-LazyCimInstance Win32_Bios - $win32_cs = Get-LazyCimInstance Win32_ComputerSystem - $ansible_facts += @{ - ansible_bios_date = $win32_bios.ReleaseDate.ToString("MM/dd/yyyy") - ansible_bios_version = $win32_bios.SMBIOSBIOSVersion - ansible_product_name = $win32_cs.Model.Trim() - ansible_product_serial = $win32_bios.SerialNumber - # ansible_product_version = ([string] $win32_cs.SystemFamily) - } -} - -if($gather_subset.Contains('date_time')) { - $datetime = (Get-Date) - $datetime_utc = $datetime.ToUniversalTime() - $date = @{ - date = $datetime.ToString("yyyy-MM-dd") - day = $datetime.ToString("dd") - epoch = (Get-Date -UFormat "%s") - hour = $datetime.ToString("HH") - iso8601 = $datetime_utc.ToString("yyyy-MM-ddTHH:mm:ssZ") - iso8601_basic = $datetime.ToString("yyyyMMddTHHmmssffffff") - iso8601_basic_short = $datetime.ToString("yyyyMMddTHHmmss") - iso8601_micro = $datetime_utc.ToString("yyyy-MM-ddTHH:mm:ss.ffffffZ") - minute = $datetime.ToString("mm") - month = $datetime.ToString("MM") - second = $datetime.ToString("ss") - time = $datetime.ToString("HH:mm:ss") - tz = ([System.TimeZoneInfo]::Local.Id) - tz_offset = $datetime.ToString("zzzz") - # Ensure that the weekday is in English - weekday = $datetime.ToString("dddd", [System.Globalization.CultureInfo]::InvariantCulture) - weekday_number = (Get-Date -UFormat "%w") - weeknumber = (Get-Date -UFormat "%W") - year = $datetime.ToString("yyyy") - } - - $ansible_facts += @{ - ansible_date_time = $date - } -} - -if($gather_subset.Contains('distribution')) { - $win32_os = Get-LazyCimInstance Win32_OperatingSystem - $product_type = switch($win32_os.ProductType) { - 1 { "workstation" } - 2 { "domain_controller" } - 3 { "server" } - default { "unknown" } - } - - $installation_type = $null - $current_version_path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" - if (Test-Path -LiteralPath $current_version_path) { - $install_type_prop = Get-ItemProperty -LiteralPath $current_version_path -ErrorAction SilentlyContinue - $installation_type = [String]$install_type_prop.InstallationType - } - - $ansible_facts += @{ - ansible_distribution = $win32_os.Caption - ansible_distribution_version = $osversion.Version.ToString() - ansible_distribution_major_version = $osversion.Version.Major.ToString() - ansible_os_family = "Windows" - ansible_os_name = ($win32_os.Name.Split('|')[0]).Trim() - ansible_os_product_type = $product_type - ansible_os_installation_type = $installation_type - } -} - -if($gather_subset.Contains('env')) { - $env_vars = @{ } - foreach ($item in Get-ChildItem Env:) { - $name = $item | Select-Object -ExpandProperty Name - # Powershell ConvertTo-Json fails if string ends with \ - $value = ($item | Select-Object -ExpandProperty Value).TrimEnd("\") - $env_vars.Add($name, $value) - } - - $ansible_facts += @{ - ansible_env = $env_vars - } -} - -if($gather_subset.Contains('facter')) { - # See if Facter is on the System Path - Try { - Get-Command facter -ErrorAction Stop > $null - $facter_installed = $true - } Catch { - $facter_installed = $false - } - - # Get JSON from Facter, and parse it out. - if ($facter_installed) { - &facter -j | Tee-Object -Variable facter_output > $null - $facts = "$facter_output" | ConvertFrom-Json - ForEach($fact in $facts.PSObject.Properties) { - $fact_name = $fact.Name - $ansible_facts.Add("facter_$fact_name", $fact.Value) - } - } -} - -if($gather_subset.Contains('interfaces')) { - $netcfg = Get-LazyCimInstance Win32_NetworkAdapterConfiguration - $ActiveNetcfg = @() - $ActiveNetcfg += $netcfg | Where-Object {$_.ipaddress -ne $null} - - $namespaces = Get-LazyCimInstance __Namespace -namespace root - if ($namespaces | Where-Object { $_.Name -eq "StandardCimv" }) { - $net_adapters = Get-LazyCimInstance MSFT_NetAdapter -namespace Root\StandardCimv2 - $guid_key = "InterfaceGUID" - $name_key = "Name" - } else { - $net_adapters = Get-LazyCimInstance Win32_NetworkAdapter - $guid_key = "GUID" - $name_key = "NetConnectionID" - } - - $formattednetcfg = @() - foreach ($adapter in $ActiveNetcfg) - { - $thisadapter = @{ - default_gateway = $null - connection_name = $null - dns_domain = $adapter.dnsdomain - interface_index = $adapter.InterfaceIndex - interface_name = $adapter.description - macaddress = $adapter.macaddress - } - - if ($adapter.defaultIPGateway) - { - $thisadapter.default_gateway = $adapter.DefaultIPGateway[0].ToString() - } - $net_adapter = $net_adapters | Where-Object { $_.$guid_key -eq $adapter.SettingID } - if ($net_adapter) { - $thisadapter.connection_name = $net_adapter.$name_key - } - - $formattednetcfg += $thisadapter - } - - $ansible_facts += @{ - ansible_interfaces = $formattednetcfg - } -} - -if ($gather_subset.Contains("local") -and $null -ne $factpath) { - # Get any custom facts; results are updated in the - Get-CustomFacts -factpath $factpath -} - -if($gather_subset.Contains('memory')) { - $win32_cs = Get-LazyCimInstance Win32_ComputerSystem - $win32_os = Get-LazyCimInstance Win32_OperatingSystem - $ansible_facts += @{ - # Win32_PhysicalMemory is empty on some virtual platforms - ansible_memtotal_mb = ([math]::ceiling($win32_cs.TotalPhysicalMemory / 1024 / 1024)) - ansible_memfree_mb = ([math]::ceiling($win32_os.FreePhysicalMemory / 1024)) - ansible_swaptotal_mb = ([math]::round($win32_os.TotalSwapSpaceSize / 1024)) - ansible_pagefiletotal_mb = ([math]::round($win32_os.SizeStoredInPagingFiles / 1024)) - ansible_pagefilefree_mb = ([math]::round($win32_os.FreeSpaceInPagingFiles / 1024)) - } -} - - -if($gather_subset.Contains('platform')) { - $win32_cs = Get-LazyCimInstance Win32_ComputerSystem - $win32_os = Get-LazyCimInstance Win32_OperatingSystem - $domain_suffix = $win32_cs.Domain.Substring($win32_cs.Workgroup.length) - $fqdn = $win32_cs.DNSHostname - - if( $domain_suffix -ne "") - { - $fqdn = $win32_cs.DNSHostname + "." + $domain_suffix - } - - try { - $ansible_reboot_pending = Get-PendingRebootStatus - } catch { - # fails for non-admin users, set to null in this case - $ansible_reboot_pending = $null - } - - $ansible_facts += @{ - ansible_architecture = $win32_os.OSArchitecture - ansible_domain = $domain_suffix - ansible_fqdn = $fqdn - ansible_hostname = $win32_cs.DNSHostname - ansible_netbios_name = $win32_cs.Name - ansible_kernel = $osversion.Version.ToString() - ansible_nodename = $fqdn - ansible_machine_id = Get-MachineSid - ansible_owner_contact = ([string] $win32_cs.PrimaryOwnerContact) - ansible_owner_name = ([string] $win32_cs.PrimaryOwnerName) - # FUTURE: should this live in its own subset? - ansible_reboot_pending = $ansible_reboot_pending - ansible_system = $osversion.Platform.ToString() - ansible_system_description = ([string] $win32_os.Description) - ansible_system_vendor = $win32_cs.Manufacturer - } -} - -if($gather_subset.Contains('powershell_version')) { - $ansible_facts += @{ - ansible_powershell_version = ($PSVersionTable.PSVersion.Major) - } -} - -if($gather_subset.Contains('processor')) { - $win32_cs = Get-LazyCimInstance Win32_ComputerSystem - $win32_cpu = Get-LazyCimInstance Win32_Processor - if ($win32_cpu -is [array]) { - # multi-socket, pick first - $win32_cpu = $win32_cpu[0] - } - - $cpu_list = @( ) - for ($i=1; $i -le $win32_cs.NumberOfLogicalProcessors; $i++) { - $cpu_list += $win32_cpu.Manufacturer - $cpu_list += $win32_cpu.Name - } - - $ansible_facts += @{ - ansible_processor = $cpu_list - ansible_processor_cores = $win32_cpu.NumberOfCores - ansible_processor_count = $win32_cs.NumberOfProcessors - ansible_processor_threads_per_core = ($win32_cpu.NumberOfLogicalProcessors / $win32_cpu.NumberofCores) - ansible_processor_vcpus = $win32_cs.NumberOfLogicalProcessors - } -} - -if($gather_subset.Contains('uptime')) { - $win32_os = Get-LazyCimInstance Win32_OperatingSystem - $ansible_facts += @{ - ansible_lastboot = $win32_os.lastbootuptime.ToString("u") - ansible_uptime_seconds = $([System.Convert]::ToInt64($(Get-Date).Subtract($win32_os.lastbootuptime).TotalSeconds)) - } -} - -if($gather_subset.Contains('user')) { - $user = [Security.Principal.WindowsIdentity]::GetCurrent() - $ansible_facts += @{ - ansible_user_dir = $env:userprofile - # Win32_UserAccount.FullName is probably the right thing here, but it can be expensive to get on large domains - ansible_user_gecos = "" - ansible_user_id = $env:username - ansible_user_sid = $user.User.Value - } -} - -if($gather_subset.Contains('windows_domain')) { - $win32_cs = Get-LazyCimInstance Win32_ComputerSystem - $domain_roles = @{ - 0 = "Stand-alone workstation" - 1 = "Member workstation" - 2 = "Stand-alone server" - 3 = "Member server" - 4 = "Backup domain controller" - 5 = "Primary domain controller" - } - - $domain_role = $domain_roles.Get_Item([Int32]$win32_cs.DomainRole) - - $ansible_facts += @{ - ansible_windows_domain = $win32_cs.Domain - ansible_windows_domain_member = $win32_cs.PartOfDomain - ansible_windows_domain_role = $domain_role - } -} - -if($gather_subset.Contains('winrm')) { - - $winrm_https_listener_parent_paths = Get-ChildItem -Path WSMan:\localhost\Listener -Recurse -ErrorAction SilentlyContinue | ` - Where-Object {$_.PSChildName -eq "Transport" -and $_.Value -eq "HTTPS"} | Select-Object PSParentPath - if ($winrm_https_listener_parent_paths -isnot [array]) { - $winrm_https_listener_parent_paths = @($winrm_https_listener_parent_paths) - } - - $winrm_https_listener_paths = @() - foreach ($winrm_https_listener_parent_path in $winrm_https_listener_parent_paths) { - $winrm_https_listener_paths += $winrm_https_listener_parent_path.PSParentPath.Substring($winrm_https_listener_parent_path.PSParentPath.LastIndexOf("\")) - } - - $https_listeners = @() - foreach ($winrm_https_listener_path in $winrm_https_listener_paths) { - $https_listeners += Get-ChildItem -Path "WSMan:\localhost\Listener$winrm_https_listener_path" - } - - $winrm_cert_thumbprints = @() - foreach ($https_listener in $https_listeners) { - $winrm_cert_thumbprints += $https_listener | Where-Object {$_.Name -EQ "CertificateThumbprint" } | Select-Object Value - } - - $winrm_cert_expiry = @() - foreach ($winrm_cert_thumbprint in $winrm_cert_thumbprints) { - Try { - $winrm_cert_expiry += Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object Thumbprint -EQ $winrm_cert_thumbprint.Value.ToString().ToUpper() | Select-Object NotAfter - } Catch { - Add-Warning -obj $result -message "Error during certificate expiration retrieval: $($_.Exception.Message)" - } - } - - $winrm_cert_expirations = $winrm_cert_expiry | Sort-Object NotAfter - if ($winrm_cert_expirations) { - # this fact was renamed from ansible_winrm_certificate_expires due to collision with ansible_winrm_X connection var pattern - $ansible_facts.Add("ansible_win_rm_certificate_expires", $winrm_cert_expirations[0].NotAfter.ToString("yyyy-MM-dd HH:mm:ss")) - } -} - -if($gather_subset.Contains('virtual')) { - $machine_info = Get-LazyCimInstance Win32_ComputerSystem - - switch ($machine_info.model) { - "Virtual Machine" { - $machine_type="Hyper-V" - $machine_role="guest" - } - - "VMware Virtual Platform" { - $machine_type="VMware" - $machine_role="guest" - } - - "VirtualBox" { - $machine_type="VirtualBox" - $machine_role="guest" - } - - "HVM domU" { - $machine_type="Xen" - $machine_role="guest" - } - - default { - $machine_type="NA" - $machine_role="NA" - } - } - - $ansible_facts += @{ - ansible_virtualization_role = $machine_role - ansible_virtualization_type = $machine_type - } -} - -$result.ansible_facts += $ansible_facts - -Exit-Json $result diff --git a/lib/ansible/modules/windows/slurp.ps1 b/lib/ansible/modules/windows/slurp.ps1 deleted file mode 100644 index eb506c7c7f..0000000000 --- a/lib/ansible/modules/windows/slurp.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true; -$src = Get-AnsibleParam -obj $params -name "src" -type "path" -aliases "path" -failifempty $true; - -$result = @{ - changed = $false; -} - -If (Test-Path -LiteralPath $src -PathType Leaf) -{ - $bytes = [System.IO.File]::ReadAllBytes($src); - $result.content = [System.Convert]::ToBase64String($bytes); - $result.encoding = "base64"; - Exit-Json $result; -} -ElseIf (Test-Path -LiteralPath $src -PathType Container) -{ - Fail-Json $result "Path $src is a directory"; -} -Else -{ - Fail-Json $result "Path $src is not found"; -} diff --git a/lib/ansible/modules/windows/win_acl.ps1 b/lib/ansible/modules/windows/win_acl.ps1 deleted file mode 100644 index e3c3813038..0000000000 --- a/lib/ansible/modules/windows/win_acl.ps1 +++ /dev/null @@ -1,225 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Phil Schwartz <schwartzmx@gmail.com> -# Copyright: (c) 2015, Trond Hindenes -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.PrivilegeUtil -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -# win_acl module (File/Resources Permission Additions/Removal) - -#Functions -function Get-UserSID { - param( - [String]$AccountName - ) - - $userSID = $null - $searchAppPools = $false - - if ($AccountName.Split("\").Count -gt 1) { - if ($AccountName.Split("\")[0] -eq "IIS APPPOOL") { - $searchAppPools = $true - $AccountName = $AccountName.Split("\")[1] - } - } - - if ($searchAppPools) { - Import-Module -Name WebAdministration - $testIISPath = Test-Path -LiteralPath "IIS:" - if ($testIISPath) { - $appPoolObj = Get-ItemProperty -LiteralPath "IIS:\AppPools\$AccountName" - $userSID = $appPoolObj.applicationPoolSid - } - } - else { - $userSID = Convert-ToSID -account_name $AccountName - } - - return $userSID -} - -$params = Parse-Args $args - -Function SetPrivilegeTokens() { - # Set privilege tokens only if admin. - # Admins would have these privs or be able to set these privs in the UI Anyway - - $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator - $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() - $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) - - - if ($myWindowsPrincipal.IsInRole($adminRole)) { - # Need to adjust token privs when executing Set-ACL in certain cases. - # e.g. d:\testdir is owned by group in which current user is not a member and no perms are inherited from d:\ - # This also sets us up for setting the owner as a feature. - # See the following for details of each privilege - # https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx - $privileges = @( - "SeRestorePrivilege", # Grants all write access control to any file, regardless of ACL. - "SeBackupPrivilege", # Grants all read access control to any file, regardless of ACL. - "SeTakeOwnershipPrivilege" # Grants ability to take owernship of an object w/out being granted discretionary access - ) - foreach ($privilege in $privileges) { - $state = Get-AnsiblePrivilege -Name $privilege - if ($state -eq $false) { - Set-AnsiblePrivilege -Name $privilege -Value $true - } - } - } -} - - -$result = @{ - changed = $false -} - -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -failifempty $true -$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true -$rights = Get-AnsibleParam -obj $params -name "rights" -type "str" -failifempty $true - -$type = Get-AnsibleParam -obj $params -name "type" -type "str" -failifempty $true -validateset "allow","deny" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" - -$inherit = Get-AnsibleParam -obj $params -name "inherit" -type "str" -$propagation = Get-AnsibleParam -obj $params -name "propagation" -type "str" -default "None" -validateset "InheritOnly","None","NoPropagateInherit" - -# We mount the HKCR, HKU, and HKCC registry hives so PS can access them. -# Network paths have no qualifiers so we use -EA SilentlyContinue to ignore that -$path_qualifier = Split-Path -Path $path -Qualifier -ErrorAction SilentlyContinue -if ($path_qualifier -eq "HKCR:" -and (-not (Test-Path -LiteralPath HKCR:\))) { - New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null -} -if ($path_qualifier -eq "HKU:" -and (-not (Test-Path -LiteralPath HKU:\))) { - New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS > $null -} -if ($path_qualifier -eq "HKCC:" -and (-not (Test-Path -LiteralPath HKCC:\))) { - New-PSDrive -Name HKCC -PSProvider Registry -Root HKEY_CURRENT_CONFIG > $null -} - -If (-Not (Test-Path -LiteralPath $path)) { - Fail-Json -obj $result -message "$path file or directory does not exist on the host" -} - -# Test that the user/group is resolvable on the local machine -$sid = Get-UserSID -AccountName $user -if (!$sid) { - Fail-Json -obj $result -message "$user is not a valid user or group on the host machine or domain" -} - -If (Test-Path -LiteralPath $path -PathType Leaf) { - $inherit = "None" -} -ElseIf ($null -eq $inherit) { - $inherit = "ContainerInherit, ObjectInherit" -} - -# Bug in Set-Acl, Get-Acl where -LiteralPath only works for the Registry provider if the location is in that root -# qualifier. We also don't have a qualifier for a network path so only change if not null -if ($null -ne $path_qualifier) { - Push-Location -LiteralPath $path_qualifier -} - -Try { - SetPrivilegeTokens - $path_item = Get-Item -LiteralPath $path -Force - If ($path_item.PSProvider.Name -eq "Registry") { - $colRights = [System.Security.AccessControl.RegistryRights]$rights - } - Else { - $colRights = [System.Security.AccessControl.FileSystemRights]$rights - } - - $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]$inherit - $PropagationFlag = [System.Security.AccessControl.PropagationFlags]$propagation - - If ($type -eq "allow") { - $objType =[System.Security.AccessControl.AccessControlType]::Allow - } - Else { - $objType =[System.Security.AccessControl.AccessControlType]::Deny - } - - $objUser = New-Object System.Security.Principal.SecurityIdentifier($sid) - If ($path_item.PSProvider.Name -eq "Registry") { - $objACE = New-Object System.Security.AccessControl.RegistryAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType) - } - Else { - $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType) - } - $objACL = Get-ACL -LiteralPath $path - - # Check if the ACE exists already in the objects ACL list - $match = $false - - ForEach($rule in $objACL.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])){ - - If ($path_item.PSProvider.Name -eq "Registry") { - If (($rule.RegistryRights -eq $objACE.RegistryRights) -And ($rule.AccessControlType -eq $objACE.AccessControlType) -And ($rule.IdentityReference -eq $objACE.IdentityReference) -And ($rule.IsInherited -eq $objACE.IsInherited) -And ($rule.InheritanceFlags -eq $objACE.InheritanceFlags) -And ($rule.PropagationFlags -eq $objACE.PropagationFlags)) { - $match = $true - Break - } - } else { - If (($rule.FileSystemRights -eq $objACE.FileSystemRights) -And ($rule.AccessControlType -eq $objACE.AccessControlType) -And ($rule.IdentityReference -eq $objACE.IdentityReference) -And ($rule.IsInherited -eq $objACE.IsInherited) -And ($rule.InheritanceFlags -eq $objACE.InheritanceFlags) -And ($rule.PropagationFlags -eq $objACE.PropagationFlags)) { - $match = $true - Break - } - } - } - - If ($state -eq "present" -And $match -eq $false) { - Try { - $objACL.AddAccessRule($objACE) - If ($path_item.PSProvider.Name -eq "Registry") { - Set-ACL -LiteralPath $path -AclObject $objACL - } else { - (Get-Item -LiteralPath $path).SetAccessControl($objACL) - } - $result.changed = $true - } - Catch { - Fail-Json -obj $result -message "an exception occurred when adding the specified rule - $($_.Exception.Message)" - } - } - ElseIf ($state -eq "absent" -And $match -eq $true) { - Try { - $objACL.RemoveAccessRule($objACE) - If ($path_item.PSProvider.Name -eq "Registry") { - Set-ACL -LiteralPath $path -AclObject $objACL - } else { - (Get-Item -LiteralPath $path).SetAccessControl($objACL) - } - $result.changed = $true - } - Catch { - Fail-Json -obj $result -message "an exception occurred when removing the specified rule - $($_.Exception.Message)" - } - } - Else { - # A rule was attempting to be added but already exists - If ($match -eq $true) { - Exit-Json -obj $result -message "the specified rule already exists" - } - # A rule didn't exist that was trying to be removed - Else { - Exit-Json -obj $result -message "the specified rule does not exist" - } - } -} -Catch { - Fail-Json -obj $result -message "an error occurred when attempting to $state $rights permission(s) on $path for $user - $($_.Exception.Message)" -} -Finally { - # Make sure we revert the location stack to the original path just for cleanups sake - if ($null -ne $path_qualifier) { - Pop-Location - } -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_acl.py b/lib/ansible/modules/windows/win_acl.py deleted file mode 100644 index 14fbd82f3a..0000000000 --- a/lib/ansible/modules/windows/win_acl.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Phil Schwartz <schwartzmx@gmail.com> -# Copyright: (c) 2015, Trond Hindenes -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_acl -version_added: "2.0" -short_description: Set file/directory/registry permissions for a system user or group -description: -- Add or remove rights/permissions for a given user or group for the specified - file, folder, registry key or AppPool identifies. -options: - path: - description: - - The path to the file or directory. - type: str - required: yes - user: - description: - - User or Group to add specified rights to act on src file/folder or - registry key. - type: str - required: yes - state: - description: - - Specify whether to add C(present) or remove C(absent) the specified access rule. - type: str - choices: [ absent, present ] - default: present - type: - description: - - Specify whether to allow or deny the rights specified. - type: str - required: yes - choices: [ allow, deny ] - rights: - description: - - The rights/permissions that are to be allowed/denied for the specified - user or group for the item at C(path). - - If C(path) is a file or directory, rights can be any right under MSDN - FileSystemRights U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemrights.aspx). - - If C(path) is a registry key, rights can be any right under MSDN - RegistryRights U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.registryrights.aspx). - type: str - required: yes - inherit: - description: - - Inherit flags on the ACL rules. - - Can be specified as a comma separated list, e.g. C(ContainerInherit), - C(ObjectInherit). - - For more information on the choices see MSDN InheritanceFlags enumeration - at U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.inheritanceflags.aspx). - - Defaults to C(ContainerInherit, ObjectInherit) for Directories. - type: str - choices: [ ContainerInherit, ObjectInherit ] - propagation: - description: - - Propagation flag on the ACL rules. - - For more information on the choices see MSDN PropagationFlags enumeration - at U(https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.propagationflags.aspx). - type: str - choices: [ InheritOnly, None, NoPropagateInherit ] - default: "None" -notes: -- If adding ACL's for AppPool identities (available since 2.3), the Windows - Feature "Web-Scripting-Tools" must be enabled. -seealso: -- module: win_acl_inheritance -- module: win_file -- module: win_owner -- module: win_stat -author: -- Phil Schwartz (@schwartzmx) -- Trond Hindenes (@trondhindenes) -- Hans-Joachim Kliemeck (@h0nIg) -''' - -EXAMPLES = r''' -- name: Restrict write and execute access to User Fed-Phil - win_acl: - user: Fed-Phil - path: C:\Important\Executable.exe - type: deny - rights: ExecuteFile,Write - -- name: Add IIS_IUSRS allow rights - win_acl: - path: C:\inetpub\wwwroot\MySite - user: IIS_IUSRS - rights: FullControl - type: allow - state: present - inherit: ContainerInherit, ObjectInherit - propagation: 'None' - -- name: Set registry key right - win_acl: - path: HKCU:\Bovine\Key - user: BUILTIN\Users - rights: EnumerateSubKeys - type: allow - state: present - inherit: ContainerInherit, ObjectInherit - propagation: 'None' - -- name: Remove FullControl AccessRule for IIS_IUSRS - win_acl: - path: C:\inetpub\wwwroot\MySite - user: IIS_IUSRS - rights: FullControl - type: allow - state: absent - inherit: ContainerInherit, ObjectInherit - propagation: 'None' - -- name: Deny Intern - win_acl: - path: C:\Administrator\Documents - user: Intern - rights: Read,Write,Modify,FullControl,Delete - type: deny - state: present -''' diff --git a/lib/ansible/modules/windows/win_acl_inheritance.ps1 b/lib/ansible/modules/windows/win_acl_inheritance.ps1 deleted file mode 100644 index 13ea0a46fd..0000000000 --- a/lib/ansible/modules/windows/win_acl_inheritance.ps1 +++ /dev/null @@ -1,67 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false - -$result = @{ - changed = $false -} - -$path = Get-AnsibleParam -obj $params "path" -type "path" -failifempty $true -$state = Get-AnsibleParam -obj $params "state" -type "str" -default "absent" -validateSet "present","absent" -resultobj $result -$reorganize = Get-AnsibleParam -obj $params "reorganize" -type "bool" -default $false -resultobj $result - -If (-Not (Test-Path -LiteralPath $path)) { - Fail-Json $result "$path file or directory does not exist on the host" -} - -Try { - $objACL = Get-ACL -LiteralPath $path - # AreAccessRulesProtected - $false if inheritance is set ,$true if inheritance is not set - $inheritanceDisabled = $objACL.AreAccessRulesProtected - - If (($state -eq "present") -And $inheritanceDisabled) { - # second parameter is ignored if first=$False - $objACL.SetAccessRuleProtection($False, $False) - - If ($reorganize) { - # it wont work without intermediate save, state would be the same - Set-ACL -LiteralPath $path -AclObject $objACL -WhatIf:$check_mode - $result.changed = $true - $objACL = Get-ACL -LiteralPath $path - - # convert explicit ACE to inherited ACE - ForEach($inheritedRule in $objACL.Access) { - If (-not $inheritedRule.IsInherited) { - Continue - } - - ForEach($explicitRrule in $objACL.Access) { - If ($explicitRrule.IsInherited) { - Continue - } - - If (($inheritedRule.FileSystemRights -eq $explicitRrule.FileSystemRights) -And ($inheritedRule.AccessControlType -eq $explicitRrule.AccessControlType) -And ($inheritedRule.IdentityReference -eq $explicitRrule.IdentityReference) -And ($inheritedRule.InheritanceFlags -eq $explicitRrule.InheritanceFlags) -And ($inheritedRule.PropagationFlags -eq $explicitRrule.PropagationFlags)) { - $objACL.RemoveAccessRule($explicitRrule) - } - } - } - } - - Set-ACL -LiteralPath $path -AclObject $objACL -WhatIf:$check_mode - $result.changed = $true - } Elseif (($state -eq "absent") -And (-not $inheritanceDisabled)) { - $objACL.SetAccessRuleProtection($True, $reorganize) - Set-ACL -LiteralPath $path -AclObject $objACL -WhatIf:$check_mode - $result.changed = $true - } -} Catch { - Fail-Json $result "an error occurred when attempting to disable inheritance: $($_.Exception.Message)" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_acl_inheritance.py b/lib/ansible/modules/windows/win_acl_inheritance.py deleted file mode 100644 index c43a7ae399..0000000000 --- a/lib/ansible/modules/windows/win_acl_inheritance.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_acl_inheritance -version_added: "2.1" -short_description: Change ACL inheritance -description: - - Change ACL (Access Control List) inheritance and optionally copy inherited ACE's (Access Control Entry) to dedicated ACE's or vice versa. -options: - path: - description: - - Path to be used for changing inheritance - required: yes - type: path - state: - description: - - Specify whether to enable I(present) or disable I(absent) ACL inheritance. - type: str - choices: [ absent, present ] - default: absent - reorganize: - description: - - For P(state) = I(absent), indicates if the inherited ACE's should be copied from the parent directory. - This is necessary (in combination with removal) for a simple ACL instead of using multiple ACE deny entries. - - For P(state) = I(present), indicates if the inherited ACE's should be deduplicated compared to the parent directory. - This removes complexity of the ACL structure. - type: bool - default: no -seealso: -- module: win_acl -- module: win_file -- module: win_stat -author: -- Hans-Joachim Kliemeck (@h0nIg) -''' - -EXAMPLES = r''' -- name: Disable inherited ACE's - win_acl_inheritance: - path: C:\apache - state: absent - -- name: Disable and copy inherited ACE's - win_acl_inheritance: - path: C:\apache - state: absent - reorganize: yes - -- name: Enable and remove dedicated ACE's - win_acl_inheritance: - path: C:\apache - state: present - reorganize: yes -''' - -RETURN = r''' - -''' diff --git a/lib/ansible/modules/windows/win_certificate_store.ps1 b/lib/ansible/modules/windows/win_certificate_store.ps1 deleted file mode 100644 index db984130e7..0000000000 --- a/lib/ansible/modules/windows/win_certificate_store.ps1 +++ /dev/null @@ -1,260 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$store_name_values = ([System.Security.Cryptography.X509Certificates.StoreName]).GetEnumValues() | ForEach-Object { $_.ToString() } -$store_location_values = ([System.Security.Cryptography.X509Certificates.StoreLocation]).GetEnumValues() | ForEach-Object { $_.ToString() } - -$spec = @{ - options = @{ - state = @{ type = "str"; default = "present"; choices = "absent", "exported", "present" } - path = @{ type = "path" } - thumbprint = @{ type = "str" } - store_name = @{ type = "str"; default = "My"; choices = $store_name_values } - store_location = @{ type = "str"; default = "LocalMachine"; choices = $store_location_values } - password = @{ type = "str"; no_log = $true } - key_exportable = @{ type = "bool"; default = $true } - key_storage = @{ type = "str"; default = "default"; choices = "default", "machine", "user" } - file_type = @{ type = "str"; default = "der"; choices = "der", "pem", "pkcs12" } - } - required_if = @( - @("state", "absent", @("path", "thumbprint"), $true), - @("state", "exported", @("path", "thumbprint")), - @("state", "present", @("path")) - ) - supports_check_mode = $true -} -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -Function Get-CertFile($module, $path, $password, $key_exportable, $key_storage) { - # parses a certificate file and returns X509Certificate2Collection - if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { - $module.FailJson("File at '$path' either does not exist or is not a file") - } - - # must set at least the PersistKeySet flag so that the PrivateKey - # is stored in a permanent container and not deleted once the handle - # is gone. - $store_flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet - - $key_storage = $key_storage.substring(0,1).ToUpper() + $key_storage.substring(1).ToLower() - $store_flags = $store_flags -bor [Enum]::Parse([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags], "$($key_storage)KeySet") - if ($key_exportable) { - $store_flags = $store_flags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable - } - - # TODO: If I'm feeling adventurours, write code to parse PKCS#12 PEM encoded - # file as .NET does not have an easy way to import this - $certs = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2Collection - - try { - $certs.Import($path, $password, $store_flags) - } catch { - $module.FailJson("Failed to load cert from file: $($_.Exception.Message)", $_) - } - - return $certs -} - -Function New-CertFile($module, $cert, $path, $type, $password) { - $content_type = switch ($type) { - "pem" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert } - "der" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert } - "pkcs12" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12 } - } - if ($type -eq "pkcs12") { - $missing_key = $false - if ($null -eq $cert.PrivateKey) { - $missing_key = $true - } elseif ($cert.PrivateKey.CspKeyContainerInfo.Exportable -eq $false) { - $missing_key = $true - } - if ($missing_key) { - $module.FailJson("Cannot export cert with key as PKCS12 when the key is not marked as exportable or not accessible by the current user") - } - } - - if (Test-Path -LiteralPath $path) { - Remove-Item -LiteralPath $path -Force - $module.Result.changed = $true - } - try { - $cert_bytes = $cert.Export($content_type, $password) - } catch { - $module.FailJson("Failed to export certificate as bytes: $($_.Exception.Message)", $_) - } - - # Need to manually handle a PEM file - if ($type -eq "pem") { - $cert_content = "-----BEGIN CERTIFICATE-----`r`n" - $base64_string = [System.Convert]::ToBase64String($cert_bytes, [System.Base64FormattingOptions]::InsertLineBreaks) - $cert_content += $base64_string - $cert_content += "`r`n-----END CERTIFICATE-----" - $file_encoding = [System.Text.Encoding]::ASCII - $cert_bytes = $file_encoding.GetBytes($cert_content) - } elseif ($type -eq "pkcs12") { - $module.Result.key_exported = $false - if ($null -ne $cert.PrivateKey) { - $module.Result.key_exportable = $cert.PrivateKey.CspKeyContainerInfo.Exportable - } - } - - if (-not $module.CheckMode) { - try { - [System.IO.File]::WriteAllBytes($path, $cert_bytes) - } catch [System.ArgumentNullException] { - $module.FailJson("Failed to write cert to file, cert was null: $($_.Exception.Message)", $_) - } catch [System.IO.IOException] { - $module.FailJson("Failed to write cert to file due to IO Exception: $($_.Exception.Message)", $_) - } catch [System.UnauthorizedAccessException] { - $module.FailJson("Failed to write cert to file due to permissions: $($_.Exception.Message)", $_) - } catch { - $module.FailJson("Failed to write cert to file: $($_.Exception.Message)", $_) - } - } - $module.Result.changed = $true -} - -Function Get-CertFileType($path, $password) { - $certs = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2Collection - try { - $certs.Import($path, $password, 0) - } catch [System.Security.Cryptography.CryptographicException] { - # the file is a pkcs12 we just had the wrong password - return "pkcs12" - } catch { - return "unknown" - } - - $file_contents = Get-Content -LiteralPath $path -Raw - if ($file_contents.StartsWith("-----BEGIN CERTIFICATE-----")) { - return "pem" - } elseif ($file_contents.StartsWith("-----BEGIN PKCS7-----")) { - return "pkcs7-ascii" - } elseif ($certs.Count -gt 1) { - # multiple certs must be pkcs7 - return "pkcs7-binary" - } elseif ($certs[0].HasPrivateKey) { - return "pkcs12" - } elseif ($path.EndsWith(".pfx") -or $path.EndsWith(".p12")) { - # no way to differenciate a pfx with a der file so we must rely on the - # extension - return "pkcs12" - } else { - return "der" - } -} - -$state = $module.Params.state -$path = $module.Params.path -$thumbprint = $module.Params.thumbprint -$store_name = [System.Security.Cryptography.X509Certificates.StoreName]"$($module.Params.store_name)" -$store_location = [System.Security.Cryptography.X509Certificates.Storelocation]"$($module.Params.store_location)" -$password = $module.Params.password -$key_exportable = $module.Params.key_exportable -$key_storage = $module.Params.key_storage -$file_type = $module.Params.file_type - -$module.Result.thumbprints = @() - -$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location -try { - $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) -} catch [System.Security.Cryptography.CryptographicException] { - $module.FailJson("Unable to open the store as it is not readable: $($_.Exception.Message)", $_) -} catch [System.Security.SecurityException] { - $module.FailJson("Unable to open the store with the current permissions: $($_.Exception.Message)", $_) -} catch { - $module.FailJson("Unable to open the store: $($_.Exception.Message)", $_) -} -$store_certificates = $store.Certificates - -try { - if ($state -eq "absent") { - $cert_thumbprints = @() - - if ($null -ne $path) { - $certs = Get-CertFile -module $module -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage - foreach ($cert in $certs) { - $cert_thumbprints += $cert.Thumbprint - } - } elseif ($null -ne $thumbprint) { - $cert_thumbprints += $thumbprint - } - - foreach ($cert_thumbprint in $cert_thumbprints) { - $module.Result.thumbprints += $cert_thumbprint - $found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $cert_thumbprint, $false) - if ($found_certs.Count -gt 0) { - foreach ($found_cert in $found_certs) { - try { - if (-not $module.CheckMode) { - $store.Remove($found_cert) - } - } catch [System.Security.SecurityException] { - $module.FailJson("Unable to remove cert with thumbprint '$cert_thumbprint' with current permissions: $($_.Exception.Message)", $_) - } catch { - $module.FailJson("Unable to remove cert with thumbprint '$cert_thumbprint': $($_.Exception.Message)", $_) - } - $module.Result.changed = $true - } - } - } - } elseif ($state -eq "exported") { - # TODO: Add support for PKCS7 and exporting a cert chain - $module.Result.thumbprints += $thumbprint - $export = $true - if (Test-Path -LiteralPath $path -PathType Container) { - $module.FailJson("Cannot export cert to path '$path' as it is a directory") - } elseif (Test-Path -LiteralPath $path -PathType Leaf) { - $actual_cert_type = Get-CertFileType -path $path -password $password - if ($actual_cert_type -eq $file_type) { - try { - $certs = Get-CertFile -module $module -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage - } catch { - # failed to load the file so we set the thumbprint to something - # that will fail validation - $certs = @{Thumbprint = $null} - } - - if ($certs.Thumbprint -eq $thumbprint) { - $export = $false - } - } - } - - if ($export) { - $found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $thumbprint, $false) - if ($found_certs.Count -ne 1) { - $module.FailJson("Found $($found_certs.Count) certs when only expecting 1") - } - - New-CertFile -module $module -cert $found_certs -path $path -type $file_type -password $password - } - } else { - $certs = Get-CertFile -module $module -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage - foreach ($cert in $certs) { - $module.Result.thumbprints += $cert.Thumbprint - $found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $cert.Thumbprint, $false) - if ($found_certs.Count -eq 0) { - try { - if (-not $module.CheckMode) { - $store.Add($cert) - } - } catch [System.Security.Cryptography.CryptographicException] { - $module.FailJson("Unable to import certificate with thumbprint '$($cert.Thumbprint)' with the current permissions: $($_.Exception.Message)", $_) - } catch { - $module.FailJson("Unable to import certificate with thumbprint '$($cert.Thumbprint)': $($_.Exception.Message)", $_) - } - $module.Result.changed = $true - } - } - } -} finally { - $store.Close() -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_certificate_store.py b/lib/ansible/modules/windows/win_certificate_store.py deleted file mode 100644 index dc617e33fd..0000000000 --- a/lib/ansible/modules/windows/win_certificate_store.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_certificate_store -version_added: '2.5' -short_description: Manages the certificate store -description: -- Used to import/export and remove certificates and keys from the local - certificate store. -- This module is not used to create certificates and will only manage existing - certs as a file or in the store. -- It can be used to import PEM, DER, P7B, PKCS12 (PFX) certificates and export - PEM, DER and PKCS12 certificates. -options: - state: - description: - - If C(present), will ensure that the certificate at I(path) is imported - into the certificate store specified. - - If C(absent), will ensure that the certificate specified by I(thumbprint) - or the thumbprint of the cert at I(path) is removed from the store - specified. - - If C(exported), will ensure the file at I(path) is a certificate - specified by I(thumbprint). - - When exporting a certificate, if I(path) is a directory then the module - will fail, otherwise the file will be replaced if needed. - type: str - choices: [ absent, exported, present ] - default: present - path: - description: - - The path to a certificate file. - - This is required when I(state) is C(present) or C(exported). - - When I(state) is C(absent) and I(thumbprint) is not specified, the - thumbprint is derived from the certificate at this path. - type: path - thumbprint: - description: - - The thumbprint as a hex string to either export or remove. - - See the examples for how to specify the thumbprint. - type: str - store_name: - description: - - The store name to use when importing a certificate or searching for a - certificate. - - "C(AddressBook): The X.509 certificate store for other users" - - "C(AuthRoot): The X.509 certificate store for third-party certificate authorities (CAs)" - - "C(CertificateAuthority): The X.509 certificate store for intermediate certificate authorities (CAs)" - - "C(Disallowed): The X.509 certificate store for revoked certificates" - - "C(My): The X.509 certificate store for personal certificates" - - "C(Root): The X.509 certificate store for trusted root certificate authorities (CAs)" - - "C(TrustedPeople): The X.509 certificate store for directly trusted people and resources" - - "C(TrustedPublisher): The X.509 certificate store for directly trusted publishers" - type: str - choices: - - AddressBook - - AuthRoot - - CertificateAuthority - - Disallowed - - My - - Root - - TrustedPeople - - TrustedPublisher - default: My - store_location: - description: - - The store location to use when importing a certificate or searching for a - certificate. - choices: [ CurrentUser, LocalMachine ] - default: LocalMachine - password: - description: - - The password of the pkcs12 certificate key. - - This is used when reading a pkcs12 certificate file or the password to - set when C(state=exported) and C(file_type=pkcs12). - - If the pkcs12 file has no password set or no password should be set on - the exported file, do not set this option. - type: str - key_exportable: - description: - - Whether to allow the private key to be exported. - - If C(no), then this module and other process will only be able to export - the certificate and the private key cannot be exported. - - Used when C(state=present) only. - type: bool - default: yes - key_storage: - description: - - Specifies where Windows will store the private key when it is imported. - - When set to C(default), the default option as set by Windows is used, typically C(user). - - When set to C(machine), the key is stored in a path accessible by various - users. - - When set to C(user), the key is stored in a path only accessible by the - current user. - - Used when C(state=present) only and cannot be changed once imported. - - See U(https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags.aspx) - for more details. - type: str - choices: [ default, machine, user ] - default: default - file_type: - description: - - The file type to export the certificate as when C(state=exported). - - C(der) is a binary ASN.1 encoded file. - - C(pem) is a base64 encoded file of a der file in the OpenSSL form. - - C(pkcs12) (also known as pfx) is a binary container that contains both - the certificate and private key unlike the other options. - - When C(pkcs12) is set and the private key is not exportable or accessible - by the current user, it will throw an exception. - type: str - choices: [ der, pem, pkcs12 ] - default: der -notes: -- Some actions on PKCS12 certificates and keys may fail with the error - C(the specified network password is not correct), either use CredSSP or - Kerberos with credential delegation, or use C(become) to bypass these - restrictions. -- The certificates must be located on the Windows host to be set with I(path). -- When importing a certificate for usage in IIS, it is generally required - to use the C(machine) key_storage option, as both C(default) and C(user) - will make the private key unreadable to IIS APPPOOL identities and prevent - binding the certificate to the https endpoint. -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Import a certificate - win_certificate_store: - path: C:\Temp\cert.pem - state: present - -- name: Import pfx certificate that is password protected - win_certificate_store: - path: C:\Temp\cert.pfx - state: present - password: VeryStrongPasswordHere! - become: yes - become_method: runas - -- name: Import pfx certificate without password and set private key as un-exportable - win_certificate_store: - path: C:\Temp\cert.pfx - state: present - key_exportable: no - # usually you don't set this here but it is for illustrative purposes - vars: - ansible_winrm_transport: credssp - -- name: Remove a certificate based on file thumbprint - win_certificate_store: - path: C:\Temp\cert.pem - state: absent - -- name: Remove a certificate based on thumbprint - win_certificate_store: - thumbprint: BD7AF104CF1872BDB518D95C9534EA941665FD27 - state: absent - -- name: Remove certificate based on thumbprint is CurrentUser/TrustedPublishers store - win_certificate_store: - thumbprint: BD7AF104CF1872BDB518D95C9534EA941665FD27 - state: absent - store_location: CurrentUser - store_name: TrustedPublisher - -- name: Export certificate as der encoded file - win_certificate_store: - path: C:\Temp\cert.cer - state: exported - file_type: der - -- name: Export certificate and key as pfx encoded file - win_certificate_store: - path: C:\Temp\cert.pfx - state: exported - file_type: pkcs12 - password: AnotherStrongPass! - become: yes - become_method: runas - become_user: SYSTEM - -- name: Import certificate be used by IIS - win_certificate_store: - path: C:\Temp\cert.pfx - file_type: pkcs12 - password: StrongPassword! - store_location: LocalMachine - key_storage: machine - state: present -''' - -RETURN = r''' -thumbprints: - description: A list of certificate thumbprints that were touched by the - module. - returned: success - type: list - sample: ["BC05633694E675449136679A658281F17A191087"] -''' diff --git a/lib/ansible/modules/windows/win_command.ps1 b/lib/ansible/modules/windows/win_command.ps1 deleted file mode 100644 index e2a30650d2..0000000000 --- a/lib/ansible/modules/windows/win_command.ps1 +++ /dev/null @@ -1,78 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.FileUtil - -# TODO: add check mode support - -Set-StrictMode -Version 2 -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $false - -$raw_command_line = Get-AnsibleParam -obj $params -name "_raw_params" -type "str" -failifempty $true -$chdir = Get-AnsibleParam -obj $params -name "chdir" -type "path" -$creates = Get-AnsibleParam -obj $params -name "creates" -type "path" -$removes = Get-AnsibleParam -obj $params -name "removes" -type "path" -$stdin = Get-AnsibleParam -obj $params -name "stdin" -type "str" -$output_encoding_override = Get-AnsibleParam -obj $params -name "output_encoding_override" -type "str" - -$raw_command_line = $raw_command_line.Trim() - -$result = @{ - changed = $true - cmd = $raw_command_line -} - -if ($creates -and $(Test-AnsiblePath -Path $creates)) { - Exit-Json @{msg="skipped, since $creates exists";cmd=$raw_command_line;changed=$false;skipped=$true;rc=0} -} - -if ($removes -and -not $(Test-AnsiblePath -Path $removes)) { - Exit-Json @{msg="skipped, since $removes does not exist";cmd=$raw_command_line;changed=$false;skipped=$true;rc=0} -} - -$command_args = @{ - command = $raw_command_line -} -if ($chdir) { - $command_args['working_directory'] = $chdir -} -if ($stdin) { - $command_args['stdin'] = $stdin -} -if ($output_encoding_override) { - $command_args['output_encoding_override'] = $output_encoding_override -} - -$start_datetime = [DateTime]::UtcNow -try { - $command_result = Run-Command @command_args -} catch { - $result.changed = $false - try { - $result.rc = $_.Exception.NativeErrorCode - } catch { - $result.rc = 2 - } - Fail-Json -obj $result -message $_.Exception.Message -} - -$result.stdout = $command_result.stdout -$result.stderr = $command_result.stderr -$result.rc = $command_result.rc - -$end_datetime = [DateTime]::UtcNow -$result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff") - -If ($result.rc -ne 0) { - Fail-Json -obj $result -message "non-zero return code" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_command.py b/lib/ansible/modules/windows/win_command.py deleted file mode 100644 index 508419b28b..0000000000 --- a/lib/ansible/modules/windows/win_command.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_command -short_description: Executes a command on a remote Windows node -version_added: 2.2 -description: - - The C(win_command) module takes the command name followed by a list of space-delimited arguments. - - The given command will be executed on all selected nodes. It will not be - processed through the shell, so variables like C($env:HOME) and operations - like C("<"), C(">"), C("|"), and C(";") will not work (use the M(win_shell) - module if you need these features). - - For non-Windows targets, use the M(command) module instead. -options: - free_form: - description: - - The C(win_command) module takes a free form command to run. - - There is no parameter actually named 'free form'. See the examples! - type: str - required: yes - creates: - description: - - A path or path filter pattern; when the referenced path exists on the target host, the task will be skipped. - type: path - removes: - description: - - A path or path filter pattern; when the referenced path B(does not) exist on the target host, the task will be skipped. - type: path - chdir: - description: - - Set the specified path as the current working directory before executing a command. - type: path - stdin: - description: - - Set the stdin of the command directly to the specified value. - type: str - version_added: '2.5' - output_encoding_override: - description: - - This option overrides the encoding of stdout/stderr output. - - You can use this option when you need to run a command which ignore the console's codepage. - - You should only need to use this option in very rare circumstances. - - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). - See U(https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings). - type: str - version_added: '2.10' -notes: - - If you want to run a command through a shell (say you are using C(<), - C(>), C(|), etc), you actually want the M(win_shell) module instead. The - C(win_command) module is much more secure as it's not affected by the user's - environment. - - C(creates), C(removes), and C(chdir) can be specified after the command. For instance, if you only want to run a command if a certain file does not - exist, use this. -seealso: -- module: command -- module: psexec -- module: raw -- module: win_psexec -- module: win_shell -author: - - Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -- name: Save the result of 'whoami' in 'whoami_out' - win_command: whoami - register: whoami_out - -- name: Run command that only runs if folder exists and runs from a specific folder - win_command: wbadmin -backupTarget:C:\backup\ - args: - chdir: C:\somedir\ - creates: C:\backup\ - -- name: Run an executable and send data to the stdin for the executable - win_command: powershell.exe - - args: - stdin: Write-Host test -''' - -RETURN = r''' -msg: - description: changed - returned: always - type: bool - sample: true -start: - description: The command execution start time - returned: always - type: str - sample: '2016-02-25 09:18:26.429568' -end: - description: The command execution end time - returned: always - type: str - sample: '2016-02-25 09:18:26.755339' -delta: - description: The command execution delta time - returned: always - type: str - sample: '0:00:00.325771' -stdout: - description: The command standard output - returned: always - type: str - sample: 'Clustering node rabbit@slave1 with rabbit@master ...' -stderr: - description: The command standard error - returned: always - type: str - sample: 'ls: cannot access foo: No such file or directory' -cmd: - description: The command executed by the task - returned: always - type: str - sample: 'rabbitmqctl join_cluster rabbit@master' -rc: - description: The command return code (0 means success) - returned: always - type: int - sample: 0 -stdout_lines: - description: The command standard output split in lines - returned: always - type: list - sample: [u'Clustering node rabbit@slave1 with rabbit@master ...'] -''' diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1 deleted file mode 100644 index 6a26ee722d..0000000000 --- a/lib/ansible/modules/windows/win_copy.ps1 +++ /dev/null @@ -1,403 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) <figs@unity.demon.co.uk> -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.Backup - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - -# there are 4 modes to win_copy which are driven by the action plugins: -# explode: src is a zip file which needs to be extracted to dest, for use with multiple files -# query: win_copy action plugin wants to get the state of remote files to check whether it needs to send them -# remote: all copy action is happening remotely (remote_src=True) -# single: a single file has been copied, also used with template -$copy_mode = Get-AnsibleParam -obj $params -name "_copy_mode" -type "str" -default "single" -validateset "explode","query","remote","single" - -# used in explode, remote and single mode -$src = Get-AnsibleParam -obj $params -name "src" -type "path" -failifempty ($copy_mode -in @("explode","process","single")) -$dest = Get-AnsibleParam -obj $params -name "dest" -type "path" -failifempty $true -$backup = Get-AnsibleParam -obj $params -name "backup" -type "bool" -default $false - -# used in single mode -$original_basename = Get-AnsibleParam -obj $params -name "_original_basename" -type "str" - -# used in query and remote mode -$force = Get-AnsibleParam -obj $params -name "force" -type "bool" -default $true - -# used in query mode, contains the local files/directories/symlinks that are to be copied -$files = Get-AnsibleParam -obj $params -name "files" -type "list" -$directories = Get-AnsibleParam -obj $params -name "directories" -type "list" - -$result = @{ - changed = $false -} - -if ($diff_mode) { - $result.diff = @{} -} - -Function Copy-File($source, $dest) { - $diff = "" - $copy_file = $false - $source_checksum = $null - if ($force) { - $source_checksum = Get-FileChecksum -path $source - } - - if (Test-Path -LiteralPath $dest -PathType Container) { - Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': dest is already a folder" - } elseif (Test-Path -LiteralPath $dest -PathType Leaf) { - if ($force) { - $target_checksum = Get-FileChecksum -path $dest - if ($source_checksum -ne $target_checksum) { - $copy_file = $true - } - } - } else { - $copy_file = $true - } - - if ($copy_file) { - $file_dir = [System.IO.Path]::GetDirectoryName($dest) - # validate the parent dir is not a file and that it exists - if (Test-Path -LiteralPath $file_dir -PathType Leaf) { - Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': object at dest parent dir is not a folder" - } elseif (-not (Test-Path -LiteralPath $file_dir)) { - # directory doesn't exist, need to create - New-Item -Path $file_dir -ItemType Directory -WhatIf:$check_mode | Out-Null - $diff += "+$file_dir\`n" - } - - if ($backup) { - $result.backup_file = Backup-File -path $dest -WhatIf:$check_mode - } - - if (Test-Path -LiteralPath $dest -PathType Leaf) { - Remove-Item -LiteralPath $dest -Force -Recurse -WhatIf:$check_mode | Out-Null - $diff += "-$dest`n" - } - - if (-not $check_mode) { - # cannot run with -WhatIf:$check_mode as if the parent dir didn't - # exist and was created above would still not exist in check mode - Copy-Item -LiteralPath $source -Destination $dest -Force | Out-Null - } - $diff += "+$dest`n" - - $result.changed = $true - } - - # ugly but to save us from running the checksum twice, let's return it for - # the main code to add it to $result - return ,@{ diff = $diff; checksum = $source_checksum } -} - -Function Copy-Folder($source, $dest) { - $diff = "" - - if (-not (Test-Path -LiteralPath $dest -PathType Container)) { - $parent_dir = [System.IO.Path]::GetDirectoryName($dest) - if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { - Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': object at dest parent dir is not a folder" - } - if (Test-Path -LiteralPath $dest -PathType Leaf) { - Fail-Json -obj $result -message "cannot copy folder from '$source' to '$dest': dest is already a file" - } - - New-Item -Path $dest -ItemType Container -WhatIf:$check_mode | Out-Null - $diff += "+$dest\`n" - $result.changed = $true - } - - $child_items = Get-ChildItem -LiteralPath $source -Force - foreach ($child_item in $child_items) { - $dest_child_path = Join-Path -Path $dest -ChildPath $child_item.Name - if ($child_item.PSIsContainer) { - $diff += (Copy-Folder -source $child_item.Fullname -dest $dest_child_path) - } else { - $diff += (Copy-File -source $child_item.Fullname -dest $dest_child_path).diff - } - } - - return $diff -} - -Function Get-FileSize($path) { - $file = Get-Item -LiteralPath $path -Force - if ($file.PSIsContainer) { - $size = (Get-ChildItem -Literalpath $file.FullName -Recurse -Force | ` - Where-Object { $_.PSObject.Properties.Name -contains 'Length' } | ` - Measure-Object -Property Length -Sum).Sum - if ($null -eq $size) { - $size = 0 - } - } else { - $size = $file.Length - } - - $size -} - -Function Extract-Zip($src, $dest) { - $archive = [System.IO.Compression.ZipFile]::Open($src, [System.IO.Compression.ZipArchiveMode]::Read, [System.Text.Encoding]::UTF8) - foreach ($entry in $archive.Entries) { - $archive_name = $entry.FullName - - # FullName may be appended with / or \, determine if it is padded and remove it - $padding_length = $archive_name.Length % 4 - if ($padding_length -eq 0) { - $is_dir = $false - $base64_name = $archive_name - } elseif ($padding_length -eq 1) { - $is_dir = $true - if ($archive_name.EndsWith("/") -or $archive_name.EndsWith("`\")) { - $base64_name = $archive_name.Substring(0, $archive_name.Length - 1) - } else { - throw "invalid base64 archive name '$archive_name'" - } - } else { - throw "invalid base64 length '$archive_name'" - } - - # to handle unicode character, win_copy action plugin has encoded the filename - $decoded_archive_name = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64_name)) - # re-add the / to the entry full name if it was a directory - if ($is_dir) { - $decoded_archive_name = "$decoded_archive_name/" - } - $entry_target_path = [System.IO.Path]::Combine($dest, $decoded_archive_name) - $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - - if (-not (Test-Path -LiteralPath $entry_dir)) { - New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null - } - - if ($is_dir -eq $false) { - if (-not $check_mode) { - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $entry_target_path, $true) - } - } - } - $archive.Dispose() # release the handle of the zip file -} - -Function Extract-ZipLegacy($src, $dest) { - if (-not (Test-Path -LiteralPath $dest)) { - New-Item -Path $dest -ItemType Directory -WhatIf:$check_mode | Out-Null - } - $shell = New-Object -ComObject Shell.Application - $zip = $shell.NameSpace($src) - $dest_path = $shell.NameSpace($dest) - - foreach ($entry in $zip.Items()) { - $is_dir = $entry.IsFolder - $encoded_archive_entry = $entry.Name - # to handle unicode character, win_copy action plugin has encoded the filename - $decoded_archive_entry = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encoded_archive_entry)) - if ($is_dir) { - $decoded_archive_entry = "$decoded_archive_entry/" - } - - $entry_target_path = [System.IO.Path]::Combine($dest, $decoded_archive_entry) - $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - - if (-not (Test-Path -LiteralPath $entry_dir)) { - New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null - } - - if ($is_dir -eq $false -and (-not $check_mode)) { - # https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866.aspx - # From Folder.CopyHere documentation, 1044 means: - # - 1024: do not display a user interface if an error occurs - # - 16: respond with "yes to all" for any dialog box that is displayed - # - 4: do not display a progress dialog box - $dest_path.CopyHere($entry, 1044) - - # once file is extraced, we need to rename it with non base64 name - $combined_encoded_path = [System.IO.Path]::Combine($dest, $encoded_archive_entry) - Move-Item -LiteralPath $combined_encoded_path -Destination $entry_target_path -Force | Out-Null - } - } -} - -if ($copy_mode -eq "query") { - # we only return a list of files/directories that need to be copied over - # the source of the local file will be the key used - $changed_files = @() - $changed_directories = @() - $changed_symlinks = @() - - foreach ($file in $files) { - $filename = $file.dest - $local_checksum = $file.checksum - - $filepath = Join-Path -Path $dest -ChildPath $filename - if (Test-Path -LiteralPath $filepath -PathType Leaf) { - if ($force) { - $checksum = Get-FileChecksum -path $filepath - if ($checksum -ne $local_checksum) { - $changed_files += $file - } - } - } elseif (Test-Path -LiteralPath $filepath -PathType Container) { - Fail-Json -obj $result -message "cannot copy file to dest '$filepath': object at path is already a directory" - } else { - $changed_files += $file - } - } - - foreach ($directory in $directories) { - $dirname = $directory.dest - - $dirpath = Join-Path -Path $dest -ChildPath $dirname - $parent_dir = [System.IO.Path]::GetDirectoryName($dirpath) - if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { - Fail-Json -obj $result -message "cannot copy folder to dest '$dirpath': object at parent directory path is already a file" - } - if (Test-Path -LiteralPath $dirpath -PathType Leaf) { - Fail-Json -obj $result -message "cannot copy folder to dest '$dirpath': object at path is already a file" - } elseif (-not (Test-Path -LiteralPath $dirpath -PathType Container)) { - $changed_directories += $directory - } - } - - # TODO: Handle symlinks - - $result.files = $changed_files - $result.directories = $changed_directories - $result.symlinks = $changed_symlinks -} elseif ($copy_mode -eq "explode") { - # a single zip file containing the files and directories needs to be - # expanded this will always result in a change as the calculation is done - # on the win_copy action plugin and is only run if a change needs to occur - if (-not (Test-Path -LiteralPath $src -PathType Leaf)) { - Fail-Json -obj $result -message "Cannot expand src zip file: '$src' as it does not exist" - } - - # Detect if the PS zip assemblies are available or whether to use Shell - $use_legacy = $false - try { - Add-Type -AssemblyName System.IO.Compression.FileSystem | Out-Null - Add-Type -AssemblyName System.IO.Compression | Out-Null - } catch { - $use_legacy = $true - } - if ($use_legacy) { - Extract-ZipLegacy -src $src -dest $dest - } else { - Extract-Zip -src $src -dest $dest - } - - $result.changed = $true -} elseif ($copy_mode -eq "remote") { - # all copy actions are happening on the remote side (windows host), need - # too copy source and dest using PS code - $result.src = $src - $result.dest = $dest - - if (-not (Test-Path -LiteralPath $src)) { - Fail-Json -obj $result -message "Cannot copy src file: '$src' as it does not exist" - } - - if (Test-Path -LiteralPath $src -PathType Container) { - # we are copying a directory or the contents of a directory - $result.operation = 'folder_copy' - if ($src.EndsWith("/") -or $src.EndsWith("`\")) { - # copying the folder's contents to dest - $diff = "" - $child_files = Get-ChildItem -LiteralPath $src -Force - foreach ($child_file in $child_files) { - $dest_child_path = Join-Path -Path $dest -ChildPath $child_file.Name - if ($child_file.PSIsContainer) { - $diff += Copy-Folder -source $child_file.FullName -dest $dest_child_path - } else { - $diff += (Copy-File -source $child_file.FullName -dest $dest_child_path).diff - } - } - } else { - # copying the folder and it's contents to dest - $dest = Join-Path -Path $dest -ChildPath (Get-Item -LiteralPath $src -Force).Name - $result.dest = $dest - $diff = Copy-Folder -source $src -dest $dest - } - } else { - # we are just copying a single file to dest - $result.operation = 'file_copy' - - $source_basename = (Get-Item -LiteralPath $src -Force).Name - $result.original_basename = $source_basename - - if ($dest.EndsWith("/") -or $dest.EndsWith("`\")) { - $dest = Join-Path -Path $dest -ChildPath (Get-Item -LiteralPath $src -Force).Name - $result.dest = $dest - } else { - # check if the parent dir exists, this is only done if src is a - # file and dest if the path to a file (doesn't end with \ or /) - $parent_dir = Split-Path -LiteralPath $dest - if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { - Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { - Fail-Json -obj $result -message "Destination directory '$parent_dir' does not exist" - } - } - $copy_result = Copy-File -source $src -dest $dest - $diff = $copy_result.diff - $result.checksum = $copy_result.checksum - } - - # the file might not exist if running in check mode - if (-not $check_mode -or (Test-Path -LiteralPath $dest -PathType Leaf)) { - $result.size = Get-FileSize -path $dest - } else { - $result.size = $null - } - if ($diff_mode) { - $result.diff.prepared = $diff - } -} elseif ($copy_mode -eq "single") { - # a single file is located in src and we need to copy to dest, this will - # always result in a change as the calculation is done on the Ansible side - # before this is run. This should also never run in check mode - if (-not (Test-Path -LiteralPath $src -PathType Leaf)) { - Fail-Json -obj $result -message "Cannot copy src file: '$src' as it does not exist" - } - - # the dest parameter is a directory, we need to append original_basename - if ($dest.EndsWith("/") -or $dest.EndsWith("`\") -or (Test-Path -LiteralPath $dest -PathType Container)) { - $remote_dest = Join-Path -Path $dest -ChildPath $original_basename - $parent_dir = Split-Path -LiteralPath $remote_dest - - # when dest ends with /, we need to create the destination directories - if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { - Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { - New-Item -Path $parent_dir -ItemType Directory | Out-Null - } - } else { - $remote_dest = $dest - $parent_dir = Split-Path -LiteralPath $remote_dest - - # check if the dest parent dirs exist, need to fail if they don't - if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { - Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { - Fail-Json -obj $result -message "Destination directory '$parent_dir' does not exist" - } - } - - if ($backup) { - $result.backup_file = Backup-File -path $remote_dest -WhatIf:$check_mode - } - - Copy-Item -LiteralPath $src -Destination $remote_dest -Force | Out-Null - $result.changed = $true -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_copy.py b/lib/ansible/modules/windows/win_copy.py deleted file mode 100644 index a55f4c65b7..0000000000 --- a/lib/ansible/modules/windows/win_copy.py +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) <figs@unity.demon.co.uk> -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_copy -version_added: '1.9.2' -short_description: Copies files to remote locations on windows hosts -description: -- The C(win_copy) module copies a file on the local box to remote windows locations. -- For non-Windows targets, use the M(copy) module instead. -options: - content: - description: - - When used instead of C(src), sets the contents of a file directly to the - specified value. - - This is for simple values, for anything complex or with formatting please - switch to the M(template) module. - type: str - version_added: '2.3' - decrypt: - description: - - This option controls the autodecryption of source files using vault. - type: bool - default: yes - version_added: '2.5' - dest: - description: - - Remote absolute path where the file should be copied to. - - If C(src) is a directory, this must be a directory too. - - Use \ for path separators or \\ when in "double quotes". - - If C(dest) ends with \ then source or the contents of source will be - copied to the directory without renaming. - - If C(dest) is a nonexistent path, it will only be created if C(dest) ends - with "/" or "\", or C(src) is a directory. - - If C(src) and C(dest) are files and if the parent directory of C(dest) - doesn't exist, then the task will fail. - type: path - required: yes - backup: - description: - - Determine whether a backup should be created. - - When set to C(yes), create a backup file including the timestamp information - so you can get the original file back if you somehow clobbered it incorrectly. - - No backup is taken when C(remote_src=False) and multiple files are being - copied. - type: bool - default: no - version_added: '2.8' - force: - description: - - If set to C(yes), the file will only be transferred if the content - is different than destination. - - If set to C(no), the file will only be transferred if the - destination does not exist. - - If set to C(no), no checksuming of the content is performed which can - help improve performance on larger files. - type: bool - default: yes - version_added: '2.3' - local_follow: - description: - - This flag indicates that filesystem links in the source tree, if they - exist, should be followed. - type: bool - default: yes - version_added: '2.4' - remote_src: - description: - - If C(no), it will search for src at originating/master machine. - - If C(yes), it will go to the remote/target machine for the src. - type: bool - default: no - version_added: '2.3' - src: - description: - - Local path to a file to copy to the remote server; can be absolute or - relative. - - If path is a directory, it is copied (including the source folder name) - recursively to C(dest). - - If path is a directory and ends with "/", only the inside contents of - that directory are copied to the destination. Otherwise, if it does not - end with "/", the directory itself with all contents is copied. - - If path is a file and dest ends with "\", the file is copied to the - folder with the same filename. - - Required unless using C(content). - type: path -notes: -- Currently win_copy does not support copying symbolic links from both local to - remote and remote to remote. -- It is recommended that backslashes C(\) are used instead of C(/) when dealing - with remote paths. -- Because win_copy runs over WinRM, it is not a very efficient transfer - mechanism. If sending large files consider hosting them on a web service and - using M(win_get_url) instead. -seealso: -- module: assemble -- module: copy -- module: win_get_url -- module: win_robocopy -author: -- Jon Hawkesworth (@jhawkesworth) -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Copy a single file - win_copy: - src: /srv/myfiles/foo.conf - dest: C:\Temp\renamed-foo.conf - -- name: Copy a single file, but keep a backup - win_copy: - src: /srv/myfiles/foo.conf - dest: C:\Temp\renamed-foo.conf - backup: yes - -- name: Copy a single file keeping the filename - win_copy: - src: /src/myfiles/foo.conf - dest: C:\Temp\ - -- name: Copy folder to C:\Temp (results in C:\Temp\temp_files) - win_copy: - src: files/temp_files - dest: C:\Temp - -- name: Copy folder contents recursively - win_copy: - src: files/temp_files/ - dest: C:\Temp - -- name: Copy a single file where the source is on the remote host - win_copy: - src: C:\Temp\foo.txt - dest: C:\ansible\foo.txt - remote_src: yes - -- name: Copy a folder recursively where the source is on the remote host - win_copy: - src: C:\Temp - dest: C:\ansible - remote_src: yes - -- name: Set the contents of a file - win_copy: - content: abc123 - dest: C:\Temp\foo.txt - -- name: Copy a single file as another user - win_copy: - src: NuGet.config - dest: '%AppData%\NuGet\NuGet.config' - vars: - ansible_become_user: user - ansible_become_password: pass - # The tmp dir must be set when using win_copy as another user - # This ensures the become user will have permissions for the operation - # Make sure to specify a folder both the ansible_user and the become_user have access to (i.e not %TEMP% which is user specific and requires Admin) - ansible_remote_tmp: 'c:\tmp' -''' - -RETURN = r''' -backup_file: - description: Name of the backup file that was created. - returned: if backup=yes - type: str - sample: C:\Path\To\File.txt.11540.20150212-220915.bak -dest: - description: Destination file/path. - returned: changed - type: str - sample: C:\Temp\ -src: - description: Source file used for the copy on the target machine. - returned: changed - type: str - sample: /home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source -checksum: - description: SHA1 checksum of the file after running copy. - returned: success, src is a file - type: str - sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827 -size: - description: Size of the target, after execution. - returned: changed, src is a file - type: int - sample: 1220 -operation: - description: Whether a single file copy took place or a folder copy. - returned: success - type: str - sample: file_copy -original_basename: - description: Basename of the copied file. - returned: changed, src is a file - type: str - sample: foo.txt -''' diff --git a/lib/ansible/modules/windows/win_dns_client.ps1 b/lib/ansible/modules/windows/win_dns_client.ps1 deleted file mode 100644 index 47eeb26b62..0000000000 --- a/lib/ansible/modules/windows/win_dns_client.ps1 +++ /dev/null @@ -1,360 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Set-StrictMode -Version 2 - -$ErrorActionPreference = "Stop" -$ConfirmPreference = "None" - -Set-Variable -Visibility Public -Option ReadOnly,AllScope,Constant -Name "AddressFamilies" -Value @{ - [System.Net.Sockets.AddressFamily]::InterNetworkV6 = 'IPv6' - [System.Net.Sockets.AddressFamily]::InterNetwork = 'IPv4' -} - -$result = @{changed=$false} - -$params = Parse-Args -arguments $args -supports_check_mode $true -Set-Variable -Visibility Public -Option ReadOnly,AllScope,Constant -Name "log_path" -Value ( - Get-AnsibleParam $params "log_path" -) -$adapter_names = Get-AnsibleParam $params "adapter_names" -Default "*" -$dns_servers = Get-AnsibleParam $params "dns_servers" -aliases "ipv4_addresses","ip_addresses","addresses" -FailIfEmpty $result -$check_mode = Get-AnsibleParam $params "_ansible_check_mode" -Default $false - - -Function Write-DebugLog { - Param( - [string]$msg - ) - - $DebugPreference = "Continue" - $ErrorActionPreference = "Continue" - $date_str = Get-Date -Format u - $msg = "$date_str $msg" - - Write-Debug $msg - if($log_path) { - Add-Content $log_path $msg - } -} - -Function Get-OptionalProperty { - <# - .SYNOPSIS - Retreives a property that may not exist from an object that may be null. - Optionally returns a default value. - Optionally coalesces to a new type with -as. - May return null, but will not throw. - #> - [CmdletBinding()] - param( - [Parameter(ValueFromPipeline=$true)] - [Object] - $InputObject , - - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [String] - $Name , - - [Parameter()] - [AllowNull()] - [Object] - $Default , - - [Parameter()] - [System.Type] - $As - ) - - Process { - if ($null -eq $InputObject) { - return $null - } - - $value = if ($InputObject.PSObject.Properties.Name -contains $Name) { - $InputObject.$Name - } else { - $Default - } - - if ($As) { - return $value -as $As - } - - return $value - } -} - -Function Get-NetAdapterInfo { - [CmdletBinding()] - Param ( - [Parameter(ValueFromPipeline=$true)] - [String]$Name = "*" - ) - - Process { - if (Get-Command -Name Get-NetAdapter -ErrorAction SilentlyContinue) { - $adapter_info = Get-NetAdapter @PSBoundParameters | Select-Object -Property Name, InterfaceIndex - } else { - # Older hosts 2008/2008R2 don't have Get-NetAdapter, fallback to deprecated Win32_NetworkAdapter - $cim_params = @{ - ClassName = "Win32_NetworkAdapter" - Property = "InterfaceIndex", "NetConnectionID" - } - - if ($Name.Contains("*")) { - $cim_params.Filter = "NetConnectionID LIKE '$($Name.Replace("*", "%"))'" - } else { - $cim_params.Filter = "NetConnectionID = '$Name'" - } - - $adapter_info = Get-CimInstance @cim_params | Select-Object -Property @( - @{Name="Name"; Expression={$_.NetConnectionID}}, - @{Name="InterfaceIndex"; Expression={$_.InterfaceIndex}} - ) - } - - # Need to filter the adapter that are not IPEnabled, while we are at it, also get the DNS config. - $net_info = $adapter_info | ForEach-Object -Process { - $cim_params = @{ - ClassName = "Win32_NetworkAdapterConfiguration" - Filter = "InterfaceIndex = $($_.InterfaceIndex)" - Property = "DNSServerSearchOrder", "IPEnabled", "SettingID" - } - $adapter_config = Get-CimInstance @cim_params | - Select-Object -Property DNSServerSearchOrder, IPEnabled, @{ - Name = 'InterfaceGuid' - Expression = { $_.SettingID } - } - - if ($adapter_config.IPEnabled -eq $false) { - return - } - - $reg_info = $adapter_config | Get-RegistryNameServerInfo - - [PSCustomObject]@{ - Name = $_.Name - InterfaceIndex = $_.InterfaceIndex - InterfaceGuid = $adapter_config.InterfaceGuid - RegInfo = $reg_info - } - } - - if (@($net_info).Count -eq 0 -and -not $Name.Contains("*")) { - throw "Get-NetAdapterInfo: Failed to find network adapter(s) that are IP enabled with the name '$Name'" - } - - $net_info - } -} - -Function Get-RegistryNameServerInfo { - [CmdletBinding()] - Param ( - [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] - [System.Guid] - $InterfaceGuid - ) - - Begin { - $protoItems = @{ - [System.Net.Sockets.AddressFamily]::InterNetwork = @{ - Interface = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{{{0}}}' - StaticNameServer = 'NameServer' - DhcpNameServer = 'DhcpNameServer' - EnableDhcp = 'EnableDHCP' - } - - [System.Net.Sockets.AddressFamily]::InterNetworkV6 = @{ - Interface = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces\{{{0}}}' - StaticNameServer = 'NameServer' - DhcpNameServer = 'Dhcpv6DNSServers' - EnableDhcp = 'EnableDHCP' - } - } - } - - Process { - foreach ($addrFamily in $AddressFamilies.Keys) { - $items = $protoItems[$addrFamily] - $regPath = $items.Interface -f $InterfaceGuid - - if (($iface = Get-Item -LiteralPath $regPath -ErrorAction Ignore)) { - $iprop = $iface | Get-ItemProperty - $famInfo = @{ - AddressFamily = $addrFamily - UsingDhcp = Get-OptionalProperty -InputObject $iprop -Name $items.EnableDhcp -As bool - EffectiveNameServers = @() - DhcpAssignedNameServers = @() - NameServerBadFormat = $false - } - - if (($ns = Get-OptionalProperty -InputObject $iprop -Name $items.DhcpNameServer)) { - $famInfo.EffectiveNameServers = $famInfo.DhcpAssignedNameServers = $ns.Split(' ') - } - - if (($ns = Get-OptionalProperty -InputObject $iprop -Name $items.StaticNameServer)) { - $famInfo.EffectiveNameServers = $famInfo.StaticNameServers = $ns -split '[,;\ ]' - $famInfo.UsingDhcp = $false - $famInfo.NameServerBadFormat = $ns -match '[;\ ]' - } - - $famInfo - } - } - } -} - -# minimal impl of Set-DnsClientServerAddress for 2008/2008R2 -Function Set-DnsClientServerAddressLegacy { - Param( - [int]$InterfaceIndex, - [Array]$ServerAddresses=@(), - [switch]$ResetServerAddresses - ) - $cim_params = @{ - ClassName = "Win32_NetworkAdapterConfiguration" - Filter = "InterfaceIndex = $InterfaceIndex" - KeyOnly = $true - } - $adapter_config = Get-CimInstance @cim_params - - If($ResetServerAddresses) { - $arguments = @{} - } - Else { - $arguments = @{ DNSServerSearchOrder = [string[]]$ServerAddresses } - } - $res = Invoke-CimMethod -InputObject $adapter_config -MethodName SetDNSServerSearchOrder -Arguments $arguments - - If($res.ReturnValue -ne 0) { - throw "Set-DnsClientServerAddressLegacy: Error calling SetDNSServerSearchOrder, code $($res.ReturnValue))" - } -} - -If(-not $(Get-Command Set-DnsClientServerAddress -ErrorAction SilentlyContinue)) { - New-Alias Set-DnsClientServerAddress Set-DnsClientServerAddressLegacy -} - -Function Test-DnsClientMatch { - Param( - [PSCustomObject]$AdapterInfo, - [System.Net.IPAddress[]] $dns_servers - ) - Write-DebugLog ("Getting DNS config for adapter {0}" -f $AdapterInfo.Name) - - foreach ($proto in $AdapterInfo.RegInfo) { - $desired_dns = if ($dns_servers) { - $dns_servers | Where-Object -FilterScript {$_.AddressFamily -eq $proto.AddressFamily} - } - - $current_dns = [System.Net.IPAddress[]]($proto.EffectiveNameServers) - Write-DebugLog ("Current DNS settings for '{1}' Address Family: {0}" -f ([string[]]$current_dns -join ", "),$AddressFamilies[$proto.AddressFamily]) - - if ($proto.NameServerBadFormat) { - Write-DebugLog "Malicious DNS server format detected. Will set DNS desired state." - return $false - # See: https://www.welivesecurity.com/2016/06/02/crouching-tiger-hidden-dns/ - } - - if ($proto.UsingDhcp -and -not $desired_dns) { - Write-DebugLog "DHCP DNS Servers are in use and no DNS servers were requested (DHCP is desired)." - } else { - if ($desired_dns -and -not $current_dns) { - Write-DebugLog "There are currently no DNS servers in use, but they should be present." - return $false - } - - if ($current_dns -and -not $desired_dns) { - Write-DebugLog "There are currently DNS servers in use, but they should be absent." - return $false - } - - if ($null -ne $current_dns -and - $null -ne $desired_dns -and - (Compare-Object -ReferenceObject $current_dns -DifferenceObject $desired_dns -SyncWindow 0)) { - Write-DebugLog "Static DNS servers are not in the desired state (incorrect or in the wrong order)." - return $false - } - } - - Write-DebugLog ("Current DNS settings match ({0})." -f ([string[]]$desired_dns -join ", ")) - } - return $true -} - - -Function Assert-IPAddress { - Param([string] $address) - - $addrout = $null - - return [System.Net.IPAddress]::TryParse($address, [ref] $addrout) -} - -Function Set-DnsClientAddresses -{ - Param( - [PSCustomObject]$AdapterInfo, - [System.Net.IPAddress[]] $dns_servers - ) - - Write-DebugLog ("Setting DNS addresses for adapter {0} to ({1})" -f $AdapterInfo.Name, ([string[]]$dns_servers -join ", ")) - - If ($dns_servers) { - Set-DnsClientServerAddress -InterfaceIndex $AdapterInfo.InterfaceIndex -ServerAddresses $dns_servers - } Else { - Set-DnsClientServerAddress -InterfaceIndex $AdapterInfo.InterfaceIndex -ResetServerAddress - } -} - -if($dns_servers -is [string]) { - if($dns_servers.Length -gt 0) { - $dns_servers = @($dns_servers) - } else { - $dns_servers = @() - } -} -# Using object equals here, to check for exact match (without implicit type conversion) -if([System.Object]::Equals($adapter_names, "*")) { - $adapters = Get-NetAdapterInfo -} else { - $adapters = $adapter_names | Get-NetAdapterInfo -} - -Try { - - Write-DebugLog ("Validating IP addresses ({0})" -f ($dns_servers -join ", ")) - $invalid_addresses = @($dns_servers | Where-Object { -not (Assert-IPAddress $_) }) - if($invalid_addresses.Count -gt 0) { - throw "Invalid IP address(es): ({0})" -f ($invalid_addresses -join ", ") - } - - foreach($adapter_info in $adapters) { - Write-DebugLog ("Validating adapter name {0}" -f $adapter_info.Name) - - if(-not (Test-DnsClientMatch $adapter_info $dns_servers)) { - $result.changed = $true - if(-not $check_mode) { - Set-DnsClientAddresses $adapter_info $dns_servers - } else { - Write-DebugLog "Check mode, skipping" - } - } - } - - Exit-Json $result - -} -Catch { - $excep = $_ - - Write-DebugLog "Exception: $($excep | out-string)" - - Throw -} diff --git a/lib/ansible/modules/windows/win_dns_client.py b/lib/ansible/modules/windows/win_dns_client.py deleted file mode 100644 index 8c89cf70eb..0000000000 --- a/lib/ansible/modules/windows/win_dns_client.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_dns_client -version_added: "2.3" -short_description: Configures DNS lookup on Windows hosts -description: - - The C(win_dns_client) module configures the DNS client on Windows network adapters. -options: - adapter_names: - description: - - Adapter name or list of adapter names for which to manage DNS settings ('*' is supported as a wildcard value). - - The adapter name used is the connection caption in the Network Control Panel or the InterfaceAlias of C(Get-DnsClientServerAddress). - type: list - required: yes - dns_servers: - description: - - Single or ordered list of DNS servers (IPv4 and IPv6 addresses) to configure for lookup. - - An empty list will configure the adapter to use the DHCP-assigned values on connections where DHCP is enabled, - or disable DNS lookup on statically-configured connections. - - IPv6 DNS servers can only be set on Windows Server 2012 or newer, older hosts can only set IPv4 addresses. - - Before 2.10 use ipv4_addresses instead. - type: list - required: yes - aliases: [ "ipv4_addresses", "ip_addresses", "addresses" ] -notes: - - Before 2.10, when setting an empty list of DNS server addresses on an adapter with DHCP enabled, a change was always registered. - - In 2.10, DNS servers will always be reset if the format of nameservers in the registry is not comma delimited. - See U(https://www.welivesecurity.com/2016/06/02/crouching-tiger-hidden-dns/) -author: -- Matt Davis (@nitzmahone) -- Brian Scholer (@briantist) -''' - -EXAMPLES = r''' -- name: Set a single address on the adapter named Ethernet - win_dns_client: - adapter_names: Ethernet - dns_servers: 192.168.34.5 - -- name: Set multiple lookup addresses on all visible adapters (usually physical adapters that are in the Up state), with debug logging to a file - win_dns_client: - adapter_names: '*' - dns_servers: - - 192.168.34.5 - - 192.168.34.6 - log_path: C:\dns_log.txt - -- name: Set IPv6 DNS servers on the adapter named Ethernet - win_dns_client: - adapter_names: Ethernet - dns_servers: - - '2001:db8::2' - - '2001:db8::3' - -- name: Configure all adapters whose names begin with Ethernet to use DHCP-assigned DNS values - win_dns_client: - adapter_names: 'Ethernet*' - dns_servers: [] -''' - -RETURN = r''' -''' diff --git a/lib/ansible/modules/windows/win_domain.ps1 b/lib/ansible/modules/windows/win_domain.ps1 deleted file mode 100644 index a5ec083e0b..0000000000 --- a/lib/ansible/modules/windows/win_domain.ps1 +++ /dev/null @@ -1,160 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Set-StrictMode -Version 2 -$ErrorActionPreference = "Stop" - -# FUTURE: Consider action wrapper to manage reboots and credential changes - -Function Ensure-Prereqs { - $gwf = Get-WindowsFeature AD-Domain-Services - if ($gwf.InstallState -ne "Installed") { - $result.changed = $true - - # NOTE: AD-Domain-Services includes: RSAT-AD-AdminCenter, RSAT-AD-Powershell and RSAT-ADDS-Tools - $awf = Add-WindowsFeature AD-Domain-Services -WhatIf:$check_mode - $result.reboot_required = $awf.RestartNeeded - # FUTURE: Check if reboot necessary - - return $true - } - return $false -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false -$dns_domain_name = Get-AnsibleParam -obj $params -name "dns_domain_name" -failifempty $true -$domain_netbios_name = Get-AnsibleParam -obj $params -name "domain_netbios_name" -$safe_mode_admin_password = Get-AnsibleParam -obj $params -name "safe_mode_password" -failifempty $true -$database_path = Get-AnsibleParam -obj $params -name "database_path" -type "path" -$sysvol_path = Get-AnsibleParam -obj $params -name "sysvol_path" -type "path" -$log_path = Get-AnsibleParam -obj $params -name "log_path" -type "path" -$create_dns_delegation = Get-AnsibleParam -obj $params -name "create_dns_delegation" -type "bool" -$domain_mode = Get-AnsibleParam -obj $params -name "domain_mode" -type "str" -$forest_mode = Get-AnsibleParam -obj $params -name "forest_mode" -type "str" -$install_dns = Get-AnsibleParam -obj $params -name "install_dns" -type "bool" -default $true - -# FUTURE: Support down to Server 2012? -if ([System.Environment]::OSVersion.Version -lt [Version]"6.3.9600.0") { - Fail-Json -message "win_domain requires Windows Server 2012R2 or higher" -} - -# Check that domain_netbios_name is less than 15 characters -if ($domain_netbios_name -and $domain_netbios_name.length -gt 15) { - Fail-Json -message "The parameter 'domain_netbios_name' should not exceed 15 characters in length" -} - -$result = @{ - changed=$false; - reboot_required=$false; -} - -# FUTURE: Any sane way to do the detection under check-mode *without* installing the feature? -$installed = Ensure-Prereqs - -# when in check mode and the prereq was "installed" we need to exit early as -# the AD cmdlets weren't really installed -if ($check_mode -and $installed) { - Exit-Json -obj $result -} - -# Check that we got a valid domain_mode -$valid_domain_modes = [Enum]::GetNames((Get-Command -Name Install-ADDSForest).Parameters.DomainMode.ParameterType) -if (($null -ne $domain_mode) -and -not ($domain_mode -in $valid_domain_modes)) { - Fail-Json -obj $result -message "The parameter 'domain_mode' does not accept '$domain_mode', please use one of: $valid_domain_modes" -} - -# Check that we got a valid forest_mode -$valid_forest_modes = [Enum]::GetNames((Get-Command -Name Install-ADDSForest).Parameters.ForestMode.ParameterType) -if (($null -ne $forest_mode) -and -not ($forest_mode -in $valid_forest_modes)) { - Fail-Json -obj $result -message "The parameter 'forest_mode' does not accept '$forest_mode', please use one of: $valid_forest_modes" -} - -$forest = $null -try { - # Cannot use Get-ADForest as that requires credential delegation, the below does not - $forest_context = New-Object -TypeName System.DirectoryServices.ActiveDirectory.DirectoryContext -ArgumentList Forest, $dns_domain_name - $forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($forest_context) -} catch [System.DirectoryServices.ActiveDirectory.ActiveDirectoryObjectNotFoundException] { -} catch [System.DirectoryServices.ActiveDirectory.ActiveDirectoryOperationException] { } - -if (-not $forest) { - $result.changed = $true - - $sm_cred = ConvertTo-SecureString $safe_mode_admin_password -AsPlainText -Force - - $install_params = @{ - DomainName=$dns_domain_name; - SafeModeAdministratorPassword=$sm_cred; - Confirm=$false; - SkipPreChecks=$true; - InstallDns=$install_dns; - NoRebootOnCompletion=$true; - WhatIf=$check_mode; - } - - if ($database_path) { - $install_params.DatabasePath = $database_path - } - - if ($sysvol_path) { - $install_params.SysvolPath = $sysvol_path - } - - if ($log_path) { - $install_params.LogPath = $log_path - } - - if ($domain_netbios_name) { - $install_params.DomainNetBiosName = $domain_netbios_name - } - - if ($null -ne $create_dns_delegation) { - $install_params.CreateDnsDelegation = $create_dns_delegation - } - - if ($domain_mode) { - $install_params.DomainMode = $domain_mode - } - - if ($forest_mode) { - $install_params.ForestMode = $forest_mode - } - - $iaf = $null - try { - $iaf = Install-ADDSForest @install_params - } catch [Microsoft.DirectoryServices.Deployment.DCPromoExecutionException] { - # ExitCode 15 == 'Role change is in progress or this computer needs to be restarted.' - # DCPromo exit codes details can be found at https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/deploy/troubleshooting-domain-controller-deployment - if ($_.Exception.ExitCode -in @(15, 19)) { - $result.reboot_required = $true - } else { - Fail-Json -obj $result -message "Failed to install ADDSForest, DCPromo exited with $($_.Exception.ExitCode): $($_.Exception.Message)" - } - } - - if ($check_mode) { - # the return value after -WhatIf does not have RebootRequired populated - # manually set to True as the domain would have been installed - $result.reboot_required = $true - } elseif ($null -ne $iaf) { - $result.reboot_required = $iaf.RebootRequired - - # The Netlogon service is set to auto start but is not started. This is - # required for Ansible to connect back to the host and reboot in a - # later task. Even if this fails Ansible can still connect but only - # with ansible_winrm_transport=basic so we just display a warning if - # this fails. - try { - Start-Service -Name Netlogon - } catch { - Add-Warning -obj $result -message "Failed to start the Netlogon service after promoting the host, Ansible may be unable to connect until the host is manually rebooting: $($_.Exception.Message)" - } - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_domain.py b/lib/ansible/modules/windows/win_domain.py deleted file mode 100644 index e05f585cea..0000000000 --- a/lib/ansible/modules/windows/win_domain.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' -module: win_domain -short_description: Ensures the existence of a Windows domain -version_added: 2.3 -description: -- Ensure that the domain named by C(dns_domain_name) exists and is reachable. -- If the domain is not reachable, the domain is created in a new forest on the target Windows Server 2012R2+ host. -- This module may require subsequent use of the M(win_reboot) action if changes are made. -options: - dns_domain_name: - description: - - The DNS name of the domain which should exist and be reachable or reside on the target Windows host. - type: str - required: yes - domain_netbios_name: - description: - - The NetBIOS name for the root domain in the new forest. - - For NetBIOS names to be valid for use with this parameter they must be single label names of 15 characters or less, if not it will fail. - - If this parameter is not set, then the default is automatically computed from the value of the I(domain_name) parameter. - type: str - version_added: '2.6' - safe_mode_password: - description: - - Safe mode password for the domain controller. - type: str - required: yes - database_path: - description: - - The path to a directory on a fixed disk of the Windows host where the - domain database will be created. - - If not set then the default path is C(%SYSTEMROOT%\NTDS). - type: path - version_added: '2.5' - log_path: - description: - - Specifies the fully qualified, non-UNC path to a directory on a fixed disk of the local computer where the log file for this operation is written. - - If not set then the default path is C(%SYSTEMROOT%\NTDS). - type: path - version_added: '2.10' - sysvol_path: - description: - - The path to a directory on a fixed disk of the Windows host where the - Sysvol file will be created. - - If not set then the default path is C(%SYSTEMROOT%\SYSVOL). - type: path - version_added: '2.5' - create_dns_delegation: - description: - - Whether to create a DNS delegation that references the new DNS server that you install along with the domain controller. - - Valid for Active Directory-integrated DNS only. - - The default is computed automatically based on the environment. - type: bool - version_added: '2.8' - domain_mode: - description: - - Specifies the domain functional level of the first domain in the creation of a new forest. - - The domain functional level cannot be lower than the forest functional level, but it can be higher. - - The default is automatically computed and set. - type: str - choices: [ Win2003, Win2008, Win2008R2, Win2012, Win2012R2, WinThreshold ] - version_added: '2.8' - forest_mode: - description: - - Specifies the forest functional level for the new forest. - - The default forest functional level in Windows Server is typically the same as the version you are running. -# - Beware that the default forest functional level in Windows Server 2008 R2 when you create a new forest is C(Win2003). - type: str - choices: [ Win2003, Win2008, Win2008R2, Win2012, Win2012R2, WinThreshold ] - version_added: '2.8' - install_dns: - description: - - Whether to install the DNS service when creating the domain controller. - type: bool - default: yes - version_added: '2.10' -seealso: -- module: win_domain_controller -- module: win_domain_computer -- module: win_domain_group -- module: win_domain_membership -- module: win_domain_user -author: -- Matt Davis (@nitzmahone) -''' - -RETURN = r''' -reboot_required: - description: True if changes were made that require a reboot. - returned: always - type: bool - sample: true -''' - -EXAMPLES = r''' -- name: Create new domain in a new forest on the target host - win_domain: - dns_domain_name: ansible.vagrant - safe_mode_password: password123! - -- name: Create new Windows domain in a new forest with specific parameters - win_domain: - create_dns_delegation: no - database_path: C:\Windows\NTDS - dns_domain_name: ansible.vagrant - domain_mode: Win2012R2 - domain_netbios_name: ANSIBLE - forest_mode: Win2012R2 - safe_mode_password: password123! - sysvol_path: C:\Windows\SYSVOL - register: domain_install -''' diff --git a/lib/ansible/modules/windows/win_domain_controller.ps1 b/lib/ansible/modules/windows/win_domain_controller.ps1 deleted file mode 100644 index b96cbc60ba..0000000000 --- a/lib/ansible/modules/windows/win_domain_controller.ps1 +++ /dev/null @@ -1,299 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Set-StrictMode -Version 2 - -$ErrorActionPreference = "Stop" -$ConfirmPreference = "None" - -$log_path = $null - -Function Write-DebugLog { - Param( - [string]$msg - ) - - $DebugPreference = "Continue" - $ErrorActionPreference = "Continue" - $date_str = Get-Date -Format u - $msg = "$date_str $msg" - - Write-Debug $msg - if($log_path) { - Add-Content $log_path $msg - } -} - -$required_features = @("AD-Domain-Services","RSAT-ADDS") - -Function Get-MissingFeatures { - Write-DebugLog "Checking for missing Windows features..." - - $features = @(Get-WindowsFeature $required_features) - - If($features.Count -ne $required_features.Count) { - Throw "One or more Windows features required for a domain controller are unavailable" - } - - $missing_features = @($features | Where-Object InstallState -ne Installed) - - return ,$missing_features # no, the comma's not a typo- allows us to return an empty array -} - -Function Ensure-FeatureInstallation { - # ensure RSAT-ADDS and AD-Domain-Services features are installed - - Write-DebugLog "Ensuring required Windows features are installed..." - $feature_result = Install-WindowsFeature $required_features - $result.reboot_required = $feature_result.RestartNeeded - - If(-not $feature_result.Success) { - Exit-Json -message ("Error installing AD-Domain-Services and RSAT-ADDS features: {0}" -f ($feature_result | Out-String)) - } -} - -# return the domain we're a DC for, or null if not a DC -Function Get-DomainControllerDomain { - Write-DebugLog "Checking for domain controller role and domain name" - - $sys_cim = Get-CIMInstance Win32_ComputerSystem - - $is_dc = $sys_cim.DomainRole -in (4,5) # backup/primary DC - # this will be our workgroup or joined-domain if we're not a DC - $domain = $sys_cim.Domain - - Switch($is_dc) { - $true { return $domain } - Default { return $null } - } -} - -Function Create-Credential { - Param( - [string] $cred_user, - [string] $cred_password - ) - - $cred = New-Object System.Management.Automation.PSCredential($cred_user, $($cred_password | ConvertTo-SecureString -AsPlainText -Force)) - - Return $cred -} - -Function Get-OperationMasterRoles { - $assigned_roles = @((Get-ADDomainController -Server localhost).OperationMasterRoles) - - Return ,$assigned_roles # no, the comma's not a typo- allows us to return an empty array -} - -$result = @{ - changed = $false - reboot_required = $false -} - -$params = Parse-Args -arguments $args -supports_check_mode $true - -$dns_domain_name = Get-AnsibleParam -obj $params -name "dns_domain_name" -$safe_mode_password= Get-AnsibleParam -obj $params -name "safe_mode_password" -$domain_admin_user = Get-AnsibleParam -obj $params -name "domain_admin_user" -failifempty $result -$domain_admin_password= Get-AnsibleParam -obj $params -name "domain_admin_password" -failifempty $result -$local_admin_password= Get-AnsibleParam -obj $params -name "local_admin_password" -$database_path = Get-AnsibleParam -obj $params -name "database_path" -type "path" -$sysvol_path = Get-AnsibleParam -obj $params -name "sysvol_path" -type "path" -$domain_log_path = Get-AnsibleParam -obj $params -name "domain_log_path" -type "path" # TODO: Use log_path and alias domain_log_path once the log_path for debug logging option has been removed. -$read_only = Get-AnsibleParam -obj $params -name "read_only" -type "bool" -default $false -$site_name = Get-AnsibleParam -obj $params -name "site_name" -type "str" -failifempty $read_only -$install_dns = Get-AnsibleParam -obj $params -name "install_dns" -type "bool" - -$state = Get-AnsibleParam -obj $params -name "state" -validateset ("domain_controller", "member_server") -failifempty $result - -$log_path = Get-AnsibleParam -obj $params -name "log_path" -if ($log_path) { - $msg = "Param 'log_path' is deprecated. See the module docs for more information" - Add-DeprecationWarning -obj $result -message $msg -version "2.14" -} -$_ansible_check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false - -$global:log_path = $log_path - -Try { - # ensure target OS support; < 2012 doesn't have cmdlet support for DC promotion - If(-not (Get-Command Install-WindowsFeature -ErrorAction SilentlyContinue)) { - Fail-Json -message "win_domain_controller requires at least Windows Server 2012" - } - - # validate args - If($state -eq "domain_controller") { - If(-not $dns_domain_name) { - Fail-Json -message "dns_domain_name is required when desired state is 'domain_controller'" - } - - If(-not $safe_mode_password) { - Fail-Json -message "safe_mode_password is required when desired state is 'domain_controller'" - } - - # ensure that domain admin user is in UPN or down-level domain format (prevent hang from https://support.microsoft.com/en-us/kb/2737935) - If(-not $domain_admin_user.Contains("\") -and -not $domain_admin_user.Contains("@")) { - Fail-Json -message "domain_admin_user must be in domain\user or user@domain.com format" - } - } - Else { # member_server - If(-not $local_admin_password) { - Fail-Json -message "local_admin_password is required when desired state is 'member_server'" - } - } - - # short-circuit "member server" check, since we don't need feature checks for this... - - $current_dc_domain = Get-DomainControllerDomain - - If($state -eq "member_server" -and -not $current_dc_domain) { - Exit-Json $result - } - - # all other operations will require the AD-DS and RSAT-ADDS features... - - $missing_features = Get-MissingFeatures - - If($missing_features.Count -gt 0) { - Write-DebugLog ("Missing Windows features ({0}), need to install" -f ($missing_features -join ", ")) - $result.changed = $true # we need to install features - If($_ansible_check_mode) { - # bail out here- we can't proceed without knowing the features are installed - Write-DebugLog "check-mode, exiting early" - Exit-Json $result - } - - Ensure-FeatureInstallation | Out-Null - } - - $domain_admin_cred = Create-Credential -cred_user $domain_admin_user -cred_password $domain_admin_password - - switch($state) { - domain_controller { - If(-not $safe_mode_password) { - Fail-Json -message "safe_mode_password is required for state=domain_controller" - } - - If($current_dc_domain) { - # FUTURE: implement managed Remove/Add to change domains? - - If($current_dc_domain -ne $dns_domain_name) { - Fail-Json "$(hostname) is a domain controller for domain $current_dc_domain; changing DC domains is not implemented" - } - } - - # need to promote to DC - If(-not $current_dc_domain) { - Write-DebugLog "Not currently a domain controller; needs promotion" - $result.changed = $true - If($_ansible_check_mode) { - Write-DebugLog "check-mode, exiting early" - Fail-Json -message $result - } - - $result.reboot_required = $true - - $safe_mode_secure = $safe_mode_password | ConvertTo-SecureString -AsPlainText -Force - Write-DebugLog "Installing domain controller..." - $install_params = @{ - DomainName = $dns_domain_name - Credential = $domain_admin_cred - SafeModeAdministratorPassword = $safe_mode_secure - } - if ($database_path) { - $install_params.DatabasePath = $database_path - } - if ($domain_log_path) { - $install_params.LogPath = $domain_log_path - } - if ($sysvol_path) { - $install_params.SysvolPath = $sysvol_path - } - if ($read_only) { - # while this is a switch value, if we set on $false site_name is required - # https://github.com/ansible/ansible/issues/35858 - $install_params.ReadOnlyReplica = $true - } - if ($site_name) { - $install_params.SiteName = $site_name - } - if ($null -ne $install_dns) { - $install_params.InstallDns = $install_dns - } - try - { - $null = Install-ADDSDomainController -NoRebootOnCompletion -Force @install_params - } catch [Microsoft.DirectoryServices.Deployment.DCPromoExecutionException] { - # ExitCode 15 == 'Role change is in progress or this computer needs to be restarted.' - # DCPromo exit codes details can be found at https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/deploy/troubleshooting-domain-controller-deployment - if ($_.Exception.ExitCode -eq 15) { - $result.reboot_required = $true - } else { - Fail-Json -obj $result -message "Failed to install ADDSDomainController with DCPromo: $($_.Exception.Message)" - } - } - # If $_.FullyQualifiedErrorId -eq 'Test.VerifyUserCredentialPermissions.DCPromo.General.25,Microsoft.DirectoryServices.Deployment.PowerShell.Commands.InstallADDSDomainControllerCommand' - # the module failed to resolve the given dns domain name - - Write-DebugLog "Installation complete, trying to start the Netlogon service" - # The Netlogon service is set to auto start but is not started. This is - # required for Ansible to connect back to the host and reboot in a - # later task. Even if this fails Ansible can still connect but only - # with ansible_winrm_transport=basic so we just display a warning if - # this fails. - try { - Start-Service -Name Netlogon - } catch { - Write-DebugLog "Failed to start the Netlogon service: $($_.Exception.Message)" - Add-Warning -obj $result -message "Failed to start the Netlogon service after promoting the host, Ansible may be unable to connect until the host is manually rebooting: $($_.Exception.Message)" - } - - Write-DebugLog "Domain Controller setup completed, needs reboot..." - } - } - member_server { - If(-not $local_admin_password) { - Fail-Json -message "local_admin_password is required for state=domain_controller" - } - # at this point we already know we're a DC and shouldn't be... - Write-DebugLog "Need to uninstall domain controller..." - $result.changed = $true - - Write-DebugLog "Checking for operation master roles assigned to this DC..." - - $assigned_roles = Get-OperationMasterRoles - - # FUTURE: figure out a sane way to hand off roles automatically (designated recipient server, randomly look one up?) - If($assigned_roles.Count -gt 0) { - Fail-Json -message ("This domain controller has operation master role(s) ({0}) assigned; they must be moved to other DCs before demotion (see Move-ADDirectoryServerOperationMasterRole)" -f ($assigned_roles -join ", ")) - } - - If($_ansible_check_mode) { - Write-DebugLog "check-mode, exiting early" - Exit-Json $result - } - - $result.reboot_required = $true - - $local_admin_secure = $local_admin_password | ConvertTo-SecureString -AsPlainText -Force - - Write-DebugLog "Uninstalling domain controller..." - Uninstall-ADDSDomainController -NoRebootOnCompletion -LocalAdministratorPassword $local_admin_secure -Credential $domain_admin_cred - Write-DebugLog "Uninstallation complete, needs reboot..." - } - default { throw ("invalid state {0}" -f $state) } - } - - Exit-Json $result -} -Catch { - $excep = $_ - - Write-DebugLog "Exception: $($excep | out-string)" - - Throw -} diff --git a/lib/ansible/modules/windows/win_domain_controller.py b/lib/ansible/modules/windows/win_domain_controller.py deleted file mode 100644 index 603abc4efc..0000000000 --- a/lib/ansible/modules/windows/win_domain_controller.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Red Hat, Inc. -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' -module: win_domain_controller -short_description: Manage domain controller/member server state for a Windows host -version_added: '2.3' -description: - - Ensure that a Windows Server 2012+ host is configured as a domain controller or demoted to member server. - - This module may require subsequent use of the M(win_reboot) action if changes are made. -options: - dns_domain_name: - description: - - When C(state) is C(domain_controller), the DNS name of the domain for which the targeted Windows host should be a DC. - type: str - domain_admin_user: - description: - - Username of a domain admin for the target domain (necessary to promote or demote a domain controller). - type: str - required: true - domain_admin_password: - description: - - Password for the specified C(domain_admin_user). - type: str - required: true - safe_mode_password: - description: - - Safe mode password for the domain controller (required when C(state) is C(domain_controller)). - type: str - local_admin_password: - description: - - Password to be assigned to the local C(Administrator) user (required when C(state) is C(member_server)). - type: str - read_only: - description: - - Whether to install the domain controller as a read only replica for an existing domain. - type: bool - default: no - version_added: '2.5' - site_name: - description: - - Specifies the name of an existing site where you can place the new domain controller. - - This option is required when I(read_only) is C(yes). - type: str - version_added: '2.5' - state: - description: - - Whether the target host should be a domain controller or a member server. - type: str - choices: [ domain_controller, member_server ] - database_path: - description: - - The path to a directory on a fixed disk of the Windows host where the - domain database will be created.. - - If not set then the default path is C(%SYSTEMROOT%\NTDS). - type: path - version_added: '2.5' - domain_log_path: - description: - - Specified the fully qualified, non-UNC path to a directory on a fixed disk of the local computer that will - contain the domain log files. - type: path - version_added: '2.10' - sysvol_path: - description: - - The path to a directory on a fixed disk of the Windows host where the - Sysvol folder will be created. - - If not set then the default path is C(%SYSTEMROOT%\SYSVOL). - type: path - version_added: '2.5' - install_dns: - description: - - Whether to install the DNS service when creating the domain controller. - - If not specified then the C(-InstallDns) option is not supplied to C(Install-ADDSDomainController) command, - see U(https://docs.microsoft.com/en-us/powershell/module/addsdeployment/install-addsdomaincontroller). - type: bool - version_added: '2.10' - log_path: - description: - - The path to log any debug information when running the module. - - This option is deprecated and should not be used, it will be removed in Ansible 2.14. - - This does not relate to the C(-LogPath) paramter of the install controller cmdlet. - type: str -seealso: -- module: win_domain -- module: win_domain_computer -- module: win_domain_group -- module: win_domain_membership -- module: win_domain_user -author: - - Matt Davis (@nitzmahone) -''' - -RETURN = r''' -reboot_required: - description: True if changes were made that require a reboot. - returned: always - type: bool - sample: true -''' - -EXAMPLES = r''' -- name: Ensure a server is a domain controller - win_domain_controller: - dns_domain_name: ansible.vagrant - domain_admin_user: testguy@ansible.vagrant - domain_admin_password: password123! - safe_mode_password: password123! - state: domain_controller - -# ensure a server is not a domain controller -# note that without an action wrapper, in the case where a DC is demoted, -# the task will fail with a 401 Unauthorized, because the domain credential -# becomes invalid to fetch the final output over WinRM. This requires win_async -# with credential switching (or other clever credential-switching -# mechanism to get the output and trigger the required reboot) -- win_domain_controller: - domain_admin_user: testguy@ansible.vagrant - domain_admin_password: password123! - local_admin_password: password123! - state: member_server - -- name: Promote server as a read only domain controller - win_domain_controller: - dns_domain_name: ansible.vagrant - domain_admin_user: testguy@ansible.vagrant - domain_admin_password: password123! - safe_mode_password: password123! - state: domain_controller - read_only: yes - site_name: London - -- name: Promote server with custom paths - win_domain_controller: - dns_domain_name: ansible.vagrant - domain_admin_user: testguy@ansible.vagrant - domain_admin_password: password123! - safe_mode_password: password123! - state: domain_controller - sysvol_path: D:\SYSVOL - database_path: D:\NTDS - domain_log_path: D:\NTDS - register: dc_promotion - -- name: Reboot after promotion - win_reboot: - when: dc_promotion.reboot_required -''' diff --git a/lib/ansible/modules/windows/win_domain_membership.ps1 b/lib/ansible/modules/windows/win_domain_membership.ps1 deleted file mode 100644 index 098dbd2ca6..0000000000 --- a/lib/ansible/modules/windows/win_domain_membership.ps1 +++ /dev/null @@ -1,315 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Set-StrictMode -Version 2 - -$ErrorActionPreference = "Stop" - -$log_path = $null - -Function Write-DebugLog { - Param( - [string]$msg - ) - - $DebugPreference = "Continue" - $date_str = Get-Date -Format u - $msg = "$date_str $msg" - - Write-Debug $msg - if($log_path) { - Add-Content $log_path $msg - } -} - -Function Get-DomainMembershipMatch { - Param( - [string] $dns_domain_name - ) - - # FUTURE: add support for NetBIOS domain name? - - # this requires the DC to be accessible; "DC unavailable" is indistinguishable from "not joined to the domain"... - Try { - Write-DebugLog "calling GetComputerDomain()" - $current_dns_domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Name - - $domain_match = $current_dns_domain -eq $dns_domain_name - - Write-DebugLog ("current domain {0} matches {1}: {2}" -f $current_dns_domain, $dns_domain_name, $domain_match) - - return $domain_match - } - catch [System.Security.Authentication.AuthenticationException] { - Write-DebugLog "Failed to get computer domain. Attempting a different method." - Add-Type -AssemblyName System.DirectoryServices.AccountManagement - $user_principal = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current - If ($user_principal.ContextType -eq "Machine") { - $current_dns_domain = (Get-CimInstance -ClassName Win32_ComputerSystem -Property Domain).Domain - - $domain_match = $current_dns_domain -eq $dns_domain_name - - Write-DebugLog ("current domain {0} matches {1}: {2}" -f $current_dns_domain, $dns_domain_name, $domain_match) - - return $domain_match - } - Else { - Fail-Json -obj $result -message "Failed to authenticate with domain controller and cannot retrieve the existing domain name: $($_.Exception.Message)" - } - } - Catch [System.DirectoryServices.ActiveDirectory.ActiveDirectoryObjectNotFoundException] { - Write-DebugLog "not currently joined to a reachable domain" - return $false - } -} - -Function Create-Credential { - Param( - [string] $cred_user, - [string] $cred_pass - ) - - $cred = New-Object System.Management.Automation.PSCredential($cred_user, $($cred_pass | ConvertTo-SecureString -AsPlainText -Force)) - - return $cred -} - -Function Get-HostnameMatch { - Param( - [string] $hostname - ) - - # Add-Computer will validate the "shape" of the hostname- we just care if it matches... - - $hostname_match = $env:COMPUTERNAME -eq $hostname - Write-DebugLog ("current hostname {0} matches {1}: {2}" -f $env:COMPUTERNAME, $hostname, $hostname_match) - - return $hostname_match -} - -Function Is-DomainJoined { - return (Get-CIMInstance Win32_ComputerSystem).PartOfDomain -} - -Function Join-Domain { - Param( - [string] $dns_domain_name, - [string] $new_hostname, - [string] $domain_admin_user, - [string] $domain_admin_password, - [string] $domain_ou_path - ) - - Write-DebugLog ("Creating credential for user {0}" -f $domain_admin_user) - $domain_cred = Create-Credential $domain_admin_user $domain_admin_password - - $add_args = @{ - ComputerName="." - Credential=$domain_cred - DomainName=$dns_domain_name - Force=$null - } - - Write-DebugLog "adding hostname set arg to Add-Computer args" - If($new_hostname) { - $add_args["NewName"] = $new_hostname - } - - - if($domain_ou_path){ - Write-DebugLog "adding OU destination arg to Add-Computer args" - $add_args["OUPath"] = $domain_ou_path - } - $argstr = $add_args | Out-String - Write-DebugLog "calling Add-Computer with args: $argstr" - try { - $add_result = Add-Computer @add_args - } catch { - Fail-Json -obj $result -message "failed to join domain: $($_.Exception.Message)" - } - - Write-DebugLog ("Add-Computer result was \n{0}" -f $add_result | Out-String) -} - -Function Get-Workgroup { - return (Get-CIMInstance Win32_ComputerSystem).Workgroup -} - -Function Set-Workgroup { - Param( - [string] $workgroup_name - ) - - Write-DebugLog ("Calling JoinDomainOrWorkgroup with workgroup {0}" -f $workgroup_name) - try { - $swg_result = Get-CimInstance Win32_ComputerSystem | Invoke-CimMethod -MethodName JoinDomainOrWorkgroup -Arguments @{Name="$workgroup_name"} - } catch { - Fail-Json -obj $result -message "failed to call Win32_ComputerSystem.JoinDomainOrWorkgroup($workgroup_name): $($_.Exception.Message)" - } - - if ($swg_result.ReturnValue -ne 0) { - Fail-Json -obj $result -message "failed to set workgroup through WMI, return value: $($swg_result.ReturnValue)" - } -} - -Function Join-Workgroup { - Param( - [string] $workgroup_name, - [string] $domain_admin_user, - [string] $domain_admin_password - ) - - If(Is-DomainJoined) { # if we're on a domain, unjoin it (which forces us to join a workgroup) - $domain_cred = Create-Credential $domain_admin_user $domain_admin_password - - # 2012+ call the Workgroup arg WorkgroupName, but seem to accept - try { - Remove-Computer -Workgroup $workgroup_name -Credential $domain_cred -Force - } catch { - Fail-Json -obj $result -message "failed to remove computer from domain: $($_.Exception.Message)" - } - } - - # we're already on a workgroup- change it. - Else { - Set-Workgroup $workgroup_name - } -} - - -$result = @{ - changed = $false - reboot_required = $false -} - -$params = Parse-Args -arguments $args -supports_check_mode $true - -$state = Get-AnsibleParam $params "state" -validateset @("domain","workgroup") -failifempty $result - -$dns_domain_name = Get-AnsibleParam $params "dns_domain_name" -$hostname = Get-AnsibleParam $params "hostname" -$workgroup_name = Get-AnsibleParam $params "workgroup_name" -$domain_admin_user = Get-AnsibleParam $params "domain_admin_user" -failifempty $result -$domain_admin_password = Get-AnsibleParam $params "domain_admin_password" -failifempty $result -$domain_ou_path = Get-AnsibleParam $params "domain_ou_path" - -$log_path = Get-AnsibleParam $params "log_path" -$_ansible_check_mode = Get-AnsibleParam $params "_ansible_check_mode" -default $false - -If ($state -eq "domain") { - If(-not $dns_domain_name) { - Fail-Json @{} "dns_domain_name is required when state is 'domain'" - } -} -Else { # workgroup - If(-not $workgroup_name) { - Fail-Json @{} "workgroup_name is required when state is 'workgroup'" - } -} - -$global:log_path = $log_path - -Try { - - $hostname_match = If($hostname) { Get-HostnameMatch $hostname } Else { $true } - - $result.changed = $result.changed -or (-not $hostname_match) - - Switch($state) { - domain { - $domain_match = Get-DomainMembershipMatch $dns_domain_name - - $result.changed = $result.changed -or (-not $domain_match) - - If($result.changed -and -not $_ansible_check_mode) { - If(-not $domain_match) { - If(Is-DomainJoined) { - Write-DebugLog "domain doesn't match, and we're already joined to another domain" - throw "switching domains is not implemented" - } - - $join_args = @{ - dns_domain_name = $dns_domain_name - domain_admin_user = $domain_admin_user - domain_admin_password = $domain_admin_password - } - - Write-DebugLog "not a domain member, joining..." - - If(-not $hostname_match) { - Write-DebugLog "adding hostname change to domain-join args" - $join_args.new_hostname = $hostname - } - If($null -ne $domain_ou_path){ # If OU Path is not empty - Write-DebugLog "adding domain_ou_path to domain-join args" - $join_args.domain_ou_path = $domain_ou_path - } - - Join-Domain @join_args - - # this change requires a reboot - $result.reboot_required = $true - } - ElseIf(-not $hostname_match) { # domain matches but hostname doesn't, just do a rename - Write-DebugLog ("domain matches, setting hostname to {0}" -f $hostname) - - $rename_args = @{NewName=$hostname} - - If (Is-DomainJoined) { - $domain_cred = Create-Credential $domain_admin_user $domain_admin_password - $rename_args.DomainCredential = $domain_cred - } - - Rename-Computer @rename_args - - # this change requires a reboot - $result.reboot_required = $true - } Else { - # no change is needed - } - - } - Else { - Write-DebugLog "check mode, exiting early..." - } - - } - - workgroup { - $workgroup_match = $(Get-Workgroup) -eq $workgroup_name - - $result.changed = $result.changed -or (-not $workgroup_match) - - If(-not $_ansible_check_mode) { - If(-not $workgroup_match) { - Write-DebugLog ("setting workgroup to {0}" -f $workgroup_name) - Join-Workgroup -workgroup_name $workgroup_name -domain_admin_user $domain_admin_user -domain_admin_password $domain_admin_password - - # this change requires a reboot - $result.reboot_required = $true - } - If(-not $hostname_match) { - Write-DebugLog ("setting hostname to {0}" -f $hostname) - Rename-Computer -NewName $hostname - - # this change requires a reboot - $result.reboot_required = $true - } - } - } - default { throw "invalid state $state" } - } - - Exit-Json $result -} -Catch { - $excep = $_ - - Write-DebugLog "Exception: $($excep | out-string)" - - Throw -} diff --git a/lib/ansible/modules/windows/win_domain_membership.py b/lib/ansible/modules/windows/win_domain_membership.py deleted file mode 100644 index e74a0d8c01..0000000000 --- a/lib/ansible/modules/windows/win_domain_membership.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Red Hat, Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' -module: win_domain_membership -short_description: Manage domain/workgroup membership for a Windows host -version_added: '2.3' -description: -- Manages domain membership or workgroup membership for a Windows host. Also supports hostname changes. -- This module may require subsequent use of the M(win_reboot) action if changes are made. -options: - dns_domain_name: - description: - - When C(state) is C(domain), the DNS name of the domain to which the targeted Windows host should be joined. - type: str - domain_admin_user: - description: - - Username of a domain admin for the target domain (required to join or leave the domain). - type: str - required: yes - domain_admin_password: - description: - - Password for the specified C(domain_admin_user). - type: str - hostname: - description: - - The desired hostname for the Windows host. - type: str - domain_ou_path: - description: - - The desired OU path for adding the computer object. - - This is only used when adding the target host to a domain, if it is already a member then it is ignored. - type: str - version_added: "2.4" - state: - description: - - Whether the target host should be a member of a domain or workgroup. - type: str - choices: [ domain, workgroup ] - workgroup_name: - description: - - When C(state) is C(workgroup), the name of the workgroup that the Windows host should be in. - type: str -seealso: -- module: win_domain -- module: win_domain_controller -- module: win_domain_computer -- module: win_domain_group -- module: win_domain_user -- module: win_group -- module: win_group_membership -- module: win_user -author: - - Matt Davis (@nitzmahone) -''' - -RETURN = r''' -reboot_required: - description: True if changes were made that require a reboot. - returned: always - type: bool - sample: true -''' - -EXAMPLES = r''' - -# host should be a member of domain ansible.vagrant; module will ensure the hostname is mydomainclient -# and will use the passed credentials to join domain if necessary. -# Ansible connection should use local credentials if possible. -# If a reboot is required, the second task will trigger one and wait until the host is available. -- hosts: winclient - gather_facts: no - tasks: - - win_domain_membership: - dns_domain_name: ansible.vagrant - hostname: mydomainclient - domain_admin_user: testguy@ansible.vagrant - domain_admin_password: password123! - domain_ou_path: "OU=Windows,OU=Servers,DC=ansible,DC=vagrant" - state: domain - register: domain_state - - - win_reboot: - when: domain_state.reboot_required - - - -# Host should be in workgroup mywg- module will use the passed credentials to clean-unjoin domain if possible. -# Ansible connection should use local credentials if possible. -# The domain admin credentials can be sourced from a vault-encrypted variable -- hosts: winclient - gather_facts: no - tasks: - - win_domain_membership: - workgroup_name: mywg - domain_admin_user: '{{ win_domain_admin_user }}' - domain_admin_password: '{{ win_domain_admin_password }}' - state: workgroup -''' diff --git a/lib/ansible/modules/windows/win_dsc.ps1 b/lib/ansible/modules/windows/win_dsc.ps1 deleted file mode 100644 index 690f391a7b..0000000000 --- a/lib/ansible/modules/windows/win_dsc.ps1 +++ /dev/null @@ -1,398 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Trond Hindenes <trond@hindenes.com>, and others -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Version 5 - -Function ConvertTo-ArgSpecType { - <# - .SYNOPSIS - Converts the DSC parameter type to the arg spec type required for Ansible. - #> - param( - [Parameter(Mandatory=$true)][String]$CimType - ) - - $arg_type = switch($CimType) { - Boolean { "bool" } - Char16 { [Func[[Object], [Char]]]{ [System.Char]::Parse($args[0].ToString()) } } - DateTime { [Func[[Object], [DateTime]]]{ [System.DateTime]($args[0].ToString()) } } - Instance { "dict" } - Real32 { "float" } - Real64 { [Func[[Object], [Double]]]{ [System.Double]::Parse($args[0].ToString()) } } - Reference { "dict" } - SInt16 { [Func[[Object], [Int16]]]{ [System.Int16]::Parse($args[0].ToString()) } } - SInt32 { "int" } - SInt64 { [Func[[Object], [Int64]]]{ [System.Int64]::Parse($args[0].ToString()) } } - SInt8 { [Func[[Object], [SByte]]]{ [System.SByte]::Parse($args[0].ToString()) } } - String { "str" } - UInt16 { [Func[[Object], [UInt16]]]{ [System.UInt16]::Parse($args[0].ToString()) } } - UInt32 { [Func[[Object], [UInt32]]]{ [System.UInt32]::Parse($args[0].ToString()) } } - UInt64 { [Func[[Object], [UInt64]]]{ [System.UInt64]::Parse($args[0].ToString()) } } - UInt8 { [Func[[Object], [Byte]]]{ [System.Byte]::Parse($args[0].ToString()) } } - Unknown { "raw" } - default { "raw" } - } - return $arg_type -} - -Function Get-DscCimClassProperties { - <# - .SYNOPSIS - Get's a list of CimProperties of a CIM Class. It filters out any magic or - read only properties that we don't need to know about. - #> - param([Parameter(Mandatory=$true)][String]$ClassName) - - $resource = Get-CimClass -ClassName $ClassName -Namespace root\Microsoft\Windows\DesiredStateConfiguration - - # Filter out any magic properties that are used internally on an OMI_BaseResource - # https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/DscSupport/CimDSCParser.cs#L1203 - $magic_properties = @("ResourceId", "SourceInfo", "ModuleName", "ModuleVersion", "ConfigurationName") - $properties = $resource.CimClassProperties | Where-Object { - - ($resource.CimSuperClassName -ne "OMI_BaseResource" -or $_.Name -notin $magic_properties) -and - -not $_.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::ReadOnly) - } - - return ,$properties -} - -Function Add-PropertyOption { - <# - .SYNOPSIS - Adds the spec for the property type to the existing module specification. - #> - param( - [Parameter(Mandatory=$true)][Hashtable]$Spec, - [Parameter(Mandatory=$true)] - [Microsoft.Management.Infrastructure.CimPropertyDeclaration]$Property - ) - - $option = @{ - required = $false - } - $property_name = $Property.Name - $property_type = $Property.CimType.ToString() - - if ($Property.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::Key) -or - $Property.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::Required)) { - $option.required = $true - } - - if ($null -ne $Property.Qualifiers['Values']) { - $option.choices = [System.Collections.Generic.List`1[Object]]$Property.Qualifiers['Values'].Value - } - - if ($property_name -eq "Name") { - # For backwards compatibility we support specifying the Name DSC property as item_name - $option.aliases = @("item_name") - } elseif ($property_name -ceq "key") { - # There seems to be a bug in the CIM property parsing when the property name is 'Key'. The CIM instance will - # think the name is 'key' when the MOF actually defines it as 'Key'. We set the proper casing so the module arg - # validator won't fire a case sensitive warning - $property_name = "Key" - } - - if ($Property.ReferenceClassName -eq "MSFT_Credential") { - # Special handling for the MSFT_Credential type (PSCredential), we handle this with having 2 options that - # have the suffix _username and _password. - $option_spec_pass = @{ - type = "str" - required = $option.required - no_log = $true - } - $Spec.options."$($property_name)_password" = $option_spec_pass - $Spec.required_together.Add(@("$($property_name)_username", "$($property_name)_password")) > $null - - $property_name = "$($property_name)_username" - $option.type = "str" - } elseif ($Property.ReferenceClassName -eq "MSFT_KeyValuePair") { - $option.type = "dict" - } elseif ($property_type.EndsWith("Array")) { - $option.type = "list" - $option.elements = ConvertTo-ArgSpecType -CimType $property_type.Substring(0, $property_type.Length - 5) - } else { - $option.type = ConvertTo-ArgSpecType -CimType $property_type - } - - if (($option.type -eq "dict" -or ($option.type -eq "list" -and $option.elements -eq "dict")) -and - $Property.ReferenceClassName -ne "MSFT_KeyValuePair") { - # Get the sub spec if the type is a Instance (CimInstance/dict) - $sub_option_spec = Get-OptionSpec -ClassName $Property.ReferenceClassName - $option += $sub_option_spec - } - - $Spec.options.$property_name = $option -} - -Function Get-OptionSpec { - <# - .SYNOPSIS - Generates the specifiec used in AnsibleModule for a CIM MOF resource name. - - .NOTES - This won't be able to retrieve the default values for an option as that is not defined in the MOF for a resource. - Default values are still preserved in the DSC engine if we don't pass in the property at all, we just can't report - on what they are automatically. - #> - param( - [Parameter(Mandatory=$true)][String]$ClassName - ) - - $spec = @{ - options = @{} - required_together = [System.Collections.ArrayList]@() - } - $properties = Get-DscCimClassProperties -ClassName $ClassName - foreach ($property in $properties) { - Add-PropertyOption -Spec $spec -Property $property - } - - return $spec -} - -Function ConvertTo-CimInstance { - <# - .SYNOPSIS - Converts a dict to a CimInstance of the specified Class. Also provides a - better error message if this fails that contains the option name that failed. - #> - param( - [Parameter(Mandatory=$true)][String]$Name, - [Parameter(Mandatory=$true)][String]$ClassName, - [Parameter(Mandatory=$true)][System.Collections.IDictionary]$Value, - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module, - [Switch]$Recurse - ) - - $properties = @{} - foreach ($value_info in $Value.GetEnumerator()) { - # Need to remove all null values from existing dict so the conversion works - if ($null -eq $value_info.Value) { - continue - } - $properties.($value_info.Key) = $value_info.Value - } - - if ($Recurse) { - # We want to validate and convert and values to what's required by DSC - $properties = ConvertTo-DscProperty -ClassName $ClassName -Params $properties -Module $Module - } - - try { - return (New-CimInstance -ClassName $ClassName -Property $properties -ClientOnly) - } catch { - # New-CimInstance raises a poor error message, make sure we mention what option it is for - $Module.FailJson("Failed to cast dict value for option '$Name' to a CimInstance: $($_.Exception.Message)", $_) - } -} - -Function ConvertTo-DscProperty { - <# - .SYNOPSIS - Converts the input module parameters that have been validated and casted - into the types expected by the DSC engine. This is mostly done to deal with - types like PSCredential and Dictionaries. - #> - param( - [Parameter(Mandatory=$true)][String]$ClassName, - [Parameter(Mandatory=$true)][System.Collections.IDictionary]$Params, - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module - ) - $properties = Get-DscCimClassProperties -ClassName $ClassName - - $dsc_properties = @{} - foreach ($property in $properties) { - $property_name = $property.Name - $property_type = $property.CimType.ToString() - - if ($property.ReferenceClassName -eq "MSFT_Credential") { - $username = $Params."$($property_name)_username" - $password = $Params."$($property_name)_password" - - # No user set == No option set in playbook, skip this property - if ($null -eq $username) { - continue - } - $sec_password = ConvertTo-SecureString -String $password -AsPlainText -Force - $value = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $sec_password - } else { - $value = $Params.$property_name - - # The actual value wasn't set, skip adding this property - if ($null -eq $value) { - continue - } - - if ($property.ReferenceClassName -eq "MSFT_KeyValuePair") { - $key_value_pairs = [System.Collections.Generic.List`1[CimInstance]]@() - foreach ($value_info in $value.GetEnumerator()) { - $kvp = @{Key = $value_info.Key; Value = $value_info.Value.ToString()} - $cim_instance = ConvertTo-CimInstance -Name $property_name -ClassName MSFT_KeyValuePair ` - -Value $kvp -Module $Module - $key_value_pairs.Add($cim_instance) > $null - } - $value = $key_value_pairs.ToArray() - } elseif ($null -ne $property.ReferenceClassName) { - # Convert the dict to a CimInstance (or list of CimInstances) - $convert_args = @{ - ClassName = $property.ReferenceClassName - Module = $Module - Name = $property_name - Recurse = $true - } - if ($property_type.EndsWith("Array")) { - $value = [System.Collections.Generic.List`1[CimInstance]]@() - foreach ($raw in $Params.$property_name.GetEnumerator()) { - $cim_instance = ConvertTo-CimInstance -Value $raw @convert_args - $value.Add($cim_instance) > $null - } - $value = $value.ToArray() # Need to make sure we are dealing with an Array not a List - } else { - $value = ConvertTo-CimInstance -Value $value @convert_args - } - } - } - $dsc_properties.$property_name = $value - } - - return $dsc_properties -} - -Function Invoke-DscMethod { - <# - .SYNOPSIS - Invokes the DSC Resource Method specified in another PS pipeline. This is - done so we can retrieve the Verbose stream and return it back to the user - for futher debugging. - #> - param( - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module, - [Parameter(Mandatory=$true)][String]$Method, - [Parameter(Mandatory=$true)][Hashtable]$Arguments - ) - - # Invoke the DSC resource in a separate runspace so we can capture the Verbose output - $ps = [PowerShell]::Create() - $ps.AddCommand("Invoke-DscResource").AddParameter("Method", $Method) > $null - $ps.AddParameters($Arguments) > $null - - $result = $ps.Invoke() - - # Pass the warnings through to the AnsibleModule return result - foreach ($warning in $ps.Streams.Warning) { - $Module.Warn($warning.Message) - } - - # If running at a high enough verbosity, add the verbose output to the AnsibleModule return result - if ($Module.Verbosity -ge 3) { - $verbose_logs = [System.Collections.Generic.List`1[String]]@() - foreach ($verbosity in $ps.Streams.Verbose) { - $verbose_logs.Add($verbosity.Message) > $null - } - $Module.Result."verbose_$($Method.ToLower())" = $verbose_logs - } - - if ($ps.HadErrors) { - # Cannot pass in the ErrorRecord as it's a RemotingErrorRecord and doesn't contain the ScriptStackTrace - # or other info that would be useful - $Module.FailJson("Failed to invoke DSC $Method method: $($ps.Streams.Error[0].Exception.Message)") - } - - return $result -} - -# win_dsc is unique in that is builds the arg spec based on DSC Resource input. To get this info -# we need to read the resource_name and module_version value which is done outside of Ansible.Basic -if ($args.Length -gt 0) { - $params = Get-Content -Path $args[0] | ConvertFrom-Json -} else { - $params = $complex_args -} -if (-not $params.ContainsKey("resource_name")) { - $res = @{ - msg = "missing required argument: resource_name" - failed = $true - } - Write-Output -InputObject (ConvertTo-Json -Compress -InputObject $res) - exit 1 -} -$resource_name = $params.resource_name - -if ($params.ContainsKey("module_version")) { - $module_version = $params.module_version -} else { - $module_version = "latest" -} - -$module_versions = (Get-DscResource -Name $resource_name -ErrorAction SilentlyContinue | Sort-Object -Property Version) -$resource = $null -if ($module_version -eq "latest" -and $null -ne $module_versions) { - $resource = $module_versions[-1] -} elseif ($module_version -ne "latest") { - $resource = $module_versions | Where-Object { $_.Version -eq $module_version } -} - -if (-not $resource) { - if ($module_version -eq "latest") { - $msg = "Resource '$resource_name' not found." - } else { - $msg = "Resource '$resource_name' with version '$module_version' not found." - $msg += " Versions installed: '$($module_versions.Version -join "', '")'." - } - - Write-Output -InputObject (ConvertTo-Json -Compress -InputObject @{ failed = $true; msg = $msg }) - exit 1 -} - -# Build the base args for the DSC Invocation based on the resource selected -$dsc_args = @{ - Name = $resource.Name -} - -# Binary resources are not working very well with that approach - need to guesstimate module name/version -$module_version = $null -if ($resource.Module) { - $dsc_args.ModuleName = @{ - ModuleName = $resource.Module.Name - ModuleVersion = $resource.Module.Version - } - $module_version = $resource.Module.Version.ToString() -} else { - $dsc_args.ModuleName = "PSDesiredStateConfiguration" -} - -# To ensure the class registered with CIM is the one based on our version, we want to run the Get method so the DSC -# engine updates the metadata propery. We don't care about any errors here -try { - Invoke-DscResource -Method Get -Property @{Fake="Fake"} @dsc_args > $null -} catch {} - -# Dynamically build the option spec based on the resource_name specified and create the module object -$spec = Get-OptionSpec -ClassName $resource.ResourceType -$spec.supports_check_mode = $true -$spec.options.module_version = @{ type = "str"; default = "latest" } -$spec.options.resource_name = @{ type = "str"; required = $true } - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) -$module.Result.reboot_required = $false -$module.Result.module_version = $module_version - -# Build the DSC invocation arguments and invoke the resource -$dsc_args.Property = ConvertTo-DscProperty -ClassName $resource.ResourceType -Module $module -Params $Module.Params -$dsc_args.Verbose = $true - -$test_result = Invoke-DscMethod -Module $module -Method Test -Arguments $dsc_args -if ($test_result.InDesiredState -ne $true) { - if (-not $module.CheckMode) { - $result = Invoke-DscMethod -Module $module -Method Set -Arguments $dsc_args - $module.Result.reboot_required = $result.RebootRequired - } - $module.Result.changed = $true -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_dsc.py b/lib/ansible/modules/windows/win_dsc.py deleted file mode 100644 index 200d025eb8..0000000000 --- a/lib/ansible/modules/windows/win_dsc.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Trond Hindenes <trond@hindenes.com>, and others -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_dsc -version_added: "2.4" -short_description: Invokes a PowerShell DSC configuration -description: -- Configures a resource using PowerShell DSC. -- Requires PowerShell version 5.0 or newer. -- Most of the options for this module are dynamic and will vary depending on - the DSC Resource specified in I(resource_name). -- See :doc:`/user_guide/windows_dsc` for more information on how to use this module. -options: - resource_name: - description: - - The name of the DSC Resource to use. - - Must be accessible to PowerShell using any of the default paths. - type: str - required: yes - module_version: - description: - - Can be used to configure the exact version of the DSC resource to be - invoked. - - Useful if the target node has multiple versions installed of the module - containing the DSC resource. - - If not specified, the module will follow standard PowerShell convention - and use the highest version available. - type: str - default: latest - free_form: - description: - - The M(win_dsc) module takes in multiple free form options based on the - DSC resource being invoked by I(resource_name). - - There is no option actually named C(free_form) so see the examples. - - This module will try and convert the option to the correct type required - by the DSC resource and throw a warning if it fails. - - If the type of the DSC resource option is a C(CimInstance) or - C(CimInstance[]), this means the value should be a dictionary or list - of dictionaries based on the values required by that option. - - If the type of the DSC resource option is a C(PSCredential) then there - needs to be 2 options set in the Ansible task definition suffixed with - C(_username) and C(_password). - - If the type of the DSC resource option is an array, then a list should be - provided but a comma separated string also work. Use a list where - possible as no escaping is required and it works with more complex types - list C(CimInstance[]). - - If the type of the DSC resource option is a C(DateTime), you should use - a string in the form of an ISO 8901 string to ensure the exact date is - used. - - Since Ansible 2.8, Ansible will now validate the input fields against the - DSC resource definition automatically. Older versions will silently - ignore invalid fields. - type: str - required: true -notes: -- By default there are a few builtin resources that come with PowerShell 5.0, - see U(https://docs.microsoft.com/en-us/powershell/scripting/dsc/resources/resources) for - more information on these resources. -- Custom DSC resources can be installed with M(win_psmodule) using the I(name) - option. -- The DSC engine run's each task as the SYSTEM account, any resources that need - to be accessed with a different account need to have C(PsDscRunAsCredential) - set. -- To see the valid options for a DSC resource, run the module with C(-vvv) to - show the possible module invocation. Default values are not shown in this - output but are applied within the DSC engine. -author: -- Trond Hindenes (@trondhindenes) -''' - -EXAMPLES = r''' -- name: Extract zip file - win_dsc: - resource_name: Archive - Ensure: Present - Path: C:\Temp\zipfile.zip - Destination: C:\Temp\Temp2 - -- name: Install a Windows feature with the WindowsFeature resource - win_dsc: - resource_name: WindowsFeature - Name: telnet-client - -- name: Edit HKCU reg key under specific user - win_dsc: - resource_name: Registry - Ensure: Present - Key: HKEY_CURRENT_USER\ExampleKey - ValueName: TestValue - ValueData: TestData - PsDscRunAsCredential_username: '{{ansible_user}}' - PsDscRunAsCredential_password: '{{ansible_password}}' - no_log: true - -- name: Create file with multiple attributes - win_dsc: - resource_name: File - DestinationPath: C:\ansible\dsc - Attributes: # can also be a comma separated string, e.g. 'Hidden, System' - - Hidden - - System - Ensure: Present - Type: Directory - -- name: Call DSC resource with DateTime option - win_dsc: - resource_name: DateTimeResource - DateTimeOption: '2019-02-22T13:57:31.2311892+00:00' - -# more complex example using custom DSC resource and dict values -- name: Setup the xWebAdministration module - win_psmodule: - name: xWebAdministration - state: present - -- name: Create IIS Website with Binding and Authentication options - win_dsc: - resource_name: xWebsite - Ensure: Present - Name: DSC Website - State: Started - PhysicalPath: C:\inetpub\wwwroot - BindingInfo: # Example of a CimInstance[] DSC parameter (list of dicts) - - Protocol: https - Port: 1234 - CertificateStoreName: MY - CertificateThumbprint: C676A89018C4D5902353545343634F35E6B3A659 - HostName: DSCTest - IPAddress: '*' - SSLFlags: '1' - - Protocol: http - Port: 4321 - IPAddress: '*' - AuthenticationInfo: # Example of a CimInstance DSC parameter (dict) - Anonymous: no - Basic: true - Digest: false - Windows: yes -''' - -RETURN = r''' -module_version: - description: The version of the dsc resource/module used. - returned: always - type: str - sample: "1.0.1" -reboot_required: - description: Flag returned from the DSC engine indicating whether or not - the machine requires a reboot for the invoked changes to take effect. - returned: always - type: bool - sample: true -verbose_test: - description: The verbose output as a list from executing the DSC test - method. - returned: Ansible verbosity is -vvv or greater - type: list - sample: [ - "Perform operation 'Invoke CimMethod' with the following parameters, ", - "[SERVER]: LCM: [Start Test ] [[File]DirectResourceAccess]", - "Operation 'Invoke CimMethod' complete." - ] -verbose_set: - description: The verbose output as a list from executing the DSC Set - method. - returned: Ansible verbosity is -vvv or greater and a change occurred - type: list - sample: [ - "Perform operation 'Invoke CimMethod' with the following parameters, ", - "[SERVER]: LCM: [Start Set ] [[File]DirectResourceAccess]", - "Operation 'Invoke CimMethod' complete." - ] -''' diff --git a/lib/ansible/modules/windows/win_environment.ps1 b/lib/ansible/modules/windows/win_environment.ps1 deleted file mode 100644 index bf0c71e94d..0000000000 --- a/lib/ansible/modules/windows/win_environment.ps1 +++ /dev/null @@ -1,61 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) <figs@unity.demon.co.uk> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - name = @{ type = "str"; required = $true } - level = @{ type = "str"; choices = "machine", "process", "user"; required = $true } - state = @{ type = "str"; choices = "absent", "present"; default = "present" } - value = @{ type = "str" } - } - required_if = @(,@("state", "present", @("value"))) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$name = $module.Params.name -$level = $module.Params.level -$state = $module.Params.state -$value = $module.Params.value - -$before_value = [Environment]::GetEnvironmentVariable($name, $level) -$module.Result.before_value = $before_value -$module.Result.value = $value - -# When removing environment, set value to $null if set -if ($state -eq "absent" -and $value) { - $module.Warn("When removing environment variable '$name' it should not have a value '$value' set") - $value = $null -} elseif ($state -eq "present" -and (-not $value)) { - $module.FailJson("When state=present, value must be defined and not an empty string, if you wish to remove the envvar, set state=absent") -} - -$module.Diff.before = @{ $level = @{} } -if ($before_value) { - $module.Diff.before.$level.$name = $before_value -} -$module.Diff.after = @{ $level = @{} } -if ($value) { - $module.Diff.after.$level.$name = $value -} - -if ($state -eq "present" -and $before_value -ne $value) { - if (-not $module.CheckMode) { - [Environment]::SetEnvironmentVariable($name, $value, $level) - } - $module.Result.changed = $true - -} elseif ($state -eq "absent" -and $null -ne $before_value) { - if (-not $module.CheckMode) { - [Environment]::SetEnvironmentVariable($name, $null, $level) - } - $module.Result.changed = $true -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_environment.py b/lib/ansible/modules/windows/win_environment.py deleted file mode 100644 index b3214f89ad..0000000000 --- a/lib/ansible/modules/windows/win_environment.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) <figs@unity.demon.co.uk> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_environment -version_added: '2.0' -short_description: Modify environment variables on windows hosts -description: -- Uses .net Environment to set or remove environment variables and can set at User, Machine or Process level. -- User level environment variables will be set, but not available until the user has logged off and on again. -options: - state: - description: - - Set to C(present) to ensure environment variable is set. - - Set to C(absent) to ensure it is removed. - type: str - choices: [ absent, present ] - default: present - name: - description: - - The name of the environment variable. - type: str - required: yes - value: - description: - - The value to store in the environment variable. - - Must be set when C(state=present) and cannot be an empty string. - - Can be omitted for C(state=absent). - type: str - level: - description: - - The level at which to set the environment variable. - - Use C(machine) to set for all users. - - Use C(user) to set for the current user that ansible is connected as. - - Use C(process) to set for the current process. Probably not that useful. - type: str - required: yes - choices: [ machine, process, user ] -notes: -- This module is best-suited for setting the entire value of an - environment variable. For safe element-based management of - path-like environment vars, use the M(win_path) module. -- This module does not broadcast change events. - This means that the minority of windows applications which can have - their environment changed without restarting will not be notified and - therefore will need restarting to pick up new environment settings. - User level environment variables will require the user to log out - and in again before they become available. -seealso: -- module: win_path -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Set an environment variable for all users - win_environment: - state: present - name: TestVariable - value: Test value - level: machine - -- name: Remove an environment variable for the current user - win_environment: - state: absent - name: TestVariable - level: user -''' - -RETURN = r''' -before_value: - description: the value of the environment key before a change, this is null if it didn't exist - returned: always - type: str - sample: C:\Windows\System32 -value: - description: the value the environment key has been set to, this is null if removed - returned: always - type: str - sample: C:\Program Files\jdk1.8 -''' diff --git a/lib/ansible/modules/windows/win_feature.ps1 b/lib/ansible/modules/windows/win_feature.ps1 deleted file mode 100644 index 9a7e1c3081..0000000000 --- a/lib/ansible/modules/windows/win_feature.ps1 +++ /dev/null @@ -1,111 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Paul Durivage <paul.durivage@rackspace.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Import-Module -Name ServerManager - -$result = @{ - changed = $false -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "list" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" - -$include_sub_features = Get-AnsibleParam -obj $params -name "include_sub_features" -type "bool" -default $false -$include_management_tools = Get-AnsibleParam -obj $params -name "include_management_tools" -type "bool" -default $false -$source = Get-AnsibleParam -obj $params -name "source" -type "str" - -$install_cmdlet = $false -if (Get-Command -Name Install-WindowsFeature -ErrorAction SilentlyContinue) { - Set-Alias -Name Install-AnsibleWindowsFeature -Value Install-WindowsFeature - Set-Alias -Name Uninstall-AnsibleWindowsFeature -Value Uninstall-WindowsFeature - $install_cmdlet = $true -} elseif (Get-Command -Name Add-WindowsFeature -ErrorAction SilentlyContinue) { - Set-Alias -Name Install-AnsibleWindowsFeature -Value Add-WindowsFeature - Set-Alias -Name Uninstall-AnsibleWindowsFeature -Value Remove-WindowsFeature -} else { - Fail-Json -obj $result -message "This version of Windows does not support the cmdlets Install-WindowsFeature or Add-WindowsFeature" -} - -if ($state -eq "present") { - $install_args = @{ - Name = $name - IncludeAllSubFeature = $include_sub_features - Restart = $false - WhatIf = $check_mode - ErrorAction = "Stop" - } - - if ($install_cmdlet) { - $install_args.IncludeManagementTools = $include_management_tools - $install_args.Confirm = $false - if ($source) { - if (-not (Test-Path -Path $source)) { - Fail-Json -obj $result -message "Failed to find source path $source for feature install" - } - $install_args.Source = $source - } - } - - try { - $action_results = Install-AnsibleWindowsFeature @install_args - } catch { - Fail-Json -obj $result -message "Failed to install Windows Feature: $($_.Exception.Message)" - } -} else { - $uninstall_args = @{ - Name = $name - Restart = $false - WhatIf = $check_mode - ErrorAction = "Stop" - } - if ($install_cmdlet) { - $uninstall_args.IncludeManagementTools = $include_management_tools - } - - try { - $action_results = Uninstall-AnsibleWindowsFeature @uninstall_args - } catch { - Fail-Json -obj $result -message "Failed to uninstall Windows Feature: $($_.Exception.Message)" - } -} - -# Loop through results and create a hash containing details about -# each role/feature that is installed/removed -# $action_results.FeatureResult is not empty if anything was changed -$feature_results = @() -foreach ($action_result in $action_results.FeatureResult) { - $message = @() - foreach ($msg in $action_result.Message) { - $message += @{ - message_type = $msg.MessageType.ToString() - error_code = $msg.ErrorCode - text = $msg.Text - } - } - - $feature_results += @{ - id = $action_result.Id - display_name = $action_result.DisplayName - message = $message - reboot_required = ConvertTo-Bool -obj $action_result.RestartNeeded - skip_reason = $action_result.SkipReason.ToString() - success = ConvertTo-Bool -obj $action_result.Success - restart_needed = ConvertTo-Bool -obj $action_result.RestartNeeded - } - $result.changed = $true -} -$result.feature_result = $feature_results -$result.success = ConvertTo-Bool -obj $action_results.Success -$result.exitcode = $action_results.ExitCode.ToString() -$result.reboot_required = ConvertTo-Bool -obj $action_results.RestartNeeded -# controls whether Ansible will fail or not -$result.failed = (-not $action_results.Success) - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_feature.py b/lib/ansible/modules/windows/win_feature.py deleted file mode 100644 index 62e310b282..0000000000 --- a/lib/ansible/modules/windows/win_feature.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Paul Durivage <paul.durivage@rackspace.com> -# Copyright: (c) 2014, Trond Hindenes <trond@hindenes.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_feature -version_added: "1.7" -short_description: Installs and uninstalls Windows Features on Windows Server -description: - - Installs or uninstalls Windows Roles or Features on Windows Server. - - This module uses the Add/Remove-WindowsFeature Cmdlets on Windows 2008 R2 - and Install/Uninstall-WindowsFeature Cmdlets on Windows 2012, which are not available on client os machines. -options: - name: - description: - - Names of roles or features to install as a single feature or a comma-separated list of features. - - To list all available features use the PowerShell command C(Get-WindowsFeature). - type: list - required: yes - state: - description: - - State of the features or roles on the system. - type: str - choices: [ absent, present ] - default: present - include_sub_features: - description: - - Adds all subfeatures of the specified feature. - type: bool - default: no - include_management_tools: - description: - - Adds the corresponding management tools to the specified feature. - - Not supported in Windows 2008 R2 and will be ignored. - type: bool - default: no - source: - description: - - Specify a source to install the feature from. - - Not supported in Windows 2008 R2 and will be ignored. - - Can either be C({driveletter}:\sources\sxs) or C(\\{IP}\share\sources\sxs). - type: str - version_added: "2.1" -seealso: -- module: win_chocolatey -- module: win_package -author: - - Paul Durivage (@angstwad) - - Trond Hindenes (@trondhindenes) -''' - -EXAMPLES = r''' -- name: Install IIS (Web-Server only) - win_feature: - name: Web-Server - state: present - -- name: Install IIS (Web-Server and Web-Common-Http) - win_feature: - name: - - Web-Server - - Web-Common-Http - state: present - -- name: Install NET-Framework-Core from file - win_feature: - name: NET-Framework-Core - source: C:\Temp\iso\sources\sxs - state: present - -- name: Install IIS Web-Server with sub features and management tools - win_feature: - name: Web-Server - state: present - include_sub_features: yes - include_management_tools: yes - register: win_feature - -- name: Reboot if installing Web-Server feature requires it - win_reboot: - when: win_feature.reboot_required -''' - -RETURN = r''' -exitcode: - description: The stringified exit code from the feature installation/removal command. - returned: always - type: str - sample: Success -feature_result: - description: List of features that were installed or removed. - returned: success - type: complex - sample: - contains: - display_name: - description: Feature display name. - returned: always - type: str - sample: "Telnet Client" - id: - description: A list of KB article IDs that apply to the update. - returned: always - type: int - sample: 44 - message: - description: Any messages returned from the feature subsystem that occurred during installation or removal of this feature. - returned: always - type: list - elements: str - sample: [] - reboot_required: - description: True when the target server requires a reboot as a result of installing or removing this feature. - returned: always - type: bool - sample: true - restart_needed: - description: DEPRECATED in Ansible 2.4 (refer to C(reboot_required) instead). True when the target server requires a reboot as a - result of installing or removing this feature. - returned: always - type: bool - sample: true - skip_reason: - description: The reason a feature installation or removal was skipped. - returned: always - type: str - sample: NotSkipped - success: - description: If the feature installation or removal was successful. - returned: always - type: bool - sample: true -reboot_required: - description: True when the target server requires a reboot to complete updates (no further updates can be installed until after a reboot). - returned: success - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_file.ps1 b/lib/ansible/modules/windows/win_file.ps1 deleted file mode 100644 index 5442754925..0000000000 --- a/lib/ansible/modules/windows/win_file.ps1 +++ /dev/null @@ -1,152 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true - -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "dest","name" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -validateset "absent","directory","file","touch" - -# used in template/copy when dest is the path to a dir and source is a file -$original_basename = Get-AnsibleParam -obj $params -name "_original_basename" -type "str" -if ((Test-Path -LiteralPath $path -PathType Container) -and ($null -ne $original_basename)) { - $path = Join-Path -Path $path -ChildPath $original_basename -} - -$result = @{ - changed = $false -} - -# Used to delete symlinks as powershell cannot delete broken symlinks -$symlink_util = @" -using System; -using System.ComponentModel; -using System.Runtime.InteropServices; - -namespace Ansible.Command { - public class SymLinkHelper { - [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] - public static extern bool DeleteFileW(string lpFileName); - - [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] - public static extern bool RemoveDirectoryW(string lpPathName); - - public static void DeleteDirectory(string path) { - if (!RemoveDirectoryW(path)) - throw new Exception(String.Format("RemoveDirectoryW({0}) failed: {1}", path, new Win32Exception(Marshal.GetLastWin32Error()).Message)); - } - - public static void DeleteFile(string path) { - if (!DeleteFileW(path)) - throw new Exception(String.Format("DeleteFileW({0}) failed: {1}", path, new Win32Exception(Marshal.GetLastWin32Error()).Message)); - } - } -} -"@ -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $symlink_util -$env:TMP = $original_tmp - -# Used to delete directories and files with logic on handling symbolic links -function Remove-File($file, $checkmode) { - try { - if ($file.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { - # Bug with powershell, if you try and delete a symbolic link that is pointing - # to an invalid path it will fail, using Win32 API to do this instead - if ($file.PSIsContainer) { - if (-not $checkmode) { - [Ansible.Command.SymLinkHelper]::DeleteDirectory($file.FullName) - } - } else { - if (-not $checkmode) { - [Ansible.Command.SymlinkHelper]::DeleteFile($file.FullName) - } - } - } elseif ($file.PSIsContainer) { - Remove-Directory -directory $file -checkmode $checkmode - } else { - Remove-Item -LiteralPath $file.FullName -Force -WhatIf:$checkmode - } - } catch [Exception] { - Fail-Json $result "Failed to delete $($file.FullName): $($_.Exception.Message)" - } -} - -function Remove-Directory($directory, $checkmode) { - foreach ($file in Get-ChildItem -LiteralPath $directory.FullName) { - Remove-File -file $file -checkmode $checkmode - } - Remove-Item -LiteralPath $directory.FullName -Force -Recurse -WhatIf:$checkmode -} - - -if ($state -eq "touch") { - if (Test-Path -LiteralPath $path) { - if (-not $check_mode) { - (Get-ChildItem -LiteralPath $path).LastWriteTime = Get-Date - } - $result.changed = $true - } else { - Write-Output $null | Out-File -LiteralPath $path -Encoding ASCII -WhatIf:$check_mode - $result.changed = $true - } -} - -if (Test-Path -LiteralPath $path) { - $fileinfo = Get-Item -LiteralPath $path -Force - if ($state -eq "absent") { - Remove-File -file $fileinfo -checkmode $check_mode - $result.changed = $true - } else { - if ($state -eq "directory" -and -not $fileinfo.PsIsContainer) { - Fail-Json $result "path $path is not a directory" - } - - if ($state -eq "file" -and $fileinfo.PsIsContainer) { - Fail-Json $result "path $path is not a file" - } - } - -} else { - - # If state is not supplied, test the $path to see if it looks like - # a file or a folder and set state to file or folder - if ($null -eq $state) { - $basename = Split-Path -Path $path -Leaf - if ($basename.length -gt 0) { - $state = "file" - } else { - $state = "directory" - } - } - - if ($state -eq "directory") { - try { - New-Item -Path $path -ItemType Directory -WhatIf:$check_mode | Out-Null - } catch { - if ($_.CategoryInfo.Category -eq "ResourceExists") { - $fileinfo = Get-Item -LiteralPath $_.CategoryInfo.TargetName - if ($state -eq "directory" -and -not $fileinfo.PsIsContainer) { - Fail-Json $result "path $path is not a directory" - } - } else { - Fail-Json $result $_.Exception.Message - } - } - $result.changed = $true - } elseif ($state -eq "file") { - Fail-Json $result "path $path will not be created" - } - -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_file.py b/lib/ansible/modules/windows/win_file.py deleted file mode 100644 index 28149579cd..0000000000 --- a/lib/ansible/modules/windows/win_file.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) <figs@unity.demon.co.uk> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_file -version_added: "1.9.2" -short_description: Creates, touches or removes files or directories -description: - - Creates (empty) files, updates file modification stamps of existing files, - and can create or remove directories. - - Unlike M(file), does not modify ownership, permissions or manipulate links. - - For non-Windows targets, use the M(file) module instead. -options: - path: - description: - - Path to the file being managed. - required: yes - type: path - aliases: [ dest, name ] - state: - description: - - If C(directory), all immediate subdirectories will be created if they - do not exist. - - If C(file), the file will NOT be created if it does not exist, see the M(copy) - or M(template) module if you want that behavior. - - If C(absent), directories will be recursively deleted, and files will be removed. - - If C(touch), an empty file will be created if the C(path) does not - exist, while an existing file or directory will receive updated file access and - modification times (similar to the way C(touch) works from the command line). - type: str - choices: [ absent, directory, file, touch ] -seealso: -- module: file -- module: win_acl -- module: win_acl_inheritance -- module: win_owner -- module: win_stat -author: -- Jon Hawkesworth (@jhawkesworth) -''' - -EXAMPLES = r''' -- name: Touch a file (creates if not present, updates modification time if present) - win_file: - path: C:\Temp\foo.conf - state: touch - -- name: Remove a file, if present - win_file: - path: C:\Temp\foo.conf - state: absent - -- name: Create directory structure - win_file: - path: C:\Temp\folder\subfolder - state: directory - -- name: Remove directory structure - win_file: - path: C:\Temp - state: absent -''' diff --git a/lib/ansible/modules/windows/win_find.ps1 b/lib/ansible/modules/windows/win_find.ps1 deleted file mode 100644 index bc57c5ff5d..0000000000 --- a/lib/ansible/modules/windows/win_find.ps1 +++ /dev/null @@ -1,416 +0,0 @@ -#!powershell - -# Copyright: (c) 2016, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.LinkUtil - -$spec = @{ - options = @{ - paths = @{ type = "list"; elements = "str"; required = $true } - age = @{ type = "str" } - age_stamp = @{ type = "str"; default = "mtime"; choices = "mtime", "ctime", "atime" } - file_type = @{ type = "str"; default = "file"; choices = "file", "directory" } - follow = @{ type = "bool"; default = $false } - hidden = @{ type = "bool"; default = $false } - patterns = @{ type = "list"; elements = "str"; aliases = "regex", "regexp" } - recurse = @{ type = "bool"; default = $false } - size = @{ type = "str" } - use_regex = @{ type = "bool"; default = $false } - get_checksum = @{ type = "bool"; default = $true } - checksum_algorithm = @{ type = "str"; default = "sha1"; choices = "md5", "sha1", "sha256", "sha384", "sha512" } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$paths = $module.Params.paths -$age = $module.Params.age -$age_stamp = $module.Params.age_stamp -$file_type = $module.Params.file_type -$follow = $module.Params.follow -$hidden = $module.Params.hidden -$patterns = $module.Params.patterns -$recurse = $module.Params.recurse -$size = $module.Params.size -$use_regex = $module.Params.use_regex -$get_checksum = $module.Params.get_checksum -$checksum_algorithm = $module.Params.checksum_algorithm - -$module.Result.examined = 0 -$module.Result.files = @() -$module.Result.matched = 0 - -Load-LinkUtils - -Function Assert-Age { - Param ( - [System.IO.FileSystemInfo]$File, - [System.Int64]$Age, - [System.String]$AgeStamp - ) - - $actual_age = switch ($AgeStamp) { - mtime { $File.LastWriteTime.Ticks } - ctime { $File.CreationTime.Ticks } - atime { $File.LastAccessTime.Ticks } - } - - if ($Age -ge 0) { - return $Age -ge $actual_age - } else { - return ($Age * -1) -le $actual_age - } -} - -Function Assert-FileType { - Param ( - [System.IO.FileSystemInfo]$File, - [System.String]$FileType - ) - - $is_dir = $File.Attributes.HasFlag([System.IO.FileAttributes]::Directory) - return ($FileType -eq 'directory' -and $is_dir) -or ($FileType -eq 'file' -and -not $is_dir) -} - -Function Assert-FileHidden { - Param ( - [System.IO.FileSystemInfo]$File, - [Switch]$IsHidden - ) - - $file_is_hidden = $File.Attributes.HasFlag([System.IO.FileAttributes]::Hidden) - return $IsHidden.IsPresent -eq $file_is_hidden -} - - -Function Assert-FileNamePattern { - Param ( - [System.IO.FileSystemInfo]$File, - [System.String[]]$Patterns, - [Switch]$UseRegex - ) - - $valid_match = $false - foreach ($pattern in $Patterns) { - if ($UseRegex) { - if ($File.Name -match $pattern) { - $valid_match = $true - break - } - } else { - if ($File.Name -like $pattern) { - $valid_match = $true - break - } - } - } - return $valid_match -} - -Function Assert-FileSize { - Param ( - [System.IO.FileSystemInfo]$File, - [System.Int64]$Size - ) - - if ($Size -ge 0) { - return $File.Length -ge $Size - } else { - return $File.Length -le ($Size * -1) - } -} - -Function Get-FileChecksum { - Param ( - [System.String]$Path, - [System.String]$Algorithm - ) - - $sp = switch ($algorithm) { - 'md5' { New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider } - 'sha1' { New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider } - 'sha256' { New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider } - 'sha384' { New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider } - 'sha512' { New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider } - } - - $fp = [System.IO.File]::Open($Path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) - try { - $hash = [System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower() - } finally { - $fp.Dispose() - } - - return $hash -} - -Function Search-Path { - [CmdletBinding()] - Param ( - [Parameter(Mandatory=$true)] - [System.String] - $Path, - - [Parameter(Mandatory=$true)] - [AllowEmptyCollection()] - [System.Collections.Generic.HashSet`1[System.String]] - $CheckedPaths, - - [Parameter(Mandatory=$true)] - [Object] - $Module, - - [System.Int64] - $Age, - - [System.String] - $AgeStamp, - - [System.String] - $FileType, - - [Switch] - $Follow, - - [Switch] - $GetChecksum, - - [Switch] - $IsHidden, - - [System.String[]] - $Patterns, - - [Switch] - $Recurse, - - [System.Int64] - $Size, - - [Switch] - $UseRegex - ) - - $dir_obj = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $Path - if ([Int32]$dir_obj.Attributes -eq -1) { - $Module.Warn("Argument path '$Path' does not exist, skipping") - return - } elseif (-not $dir_obj.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) { - $Module.Warn("Argument path '$Path' is a file not a directory, skipping") - return - } - - $dir_files = @() - try { - $dir_files = $dir_obj.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::TopDirectoryOnly) - } catch [System.IO.DirectoryNotFoundException] { # Broken ReparsePoint/Symlink, cannot enumerate - } catch [System.UnauthorizedAccessException] {} # No ListDirectory permissions, Get-ChildItem ignored this - - foreach ($dir_child in $dir_files) { - if ($dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory) -and $Recurse) { - if ($Follow -or -not $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::ReparsePoint)) { - $PSBoundParameters.Remove('Path') > $null - Search-Path -Path $dir_child.FullName @PSBoundParameters - } - } - - # Check to see if we've already encountered this path and skip if we have. - if (-not $CheckedPaths.Add($dir_child.FullName.ToLowerInvariant())) { - continue - } - - $Module.Result.examined++ - - if ($PSBoundParameters.ContainsKey('Age')) { - $age_match = Assert-Age -File $dir_child -Age $Age -AgeStamp $AgeStamp - } else { - $age_match = $true - } - - $file_type_match = Assert-FileType -File $dir_child -FileType $FileType - $hidden_match = Assert-FileHidden -File $dir_child -IsHidden:$IsHidden - - if ($PSBoundParameters.ContainsKey('Patterns')) { - $pattern_match = Assert-FileNamePattern -File $dir_child -Patterns $Patterns -UseRegex:$UseRegex.IsPresent - } else { - $pattern_match = $true - } - - if ($PSBoundParameters.ContainsKey('Size')) { - $size_match = Assert-FileSize -File $dir_child -Size $Size - } else { - $size_match = $true - } - - if (-not ($age_match -and $file_type_match -and $hidden_match -and $pattern_match -and $size_match)) { - continue - } - - # It passed all our filters so add it - $module.Result.matched++ - - # TODO: Make this generic so it can be shared with win_find and win_stat. - $epoch = New-Object -Type System.DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0 - $file_info = @{ - attributes = $dir_child.Attributes.ToString() - checksum = $null - creationtime = (New-TimeSpan -Start $epoch -End $dir_child.CreationTime).TotalSeconds - exists = $true - extension = $null - filename = $dir_child.Name - isarchive = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Archive) - isdir = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory) - ishidden = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Hidden) - isreadonly = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::ReadOnly) - isreg = $false - isshared = $false - lastaccesstime = (New-TimeSpan -Start $epoch -End $dir_child.LastAccessTime).TotalSeconds - lastwritetime = (New-TimeSpan -Start $epoch -End $dir_child.LastWriteTime).TotalSeconds - owner = $null - path = $dir_child.FullName - sharename = $null - size = $null - } - - try { - $file_info.owner = $dir_child.GetAccessControl().Owner - } catch {} # May not have rights to get the Owner, historical behaviour is to ignore. - - if ($dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) { - $share_info = Get-CimInstance -ClassName Win32_Share -Filter "Path='$($dir_child.FullName -replace '\\', '\\')'" - if ($null -ne $share_info) { - $file_info.isshared = $true - $file_info.sharename = $share_info.Name - } - } else { - $file_info.extension = $dir_child.Extension - $file_info.isreg = $true - $file_info.size = $dir_child.Length - - if ($GetChecksum) { - try { - $file_info.checksum = Get-FileChecksum -Path $dir_child.FullName -Algorithm $checksum_algorithm - } catch {} # Just keep the checksum as $null in the case of a failure. - } - } - - # Append the link information if the path is a link - $link_info = @{ - isjunction = $false - islnk = $false - nlink = 1 - lnk_source = $null - lnk_target = $null - hlnk_targets = @() - } - $link_stat = Get-Link -link_path $dir_child.FullName - if ($null -ne $link_stat) { - switch ($link_stat.Type) { - "SymbolicLink" { - $link_info.islnk = $true - $link_info.isreg = $false - $link_info.lnk_source = $link_stat.AbsolutePath - $link_info.lnk_target = $link_stat.TargetPath - break - } - "JunctionPoint" { - $link_info.isjunction = $true - $link_info.isreg = $false - $link_info.lnk_source = $link_stat.AbsolutePath - $link_info.lnk_target = $link_stat.TargetPath - break - } - "HardLink" { - $link_info.nlink = $link_stat.HardTargets.Count - - # remove current path from the targets - $hlnk_targets = $link_info.HardTargets | Where-Object { $_ -ne $dir_child.FullName } - $link_info.hlnk_targets = @($hlnk_targets) - break - } - } - } - foreach ($kv in $link_info.GetEnumerator()) { - $file_info.$($kv.Key) = $kv.Value - } - - # Output the file_info object - $file_info - } -} - -$search_params = @{ - CheckedPaths = [System.Collections.Generic.HashSet`1[System.String]]@() - GetChecksum = $get_checksum - Module = $module - FileType = $file_type - Follow = $follow - IsHidden = $hidden - Recurse = $recurse -} - -if ($null -ne $age) { - $seconds_per_unit = @{'s'=1; 'm'=60; 'h'=3600; 'd'=86400; 'w'=604800} - $seconds_pattern = '^(-?\d+)(s|m|h|d|w)?$' - $match = $age -match $seconds_pattern - if ($Match) { - $specified_seconds = [Int64]$Matches[1] - if ($null -eq $Matches[2]) { - $chosen_unit = 's' - } else { - $chosen_unit = $Matches[2] - } - - $total_seconds = $specified_seconds * ($seconds_per_unit.$chosen_unit) - - if ($total_seconds -ge 0) { - $search_params.Age = (Get-Date).AddSeconds($total_seconds * -1).Ticks - } else { - # Make sure we add the positive value of seconds to current time then make it negative for later comparisons. - $age = (Get-Date).AddSeconds($total_seconds).Ticks - $search_params.Age = $age * -1 - } - $search_params.AgeStamp = $age_stamp - } else { - $module.FailJson("Invalid age pattern specified") - } -} - -if ($null -ne $patterns) { - $search_params.Patterns = $patterns - $search_params.UseRegex = $use_regex -} - -if ($null -ne $size) { - $bytes_per_unit = @{'b'=1; 'k'=1KB; 'm'=1MB; 'g'=1GB;'t'=1TB} - $size_pattern = '^(-?\d+)(b|k|m|g|t)?$' - $match = $size -match $size_pattern - if ($Match) { - $specified_size = [Int64]$Matches[1] - if ($null -eq $Matches[2]) { - $chosen_byte = 'b' - } else { - $chosen_byte = $Matches[2] - } - - $search_params.Size = $specified_size * ($bytes_per_unit.$chosen_byte) - } else { - $module.FailJson("Invalid size pattern specified") - } -} - -$matched_files = foreach ($path in $paths) { - # Ensure we pass in an absolute path. We use the ExecutionContext as this is based on the PSProvider path not the - # process location which can be different. - $abs_path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path) - Search-Path -Path $abs_path @search_params -} - -# Make sure we sort the files in alphabetical order. -$module.Result.files = @() + ($matched_files | Sort-Object -Property {$_.path}) - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_find.py b/lib/ansible/modules/windows/win_find.py deleted file mode 100644 index f506f956f2..0000000000 --- a/lib/ansible/modules/windows/win_find.py +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_find -version_added: "2.3" -short_description: Return a list of files based on specific criteria -description: - - Return a list of files based on specified criteria. - - Multiple criteria are AND'd together. - - For non-Windows targets, use the M(find) module instead. -options: - age: - description: - - Select files or folders whose age is equal to or greater than - the specified time. - - Use a negative age to find files equal to or less than - the specified time. - - You can choose seconds, minutes, hours, days or weeks - by specifying the first letter of an of - those words (e.g., "2s", "10d", 1w"). - type: str - age_stamp: - description: - - Choose the file property against which we compare C(age). - - The default attribute we compare with is the last modification time. - type: str - choices: [ atime, ctime, mtime ] - default: mtime - checksum_algorithm: - description: - - Algorithm to determine the checksum of a file. - - Will throw an error if the host is unable to use specified algorithm. - type: str - choices: [ md5, sha1, sha256, sha384, sha512 ] - default: sha1 - file_type: - description: Type of file to search for. - type: str - choices: [ directory, file ] - default: file - follow: - description: - - Set this to C(yes) to follow symlinks in the path. - - This needs to be used in conjunction with C(recurse). - type: bool - default: no - get_checksum: - description: - - Whether to return a checksum of the file in the return info (default sha1), - use C(checksum_algorithm) to change from the default. - type: bool - default: yes - hidden: - description: Set this to include hidden files or folders. - type: bool - default: no - paths: - description: - - List of paths of directories to search for files or folders in. - - This can be supplied as a single path or a list of paths. - type: list - required: yes - patterns: - description: - - One or more (powershell or regex) patterns to compare filenames with. - - The type of pattern matching is controlled by C(use_regex) option. - - The patterns restrict the list of files or folders to be returned based on the filenames. - - For a file to be matched it only has to match with one pattern in a list provided. - type: list - aliases: [ "regex", "regexp" ] - recurse: - description: - - Will recursively descend into the directory looking for files or folders. - type: bool - default: no - size: - description: - - Select files or folders whose size is equal to or greater than the specified size. - - Use a negative value to find files equal to or less than the specified size. - - You can specify the size with a suffix of the byte type i.e. kilo = k, mega = m... - - Size is not evaluated for symbolic links. - type: str - use_regex: - description: - - Will set patterns to run as a regex check if set to C(yes). - type: bool - default: no -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Find files in path - win_find: - paths: D:\Temp - -- name: Find hidden files in path - win_find: - paths: D:\Temp - hidden: yes - -- name: Find files in multiple paths - win_find: - paths: - - C:\Temp - - D:\Temp - -- name: Find files in directory while searching recursively - win_find: - paths: D:\Temp - recurse: yes - -- name: Find files in directory while following symlinks - win_find: - paths: D:\Temp - recurse: yes - follow: yes - -- name: Find files with .log and .out extension using powershell wildcards - win_find: - paths: D:\Temp - patterns: [ '*.log', '*.out' ] - -- name: Find files in path based on regex pattern - win_find: - paths: D:\Temp - patterns: out_\d{8}-\d{6}.log - -- name: Find files older than 1 day - win_find: - paths: D:\Temp - age: 86400 - -- name: Find files older than 1 day based on create time - win_find: - paths: D:\Temp - age: 86400 - age_stamp: ctime - -- name: Find files older than 1 day with unit syntax - win_find: - paths: D:\Temp - age: 1d - -- name: Find files newer than 1 hour - win_find: - paths: D:\Temp - age: -3600 - -- name: Find files newer than 1 hour with unit syntax - win_find: - paths: D:\Temp - age: -1h - -- name: Find files larger than 1MB - win_find: - paths: D:\Temp - size: 1048576 - -- name: Find files larger than 1GB with unit syntax - win_find: - paths: D:\Temp - size: 1g - -- name: Find files smaller than 1MB - win_find: - paths: D:\Temp - size: -1048576 - -- name: Find files smaller than 1GB with unit syntax - win_find: - paths: D:\Temp - size: -1g - -- name: Find folders/symlinks in multiple paths - win_find: - paths: - - C:\Temp - - D:\Temp - file_type: directory - -- name: Find files and return SHA256 checksum of files found - win_find: - paths: C:\Temp - get_checksum: yes - checksum_algorithm: sha256 - -- name: Find files and do not return the checksum - win_find: - paths: C:\Temp - get_checksum: no -''' - -RETURN = r''' -examined: - description: The number of files/folders that was checked. - returned: always - type: int - sample: 10 -matched: - description: The number of files/folders that match the criteria. - returned: always - type: int - sample: 2 -files: - description: Information on the files/folders that match the criteria returned as a list of dictionary elements - for each file matched. The entries are sorted by the path value alphabetically. - returned: success - type: complex - contains: - attributes: - description: attributes of the file at path in raw form. - returned: success, path exists - type: str - sample: "Archive, Hidden" - checksum: - description: The checksum of a file based on checksum_algorithm specified. - returned: success, path exists, path is a file, get_checksum == True - type: str - sample: 09cb79e8fc7453c84a07f644e441fd81623b7f98 - creationtime: - description: The create time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - exists: - description: Whether the file exists, will always be true for M(win_find). - returned: success, path exists - type: bool - sample: true - extension: - description: The extension of the file at path. - returned: success, path exists, path is a file - type: str - sample: ".ps1" - filename: - description: The name of the file. - returned: success, path exists - type: str - sample: temp - hlnk_targets: - description: List of other files pointing to the same file (hard links), excludes the current file. - returned: success, path exists - type: list - sample: - - C:\temp\file.txt - - C:\Windows\update.log - isarchive: - description: If the path is ready for archiving or not. - returned: success, path exists - type: bool - sample: true - isdir: - description: If the path is a directory or not. - returned: success, path exists - type: bool - sample: true - ishidden: - description: If the path is hidden or not. - returned: success, path exists - type: bool - sample: true - isjunction: - description: If the path is a junction point. - returned: success, path exists - type: bool - sample: true - islnk: - description: If the path is a symbolic link. - returned: success, path exists - type: bool - sample: true - isreadonly: - description: If the path is read only or not. - returned: success, path exists - type: bool - sample: true - isreg: - description: If the path is a regular file or not. - returned: success, path exists - type: bool - sample: true - isshared: - description: If the path is shared or not. - returned: success, path exists - type: bool - sample: true - lastaccesstime: - description: The last access time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - lastwritetime: - description: The last modification time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - lnk_source: - description: The target of the symlink normalized for the remote filesystem. - returned: success, path exists, path is a symbolic link or junction point - type: str - sample: C:\temp - lnk_target: - description: The target of the symlink. Note that relative paths remain relative, will return null if not a link. - returned: success, path exists, path is a symbolic link or junction point - type: str - sample: temp - nlink: - description: Number of links to the file (hard links) - returned: success, path exists - type: int - sample: 1 - owner: - description: The owner of the file. - returned: success, path exists - type: str - sample: BUILTIN\Administrators - path: - description: The full absolute path to the file. - returned: success, path exists - type: str - sample: BUILTIN\Administrators - sharename: - description: The name of share if folder is shared. - returned: success, path exists, path is a directory and isshared == True - type: str - sample: file-share - size: - description: The size in bytes of the file. - returned: success, path exists, path is a file - type: int - sample: 1024 -''' diff --git a/lib/ansible/modules/windows/win_get_url.ps1 b/lib/ansible/modules/windows/win_get_url.ps1 deleted file mode 100644 index a4c6e13d32..0000000000 --- a/lib/ansible/modules/windows/win_get_url.ps1 +++ /dev/null @@ -1,277 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Paul Durivage <paul.durivage@rackspace.com> -# Copyright: (c) 2015, Tal Auslander <tal@cloudshare.com> -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# Copyright: (c) 2019, Viktor Utkin <viktor_utkin@epam.com> -# Copyright: (c) 2019, Uladzimir Klybik <uladzimir_klybik@epam.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.FileUtil -#Requires -Module Ansible.ModuleUtils.WebRequest - -$spec = @{ - options = @{ - url = @{ type="str"; required=$true } - dest = @{ type='path'; required=$true } - force = @{ type='bool'; default=$true } - checksum = @{ type='str' } - checksum_algorithm = @{ type='str'; default='sha1'; choices = @("md5", "sha1", "sha256", "sha384", "sha512") } - checksum_url = @{ type='str' } - - # Defined for the alias backwards compatibility, remove once aliases are removed - url_username = @{ - aliases = @("user", "username") - deprecated_aliases = @( - @{ name = "user"; version = "2.14" }, - @{ name = "username"; version = "2.14" } - ) - } - url_password = @{ - aliases = @("password") - deprecated_aliases = @( - @{ name = "password"; version = "2.14" } - ) - } - } - mutually_exclusive = @( - ,@('checksum', 'checksum_url') - ) - supports_check_mode = $true -} -$spec = Merge-WebRequestSpec -ModuleSpec $spec - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$url = $module.Params.url -$dest = $module.Params.dest -$force = $module.Params.force -$checksum = $module.Params.checksum -$checksum_algorithm = $module.Params.checksum_algorithm -$checksum_url = $module.Params.checksum_url - -$module.Result.elapsed = 0 -$module.Result.url = $url - -Function Get-ChecksumFromUri { - param( - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module, - [Parameter(Mandatory=$true)][Uri]$Uri, - [Uri]$SourceUri - ) - - $script = { - param($Response, $Stream) - - $read_stream = New-Object -TypeName System.IO.StreamReader -ArgumentList $Stream - $web_checksum = $read_stream.ReadToEnd() - $basename = (Split-Path -Path $SourceUri.LocalPath -Leaf) - $basename = [regex]::Escape($basename) - $web_checksum_str = $web_checksum -split '\r?\n' | Select-String -Pattern $("\s+\.?\/?\\?" + $basename + "\s*$") - if (-not $web_checksum_str) { - $Module.FailJson("Checksum record not found for file name '$basename' in file from url: '$Uri'") - } - - $web_checksum_str_splitted = $web_checksum_str[0].ToString().split(" ", 2) - $hash_from_file = $web_checksum_str_splitted[0].Trim() - # Remove any non-alphanumeric characters - $hash_from_file = $hash_from_file -replace '\W+', '' - - Write-Output -InputObject $hash_from_file - } - $web_request = Get-AnsibleWebRequest -Uri $Uri -Module $Module - - try { - Invoke-WithWebRequest -Module $Module -Request $web_request -Script $script - } catch { - $Module.FailJson("Error when getting the remote checksum from '$Uri'. $($_.Exception.Message)", $_) - } -} - -Function Compare-ModifiedFile { - <# - .SYNOPSIS - Compares the remote URI resource against the local Dest resource. Will - return true if the LastWriteTime/LastModificationDate of the remote is - newer than the local resource date. - #> - param( - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module, - [Parameter(Mandatory=$true)][Uri]$Uri, - [Parameter(Mandatory=$true)][String]$Dest - ) - - $dest_last_mod = (Get-AnsibleItem -Path $Dest).LastWriteTimeUtc - - # If the URI is a file we don't need to go through the whole WebRequest - if ($Uri.IsFile) { - $src_last_mod = (Get-AnsibleItem -Path $Uri.AbsolutePath).LastWriteTimeUtc - } else { - $web_request = Get-AnsibleWebRequest -Uri $Uri -Module $Module - $web_request.Method = switch ($web_request.GetType().Name) { - FtpWebRequest { [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp } - HttpWebRequest { [System.Net.WebRequestMethods+Http]::Head } - } - $script = { param($Response, $Stream); $Response.LastModified } - - try { - $src_last_mod = Invoke-WithWebRequest -Module $Module -Request $web_request -Script $script - } catch { - $Module.FailJson("Error when requesting 'Last-Modified' date from '$Uri'. $($_.Exception.Message)", $_) - } - } - - # Return $true if the Uri LastModification date is newer than the Dest LastModification date - ((Get-Date -Date $src_last_mod).ToUniversalTime() -gt $dest_last_mod) -} - -Function Get-Checksum { - param( - [Parameter(Mandatory=$true)][String]$Path, - [String]$Algorithm = "sha1" - ) - - switch ($Algorithm) { - 'md5' { $sp = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider } - 'sha1' { $sp = New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider } - 'sha256' { $sp = New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider } - 'sha384' { $sp = New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider } - 'sha512' { $sp = New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider } - } - - $fs = [System.IO.File]::Open($Path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read, - [System.IO.FileShare]::ReadWrite) - try { - $hash = [System.BitConverter]::ToString($sp.ComputeHash($fs)).Replace("-", "").ToLower() - } finally { - $fs.Dispose() - } - return $hash -} - -Function Invoke-DownloadFile { - param( - [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module, - [Parameter(Mandatory=$true)][Uri]$Uri, - [Parameter(Mandatory=$true)][String]$Dest, - [String]$Checksum, - [String]$ChecksumAlgorithm - ) - - # Check $dest parent folder exists before attempting download, which avoids unhelpful generic error message. - $dest_parent = Split-Path -LiteralPath $Dest - if (-not (Test-Path -LiteralPath $dest_parent -PathType Container)) { - $module.FailJson("The path '$dest_parent' does not exist for destination '$Dest', or is not visible to the current user. Ensure download destination folder exists (perhaps using win_file state=directory) before win_get_url runs.") - } - - $download_script = { - param($Response, $Stream) - - # Download the file to a temporary directory so we can compare it - $tmp_dest = Join-Path -Path $Module.Tmpdir -ChildPath ([System.IO.Path]::GetRandomFileName()) - $fs = [System.IO.File]::Create($tmp_dest) - try { - $Stream.CopyTo($fs) - $fs.Flush() - } finally { - $fs.Dispose() - } - $tmp_checksum = Get-Checksum -Path $tmp_dest -Algorithm $ChecksumAlgorithm - $Module.Result.checksum_src = $tmp_checksum - - # If the checksum has been set, verify the checksum of the remote against the input checksum. - if ($Checksum -and $Checksum -ne $tmp_checksum) { - $Module.FailJson(("The checksum for {0} did not match '{1}', it was '{2}'" -f $Uri, $Checksum, $tmp_checksum)) - } - - $download = $true - if (Test-Path -LiteralPath $Dest) { - # Validate the remote checksum against the existing downloaded file - $dest_checksum = Get-Checksum -Path $Dest -Algorithm $ChecksumAlgorithm - - # If we don't need to download anything, save the dest checksum so we don't waste time calculating it - # again at the end of the script - if ($dest_checksum -eq $tmp_checksum) { - $download = $false - $Module.Result.checksum_dest = $dest_checksum - $Module.Result.size = (Get-AnsibleItem -Path $Dest).Length - } - } - - if ($download) { - Copy-Item -LiteralPath $tmp_dest -Destination $Dest -Force -WhatIf:$Module.CheckMode > $null - $Module.Result.changed = $true - } - } - $web_request = Get-AnsibleWebRequest -Uri $Uri -Module $Module - - try { - Invoke-WithWebRequest -Module $Module -Request $web_request -Script $download_script - } catch { - $Module.FailJson("Error downloading '$Uri' to '$Dest': $($_.Exception.Message)", $_) - } -} - -# Use last part of url for dest file name if a directory is supplied for $dest -if (Test-Path -LiteralPath $dest -PathType Container) { - $uri = [System.Uri]$url - $basename = Split-Path -Path $uri.LocalPath -Leaf - if ($uri.LocalPath -and $uri.LocalPath -ne '/' -and $basename) { - $url_basename = Split-Path -Path $uri.LocalPath -Leaf - $dest = Join-Path -Path $dest -ChildPath $url_basename - } else { - $dest = Join-Path -Path $dest -ChildPath $uri.Host - } - - # Ensure we have a string instead of a PS object to avoid serialization issues - $dest = $dest.ToString() -} elseif (([System.IO.Path]::GetFileName($dest)) -eq '') { - # We have a trailing path separator - $module.FailJson("The destination path '$dest' does not exist, or is not visible to the current user. Ensure download destination folder exists (perhaps using win_file state=directory) before win_get_url runs.") -} - -$module.Result.dest = $dest - -if ($checksum) { - $checksum = $checksum.Trim().ToLower() -} -if ($checksum_algorithm) { - $checksum_algorithm = $checksum_algorithm.Trim().ToLower() -} -if ($checksum_url) { - $checksum_url = $checksum_url.Trim() -} - -# Check for case $checksum variable contain url. If yes, get file data from url and replace original value in $checksum -if ($checksum_url) { - $checksum_uri = [System.Uri]$checksum_url - if ($checksum_uri.Scheme -notin @("file", "ftp", "http", "https")) { - $module.FailJson("Unsupported 'checksum_url' value for '$dest': '$checksum_url'") - } - - $checksum = Get-ChecksumFromUri -Module $Module -Uri $checksum_uri -SourceUri $url -} - -if ($force -or -not (Test-Path -LiteralPath $dest)) { - # force=yes or dest does not exist, download the file - # Note: Invoke-DownloadFile will compare the checksums internally if dest exists - Invoke-DownloadFile -Module $module -Uri $url -Dest $dest -Checksum $checksum ` - -ChecksumAlgorithm $checksum_algorithm -} else { - # force=no, we want to check the last modified dates and only download if they don't match - $is_modified = Compare-ModifiedFile -Module $module -Uri $url -Dest $dest - if ($is_modified) { - Invoke-DownloadFile -Module $module -Uri $url -Dest $dest -Checksum $checksum ` - -ChecksumAlgorithm $checksum_algorithm - } -} - -if ((-not $module.Result.ContainsKey("checksum_dest")) -and (Test-Path -LiteralPath $dest)) { - # Calculate the dest file checksum if it hasn't already been done - $module.Result.checksum_dest = Get-Checksum -Path $dest -Algorithm $checksum_algorithm - $module.Result.size = (Get-AnsibleItem -Path $dest).Length -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_get_url.py b/lib/ansible/modules/windows/win_get_url.py deleted file mode 100644 index ef5b5f970b..0000000000 --- a/lib/ansible/modules/windows/win_get_url.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Paul Durivage <paul.durivage@rackspace.com>, and others -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# This is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_get_url -version_added: "1.7" -short_description: Downloads file from HTTP, HTTPS, or FTP to node -description: -- Downloads files from HTTP, HTTPS, or FTP to the remote server. -- The remote server I(must) have direct access to the remote resource. -- For non-Windows targets, use the M(get_url) module instead. -options: - url: - description: - - The full URL of a file to download. - type: str - required: yes - dest: - description: - - The location to save the file at the URL. - - Be sure to include a filename and extension as appropriate. - type: path - required: yes - force: - description: - - If C(yes), will download the file every time and replace the file if the contents change. If C(no), will only - download the file if it does not exist or the remote file has been - modified more recently than the local file. - - This works by sending an http HEAD request to retrieve last modified - time of the requested resource, so for this to work, the remote web - server must support HEAD requests. - type: bool - default: yes - version_added: "2.0" - checksum: - description: - - If a I(checksum) is passed to this parameter, the digest of the - destination file will be calculated after it is downloaded to ensure - its integrity and verify that the transfer completed successfully. - - This option cannot be set with I(checksum_url). - type: str - version_added: "2.8" - checksum_algorithm: - description: - - Specifies the hashing algorithm used when calculating the checksum of - the remote and destination file. - type: str - choices: - - md5 - - sha1 - - sha256 - - sha384 - - sha512 - default: sha1 - version_added: "2.8" - checksum_url: - description: - - Specifies a URL that contains the checksum values for the resource at - I(url). - - Like C(checksum), this is used to verify the integrity of the remote - transfer. - - This option cannot be set with I(checksum). - type: str - version_added: "2.8" - url_username: - description: - - The username to use for authentication. - - The aliases I(user) and I(username) are deprecated and will be removed in - Ansible 2.14. - aliases: - - user - - username - url_password: - description: - - The password for I(url_username). - - The alias I(password) is deprecated and will be removed in Ansible 2.14. - aliases: - - password - proxy_url: - version_added: "2.0" - proxy_username: - version_added: "2.0" - proxy_password: - version_added: "2.0" - headers: - version_added: "2.4" - use_proxy: - version_added: "2.4" - follow_redirects: - version_added: "2.9" - maximum_redirection: - version_added: "2.9" - client_cert: - version_added: "2.9" - client_cert_password: - version_added: "2.9" - method: - description: - - This option is not for use with C(win_get_url) and should be ignored. - version_added: "2.9" -notes: -- If your URL includes an escaped slash character (%2F) this module will convert it to a real slash. - This is a result of the behaviour of the System.Uri class as described in - L(the documentation,https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/schemesettings-element-uri-settings#remarks). -- Since Ansible 2.8, the module will skip reporting a change if the remote - checksum is the same as the local local even when C(force=yes). This is to - better align with M(get_url). -extends_documentation_fragment: -- url_windows -seealso: -- module: get_url -- module: uri -- module: win_uri -author: -- Paul Durivage (@angstwad) -- Takeshi Kuramochi (@tksarah) -''' - -EXAMPLES = r''' -- name: Download earthrise.jpg to specified path - win_get_url: - url: http://www.example.com/earthrise.jpg - dest: C:\Users\RandomUser\earthrise.jpg - -- name: Download earthrise.jpg to specified path only if modified - win_get_url: - url: http://www.example.com/earthrise.jpg - dest: C:\Users\RandomUser\earthrise.jpg - force: no - -- name: Download earthrise.jpg to specified path through a proxy server. - win_get_url: - url: http://www.example.com/earthrise.jpg - dest: C:\Users\RandomUser\earthrise.jpg - proxy_url: http://10.0.0.1:8080 - proxy_username: username - proxy_password: password - -- name: Download file from FTP with authentication - win_get_url: - url: ftp://server/file.txt - dest: '%TEMP%\ftp-file.txt' - url_username: ftp-user - url_password: ftp-password - -- name: Download src with sha256 checksum url - win_get_url: - url: http://www.example.com/earthrise.jpg - dest: C:\temp\earthrise.jpg - checksum_url: http://www.example.com/sha256sum.txt - checksum_algorithm: sha256 - force: True - -- name: Download src with sha256 checksum url - win_get_url: - url: http://www.example.com/earthrise.jpg - dest: C:\temp\earthrise.jpg - checksum: a97e6837f60cec6da4491bab387296bbcd72bdba - checksum_algorithm: sha1 - force: True -''' - -RETURN = r''' -dest: - description: destination file/path - returned: always - type: str - sample: C:\Users\RandomUser\earthrise.jpg -checksum_dest: - description: <algorithm> checksum of the file after the download - returned: success and dest has been downloaded - type: str - sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827 -checksum_src: - description: <algorithm> checksum of the remote resource - returned: force=yes or dest did not exist - type: str - sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827 -elapsed: - description: The elapsed seconds between the start of poll and the end of the module. - returned: always - type: float - sample: 2.1406487 -size: - description: size of the dest file - returned: success - type: int - sample: 1220 -url: - description: requested url - returned: always - type: str - sample: http://www.example.com/earthrise.jpg -msg: - description: Error message, or HTTP status message from web-server - returned: always - type: str - sample: OK -status_code: - description: HTTP status code - returned: always - type: int - sample: 200 -''' diff --git a/lib/ansible/modules/windows/win_group.ps1 b/lib/ansible/modules/windows/win_group.ps1 deleted file mode 100644 index 35697f40fa..0000000000 --- a/lib/ansible/modules/windows/win_group.ps1 +++ /dev/null @@ -1,54 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Chris Hoffman <choffman@chathamfinancial.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" -$description = Get-AnsibleParam -obj $params -name "description" -type "str" - -$result = @{ - changed = $false -} - -$adsi = [ADSI]"WinNT://$env:COMPUTERNAME" -$group = $adsi.Children | Where-Object {$_.SchemaClassName -eq 'group' -and $_.Name -eq $name } - -try { - If ($state -eq "present") { - If (-not $group) { - If (-not $check_mode) { - $group = $adsi.Create("Group", $name) - $group.SetInfo() - } - - $result.changed = $true - } - - If ($null -ne $description) { - IF (-not $group.description -or $group.description -ne $description) { - $group.description = $description - If (-not $check_mode) { - $group.SetInfo() - } - $result.changed = $true - } - } - } - ElseIf ($state -eq "absent" -and $group) { - If (-not $check_mode) { - $adsi.delete("Group", $group.Name.Value) - } - $result.changed = $true - } -} -catch { - Fail-Json $result $_.Exception.Message -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_group.py b/lib/ansible/modules/windows/win_group.py deleted file mode 100644 index 64c4152ec2..0000000000 --- a/lib/ansible/modules/windows/win_group.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Chris Hoffman <choffman@chathamfinancial.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_group -version_added: "1.7" -short_description: Add and remove local groups -description: - - Add and remove local groups. - - For non-Windows targets, please use the M(group) module instead. -options: - name: - description: - - Name of the group. - type: str - required: yes - description: - description: - - Description of the group. - type: str - state: - description: - - Create or remove the group. - type: str - choices: [ absent, present ] - default: present -seealso: -- module: group -- module: win_domain_group -- module: win_group_membership -author: -- Chris Hoffman (@chrishoffman) -''' - -EXAMPLES = r''' -- name: Create a new group - win_group: - name: deploy - description: Deploy Group - state: present - -- name: Remove a group - win_group: - name: deploy - state: absent -''' diff --git a/lib/ansible/modules/windows/win_group_membership.ps1 b/lib/ansible/modules/windows/win_group_membership.ps1 deleted file mode 100644 index 8afbe8b5af..0000000000 --- a/lib/ansible/modules/windows/win_group_membership.ps1 +++ /dev/null @@ -1,190 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -function Test-GroupMember { - <# - .SYNOPSIS - Return SID and consistent account name (DOMAIN\Username) format of desired member. - Also, ensure member can be resolved/exists on the target system by checking its SID. - .NOTES - Returns a hashtable of the same type as returned from Get-GroupMember. - Accepts username (users, groups) and domains in the formats accepted by Convert-ToSID. - #> - param( - [String]$GroupMember - ) - - $parsed_member = @{ - sid = $null - account_name = $null - } - - $sid = Convert-ToSID -account_name $GroupMember - $account_name = Convert-FromSID -sid $sid - - $parsed_member.sid = $sid - $parsed_member.account_name = $account_name - - return $parsed_member -} - -function Get-GroupMember { - <# - .SYNOPSIS - Retrieve group members for a given group, and return in a common format. - .NOTES - Returns an array of hashtables of the same type as returned from Test-GroupMember. - #> - param( - [System.DirectoryServices.DirectoryEntry]$Group - ) - - # instead of using ForEach pipeline we use a standard loop and cast the - # object to the ADSI adapter type before using it to get the SID and path - # this solves an random issue where multiple casts could fail once the raw - # object is invoked at least once - $raw_members = $Group.psbase.Invoke("Members") - $current_members = [System.Collections.ArrayList]@() - foreach ($raw_member in $raw_members) { - $raw_member = [ADSI]$raw_member - $sid_bytes = $raw_member.InvokeGet("objectSID") - $ads_path = $raw_member.InvokeGet("ADsPath") - $member_info = @{ - sid = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $sid_bytes, 0 - adspath = $ads_path - } - $current_members.Add($member_info) > $null - } - - $members = @() - foreach ($current_member in $current_members) { - $parsed_member = @{ - sid = $current_member.sid - account_name = $null - } - - $rootless_adspath = $current_member.adspath.Replace("WinNT://", "") - $split_adspath = $rootless_adspath.Split("/") - - # Ignore lookup on a broken SID, and just return the SID as the account_name - if ($split_adspath.Count -eq 1 -and $split_adspath[0] -like "S-1*") { - $parsed_member.account_name = $split_adspath[0] - } else { - $account_name = Convert-FromSID -sid $current_member.sid - $parsed_member.account_name = $account_name - } - - $members += $parsed_member - } - - return $members -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$members = Get-AnsibleParam -obj $params -name "members" -type "list" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","pure" - -$result = @{ - changed = $false - name = $name -} -if ($state -in @("present", "pure")) { - $result.added = @() -} -if ($state -in @("absent", "pure")) { - $result.removed = @() -} - -$adsi = [ADSI]"WinNT://$env:COMPUTERNAME" -$group = $adsi.Children | Where-Object { $_.SchemaClassName -eq "group" -and $_.Name -eq $name } - -if (!$group) { - Fail-Json -obj $result -message "Could not find local group $name" -} - -$current_members = Get-GroupMember -Group $group -$pure_members = @() - -foreach ($member in $members) { - $group_member = Test-GroupMember -GroupMember $member - if ($state -eq "pure") { - $pure_members += $group_member - } - - $user_in_group = $false - foreach ($current_member in $current_members) { - if ($current_member.sid -eq $group_member.sid) { - $user_in_group = $true - break - } - } - - $member_sid = "WinNT://{0}" -f $group_member.sid - - try { - if ($state -in @("present", "pure") -and !$user_in_group) { - if (!$check_mode) { - $group.Add($member_sid) - $result.added += $group_member.account_name - } - $result.changed = $true - } elseif ($state -eq "absent" -and $user_in_group) { - if (!$check_mode) { - $group.Remove($member_sid) - $result.removed += $group_member.account_name - } - $result.changed = $true - } - } catch { - Fail-Json -obj $result -message $_.Exception.Message - } -} - -if ($state -eq "pure") { - # Perform removals for existing group members not defined in $members - $current_members = Get-GroupMember -Group $group - - foreach ($current_member in $current_members) { - $user_to_remove = $true - foreach ($pure_member in $pure_members) { - if ($pure_member.sid -eq $current_member.sid) { - $user_to_remove = $false - break - } - } - - $member_sid = "WinNT://{0}" -f $current_member.sid - - try { - if ($user_to_remove) { - if (!$check_mode) { - $group.Remove($member_sid) - $result.removed += $current_member.account_name - } - $result.changed = $true - } - } catch { - Fail-Json -obj $result -message $_.Exception.Message - } - } -} - -$final_members = Get-GroupMember -Group $group - -if ($final_members) { - $result.members = [Array]$final_members.account_name -} else { - $result.members = @() -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_group_membership.py b/lib/ansible/modules/windows/win_group_membership.py deleted file mode 100644 index bff6d710b9..0000000000 --- a/lib/ansible/modules/windows/win_group_membership.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_group_membership -version_added: "2.4" -short_description: Manage Windows local group membership -description: - - Allows the addition and removal of local, service and domain users, - and domain groups from a local group. -options: - name: - description: - - Name of the local group to manage membership on. - type: str - required: yes - members: - description: - - A list of members to ensure are present/absent from the group. - - Accepts local users as .\username, and SERVERNAME\username. - - Accepts domain users and groups as DOMAIN\username and username@DOMAIN. - - Accepts service users as NT AUTHORITY\username. - - Accepts all local, domain and service user types as username, - favoring domain lookups when in a domain. - type: list - required: yes - state: - description: - - Desired state of the members in the group. - - C(pure) was added in Ansible 2.8. - - When C(state) is C(pure), only the members specified will exist, - and all other existing members not specified are removed. - type: str - choices: [ absent, present, pure ] - default: present -seealso: -- module: win_domain_group -- module: win_domain_membership -- module: win_group -author: - - Andrew Saraceni (@andrewsaraceni) -''' - -EXAMPLES = r''' -- name: Add a local and domain user to a local group - win_group_membership: - name: Remote Desktop Users - members: - - NewLocalAdmin - - DOMAIN\TestUser - state: present - -- name: Remove a domain group and service user from a local group - win_group_membership: - name: Backup Operators - members: - - DOMAIN\TestGroup - - NT AUTHORITY\SYSTEM - state: absent - -- name: Ensure only a domain user exists in a local group - win_group_membership: - name: Remote Desktop Users - members: - - DOMAIN\TestUser - state: pure -''' - -RETURN = r''' -name: - description: The name of the target local group. - returned: always - type: str - sample: Administrators -added: - description: A list of members added when C(state) is C(present) or - C(pure); this is empty if no members are added. - returned: success and C(state) is C(present) - type: list - sample: ["SERVERNAME\\NewLocalAdmin", "DOMAIN\\TestUser"] -removed: - description: A list of members removed when C(state) is C(absent) or - C(pure); this is empty if no members are removed. - returned: success and C(state) is C(absent) - type: list - sample: ["DOMAIN\\TestGroup", "NT AUTHORITY\\SYSTEM"] -members: - description: A list of all local group members at completion; this is empty - if the group contains no members. - returned: success - type: list - sample: ["DOMAIN\\TestUser", "SERVERNAME\\NewLocalAdmin"] -''' diff --git a/lib/ansible/modules/windows/win_hostname.ps1 b/lib/ansible/modules/windows/win_hostname.ps1 deleted file mode 100644 index 5efe4d6b9e..0000000000 --- a/lib/ansible/modules/windows/win_hostname.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -#!powershell - -# Copyright: (c) 2018, Ripon Banik (@riponbanik) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$current_computer_name = (Get-CimInstance -Class Win32_ComputerSystem).DNSHostname - -$result = @{ - changed = $false - old_name = $current_computer_name - reboot_required = $false -} - -if ($name -ne $current_computer_name) { - Try { - Rename-Computer -NewName $name -Force -WhatIf:$check_mode - } Catch { - Fail-Json -obj $result -message "Failed to rename computer to '$name': $($_.Exception.Message)" - } - $result.changed = $true - $result.reboot_required = $true -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_hostname.py b/lib/ansible/modules/windows/win_hostname.py deleted file mode 100644 index 6602ad9379..0000000000 --- a/lib/ansible/modules/windows/win_hostname.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -# Copyright: (c) 2018, Ripon Banik (@riponbanik) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' -module: win_hostname -version_added: "2.6" -short_description: Manages local Windows computer name -description: -- Manages local Windows computer name. -- A reboot is required for the computer name to take effect. -options: - name: - description: - - The hostname to set for the computer. - type: str - required: true -seealso: -- module: win_dns_client -author: -- Ripon Banik (@riponbanik) -''' - -EXAMPLES = r''' -- name: Change the hostname to sample-hostname - win_hostname: - name: sample-hostname - register: res - -- name: Reboot - win_reboot: - when: res.reboot_required -''' - -RETURN = r''' -old_name: - description: The original hostname that was set before it was changed. - returned: always - type: str - sample: old_hostname -reboot_required: - description: Whether a reboot is required to complete the hostname change. - returned: always - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_optional_feature.ps1 b/lib/ansible/modules/windows/win_optional_feature.ps1 deleted file mode 100644 index 3505f03d32..0000000000 --- a/lib/ansible/modules/windows/win_optional_feature.ps1 +++ /dev/null @@ -1,83 +0,0 @@ -#!powershell - -# Copyright: (c) 2019, Carson Anderson <rcanderson23@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - name = @{ type = "list"; required = $true } - state = @{ type = "str"; default = "present"; choices = @("absent", "present") } - source = @{ type = "str" } - include_parent = @{ type = "bool"; default = $false } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$name = $module.Params.name -$state = $module.Params.state -$source = $module.Params.source -$include_parent = $module.Params.include_parent - -$module.Result.reboot_required = $false - -if (-not (Get-Command -Name Enable-WindowsOptionalFeature -ErrorAction SilentlyContinue)) { - $module.FailJson("This version of Windows does not support the Enable-WindowsOptionalFeature.") -} - -$changed_features = [System.Collections.Generic.List`1[String]]@() -foreach ($feature_name in $name) { - try { - $feature_state_start = Get-WindowsOptionalFeature -Online -FeatureName $feature_name - } catch [System.Runtime.InteropServices.COMException] { - # Server 2012 raises a COMException and doesn't return $null even with -ErrorAction SilentlyContinue - $feature_state_start = $null - } - if (-not $feature_state_start) { - $module.FailJson("Failed to find feature '$feature_name'") - } - - if ($state -eq "present" -and $feature_state_start.State -notlike "Enabled*") { - # Matches for "Enabled" and "EnabledPending" - $changed_features.Add($feature_name) - } elseif ($state -eq "absent" -and $feature_state_start.State -notlike "Disabled*") { - # Matches for Disabled, DisabledPending, and DisabledWithPayloadRemoved - $changed_features.Add($feature_name) - } -} - - -if ($state -eq "present" -and $changed_features.Count -gt 0) { - $install_args = @{ - FeatureName = $changed_features - All = $include_parent - } - - if ($source) { - if (-not (Test-Path -LiteralPath $source)) { - $module.FailJson("Path could not be found '$source'") - } - $install_args.Source = $source - } - - if (-not $module.CheckMode) { - $action_result = Enable-WindowsOptionalFeature -Online -NoRestart @install_args - $module.Result.reboot_required = $action_result.RestartNeeded - } - $module.Result.changed = $true -} elseif ($state -eq "absent" -and $changed_features.Count -gt 0) { - $remove_args = @{ - FeatureName = $changed_features - } - - if (-not $module.CheckMode) { - $action_result = Disable-WindowsOptionalFeature -Online -NoRestart @remove_args - $module.Result.reboot_required = $action_result.RestartNeeded - } - $module.Result.changed = $true -} -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_optional_feature.py b/lib/ansible/modules/windows/win_optional_feature.py deleted file mode 100644 index b26188e1d8..0000000000 --- a/lib/ansible/modules/windows/win_optional_feature.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Carson Anderson <rcanderson23@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_optional_feature -version_added: "2.8" -short_description: Manage optional Windows features -description: - - Install or uninstall optional Windows features on non-Server Windows. - - This module uses the C(Enable-WindowsOptionalFeature) and C(Disable-WindowsOptionalFeature) cmdlets. -options: - name: - description: - - The name(s) of the feature to install. - - This relates to C(FeatureName) in the Powershell cmdlet. - - To list all available features use the PowerShell command C(Get-WindowsOptionalFeature). - type: list - required: yes - state: - description: - - Whether to ensure the feature is absent or present on the system. - type: str - choices: [ absent, present ] - default: present - include_parent: - description: - - Whether to enable the parent feature and the parent's dependencies. - type: bool - default: no - source: - description: - - Specify a source to install the feature from. - - Can either be C({driveletter}:\sources\sxs) or C(\\{IP}\share\sources\sxs). - type: str -seealso: -- module: win_chocolatey -- module: win_feature -- module: win_package -author: - - Carson Anderson (@rcanderson23) -''' - -EXAMPLES = r''' -- name: Install .Net 3.5 - win_optional_feature: - name: NetFx3 - state: present - -- name: Install .Net 3.5 from source - win_optional_feature: - name: NetFx3 - source: \\share01\win10\sources\sxs - state: present - -- name: Install Microsoft Subsystem for Linux - win_optional_feature: - name: Microsoft-Windows-Subsystem-Linux - state: present - register: wsl_status - -- name: Reboot if installing Linux Subsytem as feature requires it - win_reboot: - when: wsl_status.reboot_required - -- name: Install multiple features in one task - win_optional_feature: - name: - - NetFx3 - - Microsoft-Windows-Subsystem-Linux - state: present -''' - -RETURN = r''' -reboot_required: - description: True when the target server requires a reboot to complete updates - returned: success - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_owner.ps1 b/lib/ansible/modules/windows/win_owner.ps1 deleted file mode 100644 index a023d27ba0..0000000000 --- a/lib/ansible/modules/windows/win_owner.ps1 +++ /dev/null @@ -1,60 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$result = @{ - changed = $false -} - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true -$recurse = Get-AnsibleParam -obj $params -name "recurse" -type "bool" -default $false -resultobj $result - -If (-Not (Test-Path -LiteralPath $path)) { - Fail-Json $result "$path file or directory does not exist on the host" -} - -# Test that the user/group is resolvable on the local machine -$sid = Convert-ToSID -account_name $user -if (!$sid) { - Fail-Json $result "$user is not a valid user or group on the host machine or domain" -} - -Try { - $objUser = New-Object System.Security.Principal.SecurityIdentifier($sid) - - $file = Get-Item -LiteralPath $path - $acl = Get-Acl -LiteralPath $file.FullName - - If ($acl.getOwner([System.Security.Principal.SecurityIdentifier]) -ne $objUser) { - $acl.setOwner($objUser) - Set-Acl -LiteralPath $file.FullName -AclObject $acl -WhatIf:$check_mode - $result.changed = $true - } - - If ($recurse -and $file -is [System.IO.DirectoryInfo]) { - # Get-ChildItem falls flat on pre PSv5 when dealing with complex path chars - $files = $file.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::AllDirectories) - ForEach($file in $files){ - $acl = Get-Acl -LiteralPath $file.FullName - - If ($acl.getOwner([System.Security.Principal.SecurityIdentifier]) -ne $objUser) { - $acl.setOwner($objUser) - Set-Acl -LiteralPath $file.FullName -AclObject $acl -WhatIf:$check_mode - $result.changed = $true - } - } - } -} -Catch { - Fail-Json $result "an error occurred when attempting to change owner on $path for $($user): $($_.Exception.Message)" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_owner.py b/lib/ansible/modules/windows/win_owner.py deleted file mode 100644 index bf4fd27cf3..0000000000 --- a/lib/ansible/modules/windows/win_owner.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_owner -version_added: "2.1" -short_description: Set owner -description: - - Set owner of files or directories. -options: - path: - description: - - Path to be used for changing owner. - type: path - required: yes - user: - description: - - Name to be used for changing owner. - type: str - required: yes - recurse: - description: - - Indicates if the owner should be changed recursively. - type: bool - default: no -seealso: -- module: win_acl -- module: win_file -- module: win_stat -author: -- Hans-Joachim Kliemeck (@h0nIg) -''' - -EXAMPLES = r''' -- name: Change owner of path - win_owner: - path: C:\apache - user: apache - recurse: yes - -- name: Set the owner of root directory - win_owner: - path: C:\apache - user: SYSTEM - recurse: no -''' - -RETURN = r''' - -''' diff --git a/lib/ansible/modules/windows/win_package.ps1 b/lib/ansible/modules/windows/win_package.ps1 deleted file mode 100644 index 318545466f..0000000000 --- a/lib/ansible/modules/windows/win_package.ps1 +++ /dev/null @@ -1,1381 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Trond Hindenes <trond@hindenes.com>, and others -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# AccessToken should be removed once the username/password options are gone -#AnsibleRequires -CSharpUtil Ansible.AccessToken - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.WebRequest - -Function Import-PInvokeCode { - param ( - [Object] - $Module - ) - Add-CSharpType -AnsibleModule $Module -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; -using System.Security.Principal; -using System.Text; - -//AssemblyReference -Type System.Security.Principal.IdentityReference -CLR Core - -namespace Ansible.WinPackage -{ - internal class NativeHelpers - { - [StructLayout(LayoutKind.Sequential)] - public struct PACKAGE_VERSION - { - public UInt16 Revision; - public UInt16 Build; - public UInt16 Minor; - public UInt16 Major; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct PACKAGE_ID - { - public UInt32 reserved; - public MsixArchitecture processorArchitecture; - public PACKAGE_VERSION version; - public string name; - public string publisher; - public string resourceId; - public string publisherId; - } - } - - internal class NativeMethods - { - [DllImport("Ole32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 GetClassFile( - [MarshalAs(UnmanagedType.LPWStr)] string szFilename, - ref Guid pclsid); - - [DllImport("Msi.dll")] - public static extern UInt32 MsiCloseHandle( - IntPtr hAny); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiEnumPatchesExW( - [MarshalAs(UnmanagedType.LPWStr)] string szProductCode, - [MarshalAs(UnmanagedType.LPWStr)] string szUserSid, - InstallContext dwContext, - PatchState dwFilter, - UInt32 dwIndex, - StringBuilder szPatchCode, - StringBuilder szTargetProductCode, - out InstallContext pdwTargetProductContext, - StringBuilder szTargetUserSid, - ref UInt32 pcchTargetUserSid); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiGetPatchInfoExW( - [MarshalAs(UnmanagedType.LPWStr)] string szPatchCode, - [MarshalAs(UnmanagedType.LPWStr)] string szProductCode, - [MarshalAs(UnmanagedType.LPWStr)] string szUserSid, - InstallContext dwContext, - [MarshalAs(UnmanagedType.LPWStr)] string szProperty, - StringBuilder lpValue, - ref UInt32 pcchValue); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiGetPropertyW( - SafeMsiHandle hInstall, - [MarshalAs(UnmanagedType.LPWStr)] string szName, - StringBuilder szValueBuf, - ref UInt32 pcchValueBuf); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiGetSummaryInformationW( - IntPtr hDatabase, - [MarshalAs(UnmanagedType.LPWStr)] string szDatabasePath, - UInt32 uiUpdateCount, - out SafeMsiHandle phSummaryInfo); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiOpenPackageW( - [MarshalAs(UnmanagedType.LPWStr)] string szPackagePath, - out SafeMsiHandle hProduct); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern InstallState MsiQueryProductStateW( - [MarshalAs(UnmanagedType.LPWStr)] string szProduct); - - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiSummaryInfoGetPropertyW( - SafeHandle hSummaryInfo, - UInt32 uiProperty, - out UInt32 puiDataType, - out Int32 piValue, - ref System.Runtime.InteropServices.ComTypes.FILETIME pftValue, - StringBuilder szValueBuf, - ref UInt32 pcchValueBuf); - - [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 PackageFullNameFromId( - NativeHelpers.PACKAGE_ID packageId, - ref UInt32 packageFamilyNameLength, - StringBuilder packageFamilyName); - } - - [Flags] - public enum InstallContext : uint - { - None = 0x00000000, - UserManaged = 0x00000001, - UserUnmanaged = 0x00000002, - Machine = 0x00000004, - AllUserManaged = 0x00000008, - All = UserManaged | UserUnmanaged | Machine, - } - - public enum InstallState : int - { - NotUsed = -7, - BadConfig = -6, - Incomplete = -5, - SourceAbsent = -4, - MoreData = -3, - InvalidArg = -2, - Unknown = -1, - Broken = 0, - Advertised = 1, - Absent = 2, - Local = 3, - Source = 4, - Default = 5, - } - - public enum MsixArchitecture : uint - { - X86 = 0, - Arm = 5, - X64 = 9, - Neutral = 11, - Arm64 = 12, - } - - [Flags] - public enum PatchState : uint - { - Invalid = 0x00000000, - Applied = 0x00000001, - Superseded = 0x00000002, - Obsoleted = 0x00000004, - Registered = 0x00000008, - All = Applied | Superseded | Obsoleted | Registered, - } - - public class SafeMsiHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeMsiHandle() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - UInt32 res = NativeMethods.MsiCloseHandle(handle); - return res == 0; - } - } - - public class PatchInfo - { - public string PatchCode; - public string ProductCode; - public InstallContext Context; - public SecurityIdentifier UserSid; - } - - public class MsixHelper - { - public static string GetPackageFullName(string identity, string version, string publisher, - MsixArchitecture architecture, string resourceId) - { - string[] versionSplit = version.Split(new char[] {'.'}, 4); - NativeHelpers.PACKAGE_ID id = new NativeHelpers.PACKAGE_ID() - { - processorArchitecture = architecture, - version = new NativeHelpers.PACKAGE_VERSION() - { - Revision = Convert.ToUInt16(versionSplit.Length > 3 ? versionSplit[3] : "0"), - Build = Convert.ToUInt16(versionSplit.Length > 2 ? versionSplit[2] : "0"), - Minor = Convert.ToUInt16(versionSplit.Length > 1 ? versionSplit[1] : "0"), - Major = Convert.ToUInt16(versionSplit[0]), - }, - name = identity, - publisher = publisher, - resourceId = resourceId, - }; - - UInt32 fullNameLength = 0; - UInt32 res = NativeMethods.PackageFullNameFromId(id, ref fullNameLength, null); - if (res != 122) // ERROR_INSUFFICIENT_BUFFER - throw new Win32Exception((int)res); - - StringBuilder fullName = new StringBuilder((int)fullNameLength); - res = NativeMethods.PackageFullNameFromId(id, ref fullNameLength, fullName); - if (res != 0) - throw new Win32Exception((int)res); - - return fullName.ToString(); - } - } - - public class MsiHelper - { - public static UInt32 SUMMARY_PID_TEMPLATE = 7; - public static UInt32 SUMMARY_PID_REVNUMBER = 9; - - private static Guid MSI_CLSID = new Guid("000c1084-0000-0000-c000-000000000046"); - private static Guid MSP_CLSID = new Guid("000c1086-0000-0000-c000-000000000046"); - - public static IEnumerable<PatchInfo> EnumPatches(string productCode, string userSid, InstallContext context, - PatchState filter) - { - // PowerShell -> .NET, $null for a string parameter becomes an empty string, make sure we convert back. - productCode = String.IsNullOrEmpty(productCode) ? null : productCode; - userSid = String.IsNullOrEmpty(userSid) ? null : userSid; - - UInt32 idx = 0; - while (true) - { - StringBuilder targetPatchCode = new StringBuilder(39); - StringBuilder targetProductCode = new StringBuilder(39); - InstallContext targetContext; - StringBuilder targetUserSid = new StringBuilder(0); - UInt32 targetUserSidLength = 0; - - UInt32 res = NativeMethods.MsiEnumPatchesExW(productCode, userSid, context, filter, idx, - targetPatchCode, targetProductCode, out targetContext, targetUserSid, ref targetUserSidLength); - - SecurityIdentifier sid = null; - if (res == 0x000000EA) // ERROR_MORE_DATA - { - targetUserSidLength++; - targetUserSid.EnsureCapacity((int)targetUserSidLength); - - res = NativeMethods.MsiEnumPatchesExW(productCode, userSid, context, filter, idx, - targetPatchCode, targetProductCode, out targetContext, targetUserSid, ref targetUserSidLength); - - sid = new SecurityIdentifier(targetUserSid.ToString()); - } - - if (res == 0x00000103) // ERROR_NO_MORE_ITEMS - break; - else if (res != 0) - throw new Win32Exception((int)res); - - yield return new PatchInfo() - { - PatchCode = targetPatchCode.ToString(), - ProductCode = targetProductCode.ToString(), - Context = targetContext, - UserSid = sid, - }; - idx++; - } - } - - public static string GetPatchInfo(string patchCode, string productCode, string userSid, InstallContext context, - string property) - { - // PowerShell -> .NET, $null for a string parameter becomes an empty string, make sure we convert back. - userSid = String.IsNullOrEmpty(userSid) ? null : userSid; - - StringBuilder buffer = new StringBuilder(0); - UInt32 bufferLength = 0; - NativeMethods.MsiGetPatchInfoExW(patchCode, productCode, userSid, context, property, buffer, - ref bufferLength); - - bufferLength++; - buffer.EnsureCapacity((int)bufferLength); - - UInt32 res = NativeMethods.MsiGetPatchInfoExW(patchCode, productCode, userSid, context, property, buffer, - ref bufferLength); - if (res != 0) - throw new Win32Exception((int)res); - - return buffer.ToString(); - } - - public static string GetProperty(SafeMsiHandle productHandle, string property) - { - StringBuilder buffer = new StringBuilder(0); - UInt32 bufferLength = 0; - NativeMethods.MsiGetPropertyW(productHandle, property, buffer, ref bufferLength); - - // Make sure we include the null byte char at the end. - bufferLength += 1; - buffer.EnsureCapacity((int)bufferLength); - - UInt32 res = NativeMethods.MsiGetPropertyW(productHandle, property, buffer, ref bufferLength); - if (res != 0) - throw new Win32Exception((int)res); - - return buffer.ToString(); - } - - public static SafeMsiHandle GetSummaryHandle(string databasePath) - { - SafeMsiHandle summaryInfo = null; - UInt32 res = NativeMethods.MsiGetSummaryInformationW(IntPtr.Zero, databasePath, 0, out summaryInfo); - if (res != 0) - throw new Win32Exception((int)res); - - return summaryInfo; - } - - public static string GetSummaryPropertyString(SafeMsiHandle summaryHandle, UInt32 propertyId) - { - UInt32 dataType = 0; - Int32 intPropValue = 0; - System.Runtime.InteropServices.ComTypes.FILETIME propertyFiletime = - new System.Runtime.InteropServices.ComTypes.FILETIME(); - StringBuilder buffer = new StringBuilder(0); - UInt32 bufferLength = 0; - - NativeMethods.MsiSummaryInfoGetPropertyW(summaryHandle, propertyId, out dataType, out intPropValue, - ref propertyFiletime, buffer, ref bufferLength); - - // Make sure we include the null byte char at the end. - bufferLength += 1; - buffer.EnsureCapacity((int)bufferLength); - - UInt32 res = NativeMethods.MsiSummaryInfoGetPropertyW(summaryHandle, propertyId, out dataType, - out intPropValue, ref propertyFiletime, buffer, ref bufferLength); - if (res != 0) - throw new Win32Exception((int)res); - - return buffer.ToString(); - } - - public static bool IsMsi(string filename) - { - return GetClsid(filename) == MSI_CLSID; - } - - public static bool IsMsp(string filename) - { - return GetClsid(filename) == MSP_CLSID; - } - - public static SafeMsiHandle OpenPackage(string packagePath) - { - SafeMsiHandle packageHandle = null; - UInt32 res = NativeMethods.MsiOpenPackageW(packagePath, out packageHandle); - if (res != 0) - throw new Win32Exception((int)res); - - return packageHandle; - } - - public static InstallState QueryProductState(string productCode) - { - return NativeMethods.MsiQueryProductStateW(productCode); - } - - private static Guid GetClsid(string filename) - { - Guid clsid = Guid.Empty; - NativeMethods.GetClassFile(filename, ref clsid); - - return clsid; - } - } -} -'@ -} - -Function Add-SystemReadAce { - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [String] - $Path - ) - - # Don't set the System ACE if the path is a UNC path as the SID won't be valid. - if (([Uri]$Path).IsUnc) { - return - } - - $acl = Get-Acl -LiteralPath $Path - $ace = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList @( - (New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList ('S-1-5-18')), - [System.Security.AccessControl.FileSystemRights]::Read, - [System.Security.AccessControl.AccessControlType]::Allow - ) - $acl.AddAccessRule($ace) - $acl | Set-Acl -LiteralPath $path -} - -Function Copy-ItemWithCredential { - [CmdletBinding(SupportsShouldProcess=$false)] - param ( - [String] - $Path, - - [String] - $Destination, - - [PSCredential] - $Credential - ) - - $filename = Split-Path -Path $Path -Leaf - $targetPath = Join-Path -Path $Destination -ChildPath $filename - - # New-PSDrive with -Credentials seems to have lots of issues, just impersonate a NewCredentials token and copy the - # file locally. NewCredentials will ensure the outbound auth to the UNC path is with the new credentials specified. - - $domain = [NullString]::Value - $username = $Credential.UserName - if ($username.Contains('\')) { - $userSplit = $username.Split('\', 2) - $domain = $userSplit[0] - $username = $userSplit[1] - } - - $impersonated = $false - $token = [Ansible.AccessToken.TokenUtil]::LogonUser( - $username, $domain, $Credential.GetNetworkCredential().Password, - [Ansible.AccessToken.LogonType]::NewCredentials, [Ansible.AccessToken.LogonProvider]::WinNT50 - ) - try { - [Ansible.AccessToken.TokenUtil]::ImpersonateToken($token) - $impersonated = $true - - Copy-Item -LiteralPath $Path -Destination $targetPath - } finally { - if ($impersonated) { - [Ansible.AccessToken.TokenUtil]::RevertToSelf() - } - $token.Dispose() - } - - $targetPath -} - -Function Get-UrlFile { - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [Object] - $Module, - - [Parameter(Mandatory=$true)] - [String] - $Url - ) - - Invoke-WithWebRequest -Module $module -Request (Get-AnsibleWebRequest -Url $Url -Module $module) -Script { - Param ([System.Net.WebResponse]$Response, [System.IO.Stream]$Stream) - - $tempPath = Join-Path -Path $module.Tmpdir -ChildPath $Response.ResponseUri.Segments[-1] - $fs = [System.IO.File]::Create($tempPath) - try { - $Stream.CopyTo($fs) - $fs.Flush() - } finally { - $fs.Dispose() - } - - $tempPath - } -} - -Function Format-PackageStatus { - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [AllowEmptyString()] - [String] - $Id, - - [Parameter(Mandatory=$true)] - [String] - $Provider, - - [Switch] - $Installed, - - [Switch] - $Skip, - - [Switch] - $SkipFileForRemove, - - [Hashtable] - $ExtraInfo = @{} - ) - - @{ - Id = $Id - Installed = $Installed.IsPresent - Provider = $Provider - Skip = $Skip.IsPresent - SkipFileForRemove = $SkipFileForRemove.IsPresent - ExtraInfo = $ExtraInfo - } -} - -Function Get-InstalledStatus { - [CmdletBinding()] - param ( - [String] - $Path, - - [String] - $Id, - - [String] - $Provider, - - [String] - $CreatesPath, - - [String] - $CreatesService, - - [String] - $CreatesVersion - ) - - if ($Path) { - if ($Provider -eq 'auto') { - foreach ($info in $providerInfo.GetEnumerator()) { - if ((&$info.Value.FileSupported -Path $Path)) { - $Provider = $info.Key - break - } - } - } - - $status = &$providerInfo."$Provider".Test -Path $Path -Id $Id - } else { - if ($Provider -eq 'auto') { - $providerList = [String[]]$providerInfo.Keys - } else { - $providerList = @($Provider) - } - - foreach ($name in $providerList) { - $status = &$providerInfo."$name".Test -Id $Id - - # If the package was installed for the provider (or was the last provider available). - if ($status.Installed -or $providerList[-1] -eq $name) { - break - } - } - } - - if ($CreatesPath) { - $exists = Test-Path -LiteralPath $CreatesPath - $status.Installed = $exists - - if ($CreatesVersion) { - if (Test-Path -LiteralPath $CreatesPath -PathType Leaf) { - $versionRaw = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($CreatesPath) - $existingVersion = New-Object -TypeName System.Version -ArgumentList @( - $versionRaw.FileMajorPart, $versionRaw.FileMinorPart, $versionRaw.FileBuildPart, - $versionRaw.FilePrivatePart - ) - $status.Installed = $CreatesVersion -eq $existingVersion - } else { - throw "creates_path must be a file not a directory when creates_version is set" - } - } - } - - if ($CreatesService) { - $serviceInfo = Get-Service -Name $CreatesService -ErrorAction SilentlyContinue - $status.Installed = $null -ne $serviceInfo - } - - Format-PackageStatus @status -} - -Function Invoke-Executable { - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [Object] - $Module, - - [Parameter(Mandatory=$true)] - [String] - $Command, - - [Int32[]] - $ReturnCodes, - - [String] - $LogPath, - - [String] - $WorkingDirectory, - - [String] - $ConsoleOutputEncoding - ) - - $commandArgs = @{ - command = $Command - } - if ($WorkingDirectory) { - $commandArgs.working_directory = $WorkingDirectory - } - if ($ConsoleOutputEncoding) { - $commandArgs.output_encoding_override = $ConsoleOutputEncoding - } - - $result = Run-Command @commandArgs - - $module.Result.rc = $result.rc - if ($ReturnCodes -notcontains $result.rc) { - $module.Result.stdout = $result.stdout - $module.Result.stderr = $result.stderr - if ($LogPath -and (Test-Path -LiteralPath $LogPath)) { - $module.Result.log = (Get-Content -LiteralPath $LogPath | Out-String) - } - - $module.FailJson("unexpected rc from '$($commandArgs.command)': see rc, stdout, and stderr for more details") - } else { - $module.Result.failed = $false - } - - if ($result.rc -eq 3010) { - $module.Result.reboot_required = $true - } -} - -Function Invoke-Msiexec { - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [Object] - $Module, - - [Parameter(Mandatory=$true)] - [String[]] - $Actions, - - [String] - $Arguments, - - [Int32[]] - $ReturnCodes, - - [String] - $LogPath, - - [String] - $WorkingDirectory - ) - - $tempFile = $null - try { - if (-not $LogPath) { - $tempFile = Join-Path -Path $module.Tmpdir -ChildPath "msiexec.log" - $LogPath = $tempFile - } - - $cmd = [System.Collections.Generic.List[String]]@("$env:SystemRoot\System32\msiexec.exe") - $cmd.AddRange([System.Collections.Generic.List[String]]$Actions) - $cmd.AddRange([System.Collections.Generic.List[String]]@( - '/L*V', $LogPath, '/qn', '/norestart' - )) - - $invokeParams = @{ - Module = $Module - Command = (Argv-ToString -arguments $cmd) - ReturnCodes = $ReturnCodes - LogPath = $LogPath - WorkingDirectory = $WorkingDirectory - - # Msiexec is not a console application but in the case of a fatal error it does still send messages back - # over the stdout pipe. These messages are UTF-16 encoded so we override the default UTF-8. - ConsoleOutputEncoding = 'Unicode' - } - if ($Arguments) { - $invokeParams.Command += " $Arguments" - } - Invoke-Executable @invokeParams - } finally { - if ($tempFile -and (Test-Path -LiteralPath $tempFile)) { - Remove-Item -LiteralPath $tempFile -Force - } - } -} - -$providerInfo = [Ordered]@{ - msi = @{ - FileSupported = { - param ([String]$Path) - - [Ansible.WInPackage.MsiHelper]::IsMsi($Path) - } - - Test = { - param ([String]$Path, [String]$Id) - - if ($Path) { - $msiHandle = [Ansible.WinPackage.MsiHelper]::OpenPackage($Path) - try { - $Id = [Ansible.WinPackage.MsiHelper]::GetProperty($msiHandle, 'ProductCode') - } finally { - $msiHandle.Dispose() - } - } - - $installState = [Ansible.WinPackage.MsiHelper]::QueryProductState($Id) - - @{ - Provider = 'msi' - Id = $Id - Installed = $installState -eq [Ansible.WinPackage.InstallState]::Default - SkipFileForRemove = $true - } - } - - Set = { - param ( - [String] - $Arguments, - - [Int32[]] - $ReturnCodes, - - [String] - $Id, - - [String] - $LogPath, - - [Object] - $Module, - - [String] - $Path, - - [String] - $State, - - [String] - $WorkingDirectory - ) - - if ($state -eq 'present') { - $actions = @('/i', $Path) - - # $Module.Tmpdir only gives rights to the current user but msiexec (as SYSTEM) needs access. - Add-SystemReadAce -Path $Path - } else { - $actions = @('/x', $Id) - } - - $invokeParams = @{ - Module = $Module - Actions = $actions - Arguments = $Arguments - ReturnCodes = $ReturnCodes - LogPath = $LogPath - WorkingDirectory = $WorkingDirectory - } - Invoke-Msiexec @invokeParams - } - } - - msix = @{ - FileSupported = { - param ([String]$Path) - - $extension = [System.IO.Path]::GetExtension($Path) - - $extension -in @('.appx', '.appxbundle', '.msix', '.msixbundle') - } - - Test = { - param ([String]$Path, [String]$Id) - - $package = $null - - if ($Path) { - # Cannot find a native way to get the package info from the actual path so we need to inspect the XML - # manually. - $null = Add-Type -AssemblyName System.IO.Compression - $null = Add-Type -AssemblyName System.IO.Compression.FileSystem - - $archive = [System.IO.Compression.ZipFile]::Open($Path, [System.IO.Compression.ZipArchiveMode]::Read, - [System.Text.Encoding]::UTF8) - try { - $manifestEntry = $archive.Entries | Where-Object { - $_.FullName -in @('AppxManifest.xml', 'AppxMetadata/AppxBundleManifest.xml') - } - $manifestStream = New-Object -TypeName System.IO.StreamReader -ArgumentList $manifestEntry.Open() - try { - $manifest = [xml]$manifestStream.ReadToEnd() - } finally { - $manifestStream.Dispose() - } - } finally { - $archive.Dispose() - } - - if ($manifestEntry.Name -eq 'AppxBundleManifest.xml') { - # https://docs.microsoft.com/en-us/uwp/schemas/bundlemanifestschema/element-identity - $name = $manifest.Bundle.Identity.Name - $publisher = $manifest.Bundle.Identity.Publisher - - $Ids = foreach ($p in $manifest.Bundle.Packages.Package) { - $version = $p.Version - - $architecture = 'neutral' - if ($p.HasAttribute('Architecture')) { - $architecture = $p.Architecture - } - - $resourceId = '' - if ($p.HasAttribute('ResourceId')) { - $resourceId = $p.ResourceId - } - - [Ansible.WinPackage.MsixHelper]::GetPackageFullName($name, $version, $publisher, $architecture, - $resourceId) - } - } else { - # https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-identity - $name = $manifest.Package.Identity.Name - $version = $manifest.Package.Identity.Version - $publisher = $manifest.Package.Identity.Publisher - - $architecture = 'neutral' - if ($manifest.Package.Identity.HasAttribute('ProcessorArchitecture')) { - $architecture = $manifest.Package.Identity.ProcessorArchitecture - } - - $resourceId = '' - if ($manifest.Package.Identity.HasAttribute('ResourceId')) { - $resourceId = $manifest.$identityParent.Identity.ResourceId - } - - $Ids = @(,[Ansible.WinPackage.MsixHelper]::GetPackageFullName($name, $version, $publisher, - $architecture, $resourceId) - ) - } - } else { - $package = Get-AppxPackage -Name $Id -ErrorAction SilentlyContinue - $Ids = @($Id) - } - - # In the case when a file is specified or the user has set the full name and not the name, scan again for - # PackageFullName. - if ($null -eq $package) { - $package = Get-AppxPackage | Where-Object { $_.PackageFullName -in $Ids } - } - - # Make sure the Id is set to the PackageFullName so state=absent works. - if ($package) { - $Id = $package.PackageFullName - } - - @{ - Provider = 'msix' - Id = $Id - Installed = $null -ne $package - } - } - - Set = { - param ( - [String] - $Id, - - [Object] - $Module, - - [String] - $Path, - - [String] - $State - ) - $originalProgress = $ProgressPreference - try { - $ProgressPreference = 'SilentlyContinue' - if ($State -eq 'present') { - # Add-AppxPackage does not support a -LiteralPath parameter and it chokes on wildcard characters. - # We need to escape those characters when calling the cmdlet. - Add-AppxPackage -Path ([WildcardPattern]::Escape($Path)) - } else { - Remove-AppxPackage -Package $Id - } - } catch { - # Replicate the same return values as the other providers. - $module.Result.rc = $_.Exception.HResult - $module.Result.stdout = "" - $module.Result.stderr = $_.Exception.Message - - $msg = "unexpected status from $($_.InvocationInfo.InvocationName): see rc and stderr for more details" - $module.FailJson($msg, $_) - } finally { - $ProgressPreference = $originalProgress - } - - # Just set to 0 to align with other providers - $module.Result.rc = 0 - - # It looks like the reboot checks are an insider feature so we can't do a check for that today. - # https://docs.microsoft.com/en-us/windows/msix/packaging-tool/support-restart - } - } - - msp = @{ - FileSupported = { - param ([String]$Path) - - [Ansible.WInPackage.MsiHelper]::IsMsp($Path) - } - - Test = { - param ([String]$Path, [String]$Id) - - $productCodes = [System.Collections.Generic.List[System.String]]@() - if ($Path) { - $summaryInfo = [Ansible.WinPackage.MsiHelper]::GetSummaryHandle($Path) - try { - $productCodesRaw = [Ansible.WinPackage.MsiHelper]::GetSummaryPropertyString( - $summaryInfo, [Ansible.WinPackage.MsiHelper]::SUMMARY_PID_TEMPLATE - ) - - # Filter out product codes that are not installed on the host. - foreach ($code in ($productCodesRaw -split ';')) { - $productState = [Ansible.WinPackage.MsiHelper]::QueryProductState($code) - if ($productState -eq [Ansible.WinPackage.InstallState]::Default) { - $productCodes.Add($code) - } - } - - if ($productCodes.Count -eq 0) { - throw "The specified patch does not apply to any installed MSI packages." - } - - # The first guid in the REVNUMBER is the patch code, the subsequent values are obsoleted patches - # which we don't care about. - $Id = [Ansible.WinPackage.MsiHelper]::GetSummaryPropertyString($summaryInfo, - [Ansible.WinPackage.MsiHelper]::SUMMARY_PID_REVNUMBER).Substring(0, 38) - } finally { - $summaryInfo.Dispose() - } - } else { - foreach ($patch in ([Ansible.WinPackage.MsiHelper]::EnumPatches($null, $null, 'All', 'All'))) { - if ($patch.PatchCode -eq $Id) { - # We append "{guid}:{context}" so the check below checks the proper context, the context - # is then stripped out there. - $ProductCodes.Add("$($patch.ProductCode):$($patch.Context)") - } - } - } - - # Filter the product list even further to only ones that are applied and not obsolete. - $skipCodes = [System.Collections.Generic.List[System.String]]@() - $productCodes = @(@(foreach ($product in $productCodes) { - if ($product.Length -eq 38) { # Guid length with braces is 38 - $contextList = @('UserManaged', 'UserUnmanaged', 'Machine') - } else { - # We already know the context and was appended to the product guid with ';context' - $productInfo = $product.Split(':', 2) - $product = $productInfo[0] - $contextList = @($productInfo[1]) - } - - foreach ($context in $contextList) { - try { - # GetPatchInfo('State') returns a string that is a number of an enum value. - $state = [Ansible.WinPackage.PatchState][UInt32]([Ansible.WinPackage.MsiHelper]::GetPatchInfo( - $Id, $product, $null, $context, 'State' - )) - } catch [System.ComponentModel.Win32Exception] { - if ($_.Exception.NativeErrorCode -in @(0x00000645, 0x0000066F)) { - # ERROR_UNKNOWN_PRODUCT can be raised if the product is not installed in the context - # specified, just try the next one. - # ERROR_UNKNOWN_PATCH can be raised if the patch is not installed but the product is. - continue - } - throw - } - - if ($state -eq [Ansible.WinPackage.PatchState]::Applied) { - # The patch is applied to the product code, output the code for the outer list to capture. - $product - } elseif ($state.ToString() -in @('Obsoleted', 'Superseded')) { - # If the patch is obsoleted or suprseded we cannot install or remove but consider it equal to - # state=absent and present so we skip the set step. - $skipCodes.Add($product) - } - } - }) | Select-Object -Unique) - - @{ - Provider = 'msp' - Id = $Id - Installed = $productCodes.Length -gt 0 - Skip = $skipCodes.Length -eq $productCodes.Length - SkipFileForRemove = $true - ExtraInfo = @{ - ProductCodes = $productCodes - } - } - } - - Set = { - param ( - [String] - $Arguments, - - [Int32[]] - $ReturnCodes, - - [String] - $Id, - - [String] - $LogPath, - - [Object] - $Module, - - [String] - $Path, - - [String] - $State, - - [String] - $WorkingDirectory, - - [String[]] - $ProductCodes - ) - - $tempLink = $null - try { - $actions = @(if ($state -eq 'present') { - # $Module.Tmpdir only gives rights to the current user but msiexec (as SYSTEM) needs access. - Add-SystemReadAce -Path $Path - - # MsiApplyPatchW fails if the path contains a ';', we need to use a temporary symlink instead. - # https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiapplypatchw - if ($Path.Contains(';')) { - $tempLink = Join-Path -Path $env:TEMP -ChildPath "win_package-$([System.IO.Path]::GetRandomFileName()).msp" - $res = Run-Command -command (Argv-ToString -arguments @("cmd.exe", "/c", "mklink", $tempLink, $Path)) - if ($res.rc -ne 0) { - $Module.Result.rc = $res.rc - $Module.Result.stdout = $res.stdout - $Module.Result.stderr = $res.stderr - - $Module.FailJson("Failed to create temporary symlink '$tempLink' -> '$Path' for msiexec patch install as path contains semicolon") - } - $Path = $tempLink - } - - ,@('/update', $Path) - } else { - foreach ($code in $ProductCodes) { - ,@('/uninstall', $Id, '/package', $code) - } - }) - - $invokeParams = @{ - Arguments = $Arguments - Module = $Module - ReturnCodes = $ReturnCodes - LogPath = $LogPath - WorkingDirectory = $WorkingDirectory - } - foreach ($action in $actions) { - Invoke-Msiexec -Actions $action @invokeParams - } - } finally { - if ($tempLink -and (Test-Path -LiteralPath $tempLink)) { - Remove-Item -LiteralPath $tempLink -Force - } - } - } - } - - # Should always be last as the FileSupported is a catch all. - registry = @{ - FileSupported = { $true } - - Test = { - param ([String]$Id) - - $status = @{ - Provider = 'registry' - Id = $Id - Installed = $false - ExtraInfo = @{ - RegistryPath = $null - } - } - - if ($Id) { - :regLoop foreach ($hive in @("HKLM", "HKCU")) { # Search machine wide and user specific. - foreach ($key in @("SOFTWARE", "SOFTWARE\Wow6432Node")) { # Search the 32 and 64-bit locations. - $regPath = "$($hive):\$key\Microsoft\Windows\CurrentVersion\Uninstall\$Id" - if (Test-Path -LiteralPath $regPath) { - $status.Installed = $true - $status.ExtraInfo.RegistryPath = $regPath - break regLoop - } - } - } - } - - $status - } - - Set = { - param ( - [String] - $Arguments, - - [Int32[]] - $ReturnCodes, - - [Object] - $Module, - - [String] - $Path, - - [String] - $State, - - [String] - $WorkingDirectory, - - [String] - $RegistryPath - ) - - $invokeParams = @{ - Module = $Module - ReturnCodes = $ReturnCodes - WorkingDirectory = $WorkingDirectory - } - - if ($Path) { - $invokeParams.Command = Argv-ToString -arguments @($Path) - } else { - $registryProperties = Get-ItemProperty -LiteralPath $RegistryPath - - if ('QuietUninstallString' -in $registryProperties.PSObject.Properties.Name) { - $command = $registryProperties.QuietUninstallString - } elseif ('UninstallString' -in $registryProperties.PSObject.Properties.Name) { - $command = $registryProperties.UninstallString - } else { - $module.FailJson("Failed to find registry uninstall string at registry path '$RegistryPath'") - } - - # If the uninstall string starts with '%', we need to expand the env vars. - if ($command.StartsWith('%') -or $command.StartsWith('"%')) { - $command = [System.Environment]::ExpandEnvironmentVariables($command) - } - - # If the command is not quoted and contains spaces we need to see if it needs to be manually quoted for the executable. - if (-not $command.StartsWith('"') -and $command.Contains(' ')) { - $rawArguments = [System.Collections.Generic.List[String]]@() - - $executable = New-Object -TypeName System.Text.StringBuilder - foreach ($cmd in ([Ansible.Process.ProcessUtil]::ParseCommandLine($command))) { - if ($rawArguments.Count -eq 0) { - # Still haven't found the path, append the arg to the executable path and see if it exists. - $null = $executable.Append($cmd) - $exe = $executable.ToString() - if (Test-Path -LiteralPath $exe -PathType Leaf) { - $rawArguments.Add($exe) - } else { - $null = $executable.Append(" ") # The arg had a space and we need to preserve that. - } - } else { - $rawArguments.Add($cmd) - } - } - - # If we still couldn't find a file just use the command literally and hope WIndows can handle it, - # otherwise recombind the args which will also quote whatever is needed. - if ($rawArguments.Count -gt 0) { - $command = Argv-ToString -arguments $rawArguments - } - } - - $invokeParams.Command = $command - } - - if ($Arguments) { - $invokeParams.Command += " $Arguments" - } - - Invoke-Executable @invokeParams - } - } -} - -$spec = @{ - options = @{ - arguments = @{ type = "raw" } - expected_return_code = @{ type = "list"; elements = "int"; default = @(0, 3010) } - path = @{ type = "str"} - chdir = @{ type = "path" } - product_id = @{ - type = "str" - aliases = @("productid") - deprecated_aliases = @( - @{ name = "productid"; version = "2.14" } - ) - } - state = @{ - type = "str" - default = "present" - choices = "absent", "present" - aliases = @(,"ensure") - deprecated_aliases = @( - ,@{ name = "ensure"; version = "2.14" } - ) - } - username = @{ type = "str"; aliases = @(,"user_name"); removed_in_version = "2.14" } - password = @{ type = "str"; no_log = $true; aliases = @(,"user_password"); removed_in_version = "2.14" } - creates_path = @{ type = "path" } - creates_version = @{ type = "str" } - creates_service = @{ type = "str" } - log_path = @{ type = "path" } - provider = @{ type = "str"; default = "auto"; choices = $providerInfo.Keys + "auto" } - } - required_by = @{ - creates_version = "creates_path" - } - required_if = @( - @("state", "present", @("path")), - @("state", "absent", @("path", "product_id"), $true) - ) - required_together = @(,@("username", "password")) - supports_check_mode = $true -} -$spec = Merge-WebRequestSpec -ModuleSpec $spec - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$arguments = $module.Params.arguments -$expectedReturnCode = $module.Params.expected_return_code -$path = $module.Params.path -$chdir = $module.Params.chdir -$productId = $module.Params.product_id -$state = $module.Params.state -$username = $module.Params.username -$password = $module.Params.password -$createsPath = $module.Params.creates_path -$createsVersion = $module.Params.creates_version -$createsService = $module.Params.creates_service -$logPath = $module.Params.log_path -$provider = $module.Params.provider - -$module.Result.reboot_required = $false - -if ($null -ne $arguments) { - # convert a list to a string and escape the values - if ($arguments -is [array]) { - $arguments = Argv-ToString -arguments $arguments - } -} - -$credential = $null -if ($null -ne $username) { - $secPassword = ConvertTo-SecureString -String $password -AsPlainText -Force - $credential = New-Object -TypeName PSCredential -ArgumentList $username, $secPassword -} - -# This must be set after the module spec so the validate-modules sanity-test can get the arg spec. -Import-PInvokeCode -Module $module - -$pathType = $null -if ($path -and $path.StartsWith('http', [System.StringComparison]::InvariantCultureIgnoreCase)) { - $pathType = 'url' -} elseif ($path -and ($path.StartsWith('\\') -or $path.StartsWith('//') -and $username)) { - $pathType = 'unc' -} - -$tempFile = $null -try { - $getParams = @{ - Id = $productId - Provider = $provider - CreatesPath = $createsPath - CreatesVersion = $createsVersion - CreatesService = $createsService - } - - # If the path is a URL or UNC with credentials and no ID is set then create a temp copy for idempotency checks. - if ($pathType -and -not $Id) { - $tempFile = switch ($pathType) { - url { Get-UrlFile -Module $module -Url $path } - unc { Copy-ItemWithCredential -Path $path -Destination $module.Tmpdir -Credential $credential } - } - $path = $tempFile - $getParams.Path = $path - } elseif ($path -and -not $pathType) { - if (-not (Test-Path -LiteralPath $path)) { - $module.FailJson("the file at the path '$path' cannot be reached") - } - $getParams.Path = $path - } - - $packageStatus = Get-InstalledStatus @getParams - - $changed = -not $packageStatus.Skip -and (($state -eq 'present') -ne $packageStatus.Installed) - $module.Result.rc = 0 # Make sure rc is always set - if ($changed -and -not $module.CheckMode) { - # Make sure we get a temp copy of the file if the provider requires it and we haven't already done so. - if ($pathType -and -not $tempFile -and ($state -eq 'present' -or -not $packageStatus.SkipFileForRemove)) { - $tempFile = switch ($pathType) { - url { Get-UrlFile -Module $module -Url $path } - unc { Copy-ItemWithCredential -Path $path -Destination $module.Tmpdir -Credential $credential } - } - $path = $tempFile - } - - $setParams = @{ - Arguments = $arguments - ReturnCodes = $expectedReturnCode - Id = $packageStatus.Id - LogPath = $logPath - Module = $module - Path = $path - State = $state - WorkingDirectory = $chdir - } - $setParams += $packageStatus.ExtraInfo - &$providerInfo."$($packageStatus.Provider)".Set @setParams - } - $module.Result.changed = $changed -} finally { - if ($tempFile -and (Test-Path -LiteralPath $tempFile)) { - Remove-Item -LiteralPath $tempFile -Force - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_package.py b/lib/ansible/modules/windows/win_package.py deleted file mode 100644 index 864fe6975d..0000000000 --- a/lib/ansible/modules/windows/win_package.py +++ /dev/null @@ -1,386 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Trond Hindenes <trond@hindenes.com>, and others -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_package -version_added: "1.7" -short_description: Installs/uninstalls an installable package -description: -- Installs or uninstalls software packages for Windows. -- Supports C(.exe), C(.msi), C(.msp), C(.appx), C(.appxbundle), C(.msix), - and C(.msixbundle). -- These packages can be sourced from the local file system, network file share - or a url. -- See I(provider) for more info on each package type that is supported. -options: - arguments: - description: - - Any arguments the installer needs to either install or uninstall the - package. - - If the package is an MSI do not supply the C(/qn), C(/log) or - C(/norestart) arguments. - - This is only used for the C(msi), C(msp), and C(registry) providers. - - As of Ansible 2.5, this parameter can be a list of arguments and the - module will escape the arguments as necessary, it is recommended to use a - string when dealing with MSI packages due to the unique escaping issues - with msiexec. - type: raw - chdir: - description: - - Set the specified path as the current working directory before installing - or uninstalling a package. - - This is only used for the C(msi), C(msp), and C(registry) providers. - type: path - version_added: '2.8' - creates_path: - description: - - Will check the existence of the path specified and use the result to - determine whether the package is already installed. - - You can use this in conjunction with C(product_id) and other C(creates_*). - type: path - version_added: '2.4' - creates_service: - description: - - Will check the existing of the service specified and use the result to - determine whether the package is already installed. - - You can use this in conjunction with C(product_id) and other C(creates_*). - type: str - version_added: '2.4' - creates_version: - description: - - Will check the file version property of the file at C(creates_path) and - use the result to determine whether the package is already installed. - - C(creates_path) MUST be set and is a file. - - You can use this in conjunction with C(product_id) and other C(creates_*). - type: str - version_added: '2.4' - expected_return_code: - description: - - One or more return codes from the package installation that indicates - success. - - Before Ansible 2.4 this was just 0 but since Ansible 2.4 this is both C(0) and - C(3010). - - A return code of C(3010) usually means that a reboot is required, the - C(reboot_required) return value is set if the return code is C(3010). - - This is only used for the C(msi), C(msp), and C(registry) providers. - type: list - elements: int - default: [0, 3010] - log_path: - description: - - Specifies the path to a log file that is persisted after a package is - installed or uninstalled. - - This is only used for the C(msi) or C(msp) provider. - - When omitted, a temporary log file is used instead for those providers. - - This is only valid for MSI files, use C(arguments) for the C(registry) - provider. - type: path - version_added: '2.8' - password: - description: - - The password for C(user_name), must be set when C(user_name) is. - - This option is deprecated in favour of using become, see examples for - more information. - type: str - aliases: [ user_password ] - path: - description: - - Location of the package to be installed or uninstalled. - - This package can either be on the local file system, network share or a - url. - - When C(state=present), C(product_id) is not set and the path is a URL, - this file will always be downloaded to a temporary directory for - idempotency checks, otherwise the file will only be downloaded if the - package has not been installed based on the C(product_id) checks. - - If C(state=present) then this value MUST be set. - - If C(state=absent) then this value does not need to be set if - C(product_id) is. - type: str - product_id: - description: - - The product id of the installed packaged. - - This is used for checking whether the product is already installed and - getting the uninstall information if C(state=absent). - - For msi packages, this is the C(ProductCode) (GUID) of the package. This - can be found under the same registry paths as the C(registry) provider. - - For msp packages, this is the C(PatchCode) (GUID) of the package which - can found under the C(Details -> Revision number) of the file's properties. - - For msix packages, this is the C(Name) or C(PackageFullName) of the - package found under the C(Get-AppxPackage) cmdlet. - - For registry (exe) packages, this is the registry key name under the - registry paths specified in I(provider). - - This value is ignored if C(path) is set to a local accesible file path - and the package is not an C(exe). - - This SHOULD be set when the package is an C(exe), or the path is a url - or a network share and credential delegation is not being used. The - C(creates_*) options can be used instead but is not recommended. - - The C(productid) alias will be removed in Ansible 2.14. - type: str - aliases: [ productid ] - provider: - description: - - Set the package provider to use when searching for a package. - - The C(auto) provider will select the proper provider if I(path) - otherwise it scans all the other providers based on the I(product_id). - - The C(msi) provider scans for MSI packages installed on a machine wide - and current user context based on the C(ProductCode) of the MSI. Before - Ansible 2.10 only the machine wide context was searched. - - The C(msix) provider is used to install C(.appx), C(.msix), - C(.appxbundle), or C(.msixbundle) packages. These packages are only - installed or removed on the current use. The host must be set to allow - sideloaded apps or in developer mode. See the examples for how to enable - this. If a package is already installed but C(path) points to an updated - package, this will be installed over the top of the existing one. - - The C(msp) provider scans for all MSP patches installed on a machine wide - and current user context based on the C(PatchCode) of the MSP. A C(msp) - will be applied or removed on all C(msi) products that it applies to and - is installed. If the patch is obsoleted or superseded then no action will - be taken. - - The C(registry) provider is used for traditional C(exe) installers and - uses the following registry path to determine if a product was installed; - C(HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall), - C(HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall), - C(HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall), and - C(HKCU:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall). - Before Ansible 2.10 only the C(HKLM) hive was searched. - - Before Ansible 2.10 only the C(msi) and C(registry) providers were used. - choices: - - auto - - msi - - msix - - msp - - registry - default: auto - type: str - version_added: '2.10' - state: - description: - - Whether to install or uninstall the package. - - The module uses I(product_id) to determine whether the package is - installed or not. - - For all providers but C(auto), the I(path) can be used for idempotency - checks if it is locally accesible filesystem path. - - The C(ensure) alias will be removed in Ansible 2.14. - type: str - choices: [ absent, present ] - default: present - aliases: [ ensure ] - username: - description: - - Username of an account with access to the package if it is located on a - file share. - - This is only needed if the WinRM transport is over an auth method that - does not support credential delegation like Basic or NTLM or become is - not used. - - This option is deprecated in favour of using become, see examples for - more information. - type: str - aliases: [ user_name ] - - # Overrides the options in url_windows - client_cert: - version_added: '2.10' - client_cert_password: - version_added: '2.10' - follow_redirects: - version_added: '2.10' - force_basic_auth: - version_added: '2.10' - headers: - version_added: '2.10' - http_agent: - version_added: '2.10' - maximum_redirection: - version_added: '2.10' - method: - version_added: '2.10' - proxy_password: - version_added: '2.10' - proxy_url: - version_added: '2.10' - proxy_use_default_credential: - version_added: '2.10' - proxy_username: - version_added: '2.10' - timeout: - description: - - Specifies how long the web download request can be pending before it - times out in seconds. - - Set to C(0) to specify an infinite timeout. - version_added: '2.10' - url_password: - version_added: '2.10' - url_username: - version_added: '2.10' - use_default_credential: - version_added: '2.10' - use_proxy: - version_added: '2.10' -extends_documentation_fragment: -- url_windows -notes: -- When C(state=absent) and the product is an exe, the path may be different - from what was used to install the package originally. If path is not set then - the path used will be what is set under C(QuietUninstallString) or - C(UninstallString) in the registry for that I(product_id). -- By default all msi installs and uninstalls will be run with the arguments - C(/log, /qn, /norestart). -- All the installation checks under C(product_id) and C(creates_*) add - together, if one fails then the program is considered to be absent. -seealso: -- module: win_chocolatey -- module: win_hotfix -- module: win_updates -author: -- Trond Hindenes (@trondhindenes) -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Install the Visual C thingy - win_package: - path: http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe - product_id: '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}' - arguments: /install /passive /norestart - -- name: Install Visual C thingy with list of arguments instead of a string - win_package: - path: http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe - product_id: '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}' - arguments: - - /install - - /passive - - /norestart - -- name: Install Remote Desktop Connection Manager from msi with a permanent log - win_package: - path: https://download.microsoft.com/download/A/F/0/AF0071F3-B198-4A35-AA90-C68D103BDCCF/rdcman.msi - product_id: '{0240359E-6A4C-4884-9E94-B397A02D893C}' - state: present - log_path: D:\logs\vcredist_x64-exe-{{lookup('pipe', 'date +%Y%m%dT%H%M%S')}}.log - -- name: Uninstall Remote Desktop Connection Manager - win_package: - product_id: '{0240359E-6A4C-4884-9E94-B397A02D893C}' - state: absent - -- name: Install Remote Desktop Connection Manager locally omitting the product_id - win_package: - path: C:\temp\rdcman.msi - state: present - -- name: Uninstall Remote Desktop Connection Manager from local MSI omitting the product_id - win_package: - path: C:\temp\rdcman.msi - state: absent - -# 7-Zip exe doesn't use a guid for the Product ID -- name: Install 7zip from a network share with specific credentials - win_package: - path: \\domain\programs\7z.exe - product_id: 7-Zip - arguments: /S - state: present - become: yes - become_method: runas - become_flags: logon_type=new_credential logon_flags=netcredentials_only - vars: - ansible_become_user: DOMAIN\User - ansible_become_password: Password - -- name: Install 7zip and use a file version for the installation check - win_package: - path: C:\temp\7z.exe - creates_path: C:\Program Files\7-Zip\7z.exe - creates_version: 16.04 - state: present - -- name: Uninstall 7zip from the exe - win_package: - path: C:\Program Files\7-Zip\Uninstall.exe - product_id: 7-Zip - arguments: /S - state: absent - -- name: Uninstall 7zip without specifying the path - win_package: - product_id: 7-Zip - arguments: /S - state: absent - -- name: Install application and override expected return codes - win_package: - path: https://download.microsoft.com/download/1/6/7/167F0D79-9317-48AE-AEDB-17120579F8E2/NDP451-KB2858728-x86-x64-AllOS-ENU.exe - product_id: '{7DEBE4EB-6B40-3766-BB35-5CBBC385DA37}' - arguments: '/q /norestart' - state: present - expected_return_code: [0, 666, 3010] - -- name: Install a .msp patch - win_package: - path: C:\Patches\Product.msp - state: present - -- name: Remove a .msp patch - win_package: - product_id: '{AC76BA86-A440-FFFF-A440-0C13154E5D00}' - state: absent - -- name: Enable installation of 3rd party MSIX packages - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock - name: AllowAllTrustedApps - data: 1 - type: dword - state: present - -- name: Install an MSIX package for the current user - win_package: - path: C:\Installers\Calculator.msix # Can be .appx, .msixbundle, or .appxbundle - state: present - -- name: Uninstall an MSIX package using the product_id - win_package: - product_id: InputApp - state: absent -''' - -RETURN = r''' -log: - description: The contents of the MSI or MSP log. - returned: installation/uninstallation failure for MSI or MSP packages - type: str - sample: Installation completed successfully -rc: - description: The return code of the package process. - returned: change occurred - type: int - sample: 0 -reboot_required: - description: Whether a reboot is required to finalise package. This is set - to true if the executable return code is 3010. - returned: always - type: bool - sample: true -stdout: - description: The stdout stream of the package process. - returned: failure during install or uninstall - type: str - sample: Installing program -stderr: - description: The stderr stream of the package process. - returned: failure during install or uninstall - type: str - sample: Failed to install program -''' diff --git a/lib/ansible/modules/windows/win_path.ps1 b/lib/ansible/modules/windows/win_path.ps1 deleted file mode 100644 index 04eb41a374..0000000000 --- a/lib/ansible/modules/windows/win_path.ps1 +++ /dev/null @@ -1,145 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -Set-StrictMode -Version 2 -$ErrorActionPreference = "Stop" - -$system_path = "System\CurrentControlSet\Control\Session Manager\Environment" -$user_path = "Environment" - -# list/arraylist methods don't allow IEqualityComparer override for case/backslash/quote-insensitivity, roll our own search -Function Get-IndexOfPathElement ($list, [string]$value) { - $idx = 0 - $value = $value.Trim('"').Trim('\') - ForEach($el in $list) { - If ([string]$el.Trim('"').Trim('\') -ieq $value) { - return $idx - } - - $idx++ - } - - return -1 -} - -# alters list in place, returns true if at least one element was added -Function Add-Elements ($existing_elements, $elements_to_add) { - $last_idx = -1 - $changed = $false - - ForEach($el in $elements_to_add) { - $idx = Get-IndexOfPathElement $existing_elements $el - - # add missing elements at the end - If ($idx -eq -1) { - $last_idx = $existing_elements.Add($el) - $changed = $true - } - ElseIf ($idx -lt $last_idx) { - $existing_elements.RemoveAt($idx) | Out-Null - $existing_elements.Add($el) | Out-Null - $last_idx = $existing_elements.Count - 1 - $changed = $true - } - Else { - $last_idx = $idx - } - } - - return $changed -} - -# alters list in place, returns true if at least one element was removed -Function Remove-Elements ($existing_elements, $elements_to_remove) { - $count = $existing_elements.Count - - ForEach($el in $elements_to_remove) { - $idx = Get-IndexOfPathElement $existing_elements $el - $result.removed_idx = $idx - If ($idx -gt -1) { - $existing_elements.RemoveAt($idx) - } - } - - return $count -ne $existing_elements.Count -} - -# PS registry provider doesn't allow access to unexpanded REG_EXPAND_SZ; fall back to .NET -Function Get-RawPathVar ($scope) { - If ($scope -eq "user") { - $env_key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($user_path) - } - ElseIf ($scope -eq "machine") { - $env_key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($system_path) - } - - return $env_key.GetValue($var_name, "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) -} - -Function Set-RawPathVar($path_value, $scope) { - If ($scope -eq "user") { - $var_path = "HKCU:\" + $user_path - } - ElseIf ($scope -eq "machine") { - $var_path = "HKLM:\" + $system_path - } - - Set-ItemProperty $var_path -Name $var_name -Value $path_value -Type ExpandString | Out-Null - - return $path_value -} - -$parsed_args = Parse-Args $args -supports_check_mode $true - -$result = @{changed=$false} - -$var_name = Get-AnsibleParam $parsed_args "name" -Default "PATH" -$elements = Get-AnsibleParam $parsed_args "elements" -FailIfEmpty $result -$state = Get-AnsibleParam $parsed_args "state" -Default "present" -ValidateSet "present","absent" -$scope = Get-AnsibleParam $parsed_args "scope" -Default "machine" -ValidateSet "machine","user" - -$check_mode = Get-AnsibleParam $parsed_args "_ansible_check_mode" -Default $false - -If ($elements -is [string]) { - $elements = @($elements) -} - -If ($elements -isnot [Array]) { - Fail-Json $result "elements must be a string or list of path strings" -} - -$current_value = Get-RawPathVar $scope -$result.path_value = $current_value - -# TODO: test case-canonicalization on wacky unicode values (eg turkish i) -# TODO: detect and warn/fail on unparseable path? (eg, unbalanced quotes, invalid path chars) -# TODO: detect and warn/fail if system path and Powershell isn't on it? - -$existing_elements = New-Object System.Collections.ArrayList - -# split on semicolons, accounting for quoted values with embedded semicolons (which may or may not be wrapped in whitespace) -$pathsplit_re = [regex] '((?<q>\s*"[^"]+"\s*)|(?<q>[^;]+))(;$|$|;)' - -ForEach ($m in $pathsplit_re.Matches($current_value)) { - $existing_elements.Add($m.Groups['q'].Value) | Out-Null -} - -If ($state -eq "absent") { - $result.changed = Remove-Elements $existing_elements $elements -} -ElseIf ($state -eq "present") { - $result.changed = Add-Elements $existing_elements $elements -} - -# calculate the new path value from the existing elements -$path_value = [String]::Join(";", $existing_elements.ToArray()) -$result.path_value = $path_value - -If ($result.changed -and -not $check_mode) { - Set-RawPathVar $path_value $scope | Out-Null -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_path.py b/lib/ansible/modules/windows/win_path.py deleted file mode 100644 index 6404504fa2..0000000000 --- a/lib/ansible/modules/windows/win_path.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Red Hat | Ansible -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# This is a windows documentation stub. Actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_path -version_added: "2.3" -short_description: Manage Windows path environment variables -description: - - Allows element-based ordering, addition, and removal of Windows path environment variables. -options: - name: - description: - - Target path environment variable name. - type: str - default: PATH - elements: - description: - - A single path element, or a list of path elements (ie, directories) to add or remove. - - When multiple elements are included in the list (and C(state) is C(present)), the elements are guaranteed to appear in the same relative order - in the resultant path value. - - Variable expansions (eg, C(%VARNAME%)) are allowed, and are stored unexpanded in the target path element. - - Any existing path elements not mentioned in C(elements) are always preserved in their current order. - - New path elements are appended to the path, and existing path elements may be moved closer to the end to satisfy the requested ordering. - - Paths are compared in a case-insensitive fashion, and trailing backslashes are ignored for comparison purposes. However, note that trailing - backslashes in YAML require quotes. - type: list - required: yes - state: - description: - - Whether the path elements specified in C(elements) should be present or absent. - type: str - choices: [ absent, present ] - scope: - description: - - The level at which the environment variable specified by C(name) should be managed (either for the current user or global machine scope). - type: str - choices: [ machine, user ] - default: machine -notes: - - This module is for modifying individual elements of path-like - environment variables. For general-purpose management of other - environment vars, use the M(win_environment) module. - - This module does not broadcast change events. - This means that the minority of windows applications which can have - their environment changed without restarting will not be notified and - therefore will need restarting to pick up new environment settings. - - User level environment variables will require an interactive user to - log out and in again before they become available. -seealso: -- module: win_environment -author: -- Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -- name: Ensure that system32 and Powershell are present on the global system path, and in the specified order - win_path: - elements: - - '%SystemRoot%\system32' - - '%SystemRoot%\system32\WindowsPowerShell\v1.0' - -- name: Ensure that C:\Program Files\MyJavaThing is not on the current user's CLASSPATH - win_path: - name: CLASSPATH - elements: C:\Program Files\MyJavaThing - scope: user - state: absent -''' diff --git a/lib/ansible/modules/windows/win_ping.ps1 b/lib/ansible/modules/windows/win_ping.ps1 deleted file mode 100644 index c848b9121e..0000000000 --- a/lib/ansible/modules/windows/win_ping.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -$spec = @{ - options = @{ - data = @{ type = "str"; default = "pong" } - } - supports_check_mode = $true -} -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) -$data = $module.Params.data - -if ($data -eq "crash") { - throw "boom" -} - -$module.Result.ping = $data -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_ping.py b/lib/ansible/modules/windows/win_ping.py deleted file mode 100644 index 6d35f37994..0000000000 --- a/lib/ansible/modules/windows/win_ping.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>, and others -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_ping -version_added: "1.7" -short_description: A windows version of the classic ping module -description: - - Checks management connectivity of a windows host. - - This is NOT ICMP ping, this is just a trivial test module. - - For non-Windows targets, use the M(ping) module instead. - - For Network targets, use the M(net_ping) module instead. -options: - data: - description: - - Alternate data to return instead of 'pong'. - - If this parameter is set to C(crash), the module will cause an exception. - type: str - default: pong -seealso: -- module: ping -author: -- Chris Church (@cchurch) -''' - -EXAMPLES = r''' -# Test connectivity to a windows host -# ansible winserver -m win_ping - -- name: Example from an Ansible Playbook - win_ping: - -- name: Induce an exception to see what happens - win_ping: - data: crash -''' - -RETURN = r''' -ping: - description: Value provided with the data parameter. - returned: success - type: str - sample: pong -''' diff --git a/lib/ansible/modules/windows/win_reboot.py b/lib/ansible/modules/windows/win_reboot.py deleted file mode 100644 index 1431804143..0000000000 --- a/lib/ansible/modules/windows/win_reboot.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_reboot -short_description: Reboot a windows machine -description: -- Reboot a Windows machine, wait for it to go down, come back up, and respond to commands. -- For non-Windows targets, use the M(reboot) module instead. -version_added: '2.1' -options: - pre_reboot_delay: - description: - - Seconds to wait before reboot. Passed as a parameter to the reboot command. - type: int - default: 2 - aliases: [ pre_reboot_delay_sec ] - post_reboot_delay: - description: - - Seconds to wait after the reboot command was successful before attempting to validate the system rebooted successfully. - - This is useful if you want wait for something to settle despite your connection already working. - type: int - default: 0 - version_added: '2.4' - aliases: [ post_reboot_delay_sec ] - shutdown_timeout: - description: - - Maximum seconds to wait for shutdown to occur. - - Increase this timeout for very slow hardware, large update applications, etc. - - This option has been removed since Ansible 2.5 as the win_reboot behavior has changed. - type: int - default: 600 - aliases: [ shutdown_timeout_sec ] - reboot_timeout: - description: - - Maximum seconds to wait for machine to re-appear on the network and respond to a test command. - - This timeout is evaluated separately for both reboot verification and test command success so maximum clock time is actually twice this value. - type: int - default: 600 - aliases: [ reboot_timeout_sec ] - connect_timeout: - description: - - Maximum seconds to wait for a single successful TCP connection to the WinRM endpoint before trying again. - type: int - default: 5 - aliases: [ connect_timeout_sec ] - test_command: - description: - - Command to expect success for to determine the machine is ready for management. - type: str - default: whoami - msg: - description: - - Message to display to users. - type: str - default: Reboot initiated by Ansible - boot_time_command: - description: - - Command to run that returns a unique string indicating the last time the system was booted. - - Setting this to a command that has different output each time it is run will cause the task to fail. - type: str - default: '(Get-WmiObject -ClassName Win32_OperatingSystem).LastBootUpTime' - version_added: '2.10' -notes: -- If a shutdown was already scheduled on the system, C(win_reboot) will abort the scheduled shutdown and enforce its own shutdown. -- Beware that when C(win_reboot) returns, the Windows system may not have settled yet and some base services could be in limbo. - This can result in unexpected behavior. Check the examples for ways to mitigate this. -- The connection user must have the C(SeRemoteShutdownPrivilege) privilege enabled, see - U(https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/force-shutdown-from-a-remote-system) - for more information. -seealso: -- module: reboot -author: -- Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -- name: Reboot the machine with all defaults - win_reboot: - -- name: Reboot a slow machine that might have lots of updates to apply - win_reboot: - reboot_timeout: 3600 - -# Install a Windows feature and reboot if necessary -- name: Install IIS Web-Server - win_feature: - name: Web-Server - register: iis_install - -- name: Reboot when Web-Server feature requires it - win_reboot: - when: iis_install.reboot_required - -# One way to ensure the system is reliable, is to set WinRM to a delayed startup -- name: Ensure WinRM starts when the system has settled and is ready to work reliably - win_service: - name: WinRM - start_mode: delayed - - -# Additionally, you can add a delay before running the next task -- name: Reboot a machine that takes time to settle after being booted - win_reboot: - post_reboot_delay: 120 - -# Or you can make win_reboot validate exactly what you need to work before running the next task -- name: Validate that the netlogon service has started, before running the next task - win_reboot: - test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"' -''' - -RETURN = r''' -rebooted: - description: True if the machine was rebooted. - returned: always - type: bool - sample: true -elapsed: - description: The number of seconds that elapsed waiting for the system to be rebooted. - returned: always - type: float - sample: 23.2 -''' diff --git a/lib/ansible/modules/windows/win_reg_stat.ps1 b/lib/ansible/modules/windows/win_reg_stat.ps1 deleted file mode 100644 index c31fc5a869..0000000000 --- a/lib/ansible/modules/windows/win_reg_stat.ps1 +++ /dev/null @@ -1,126 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true - -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -failifempty $true -aliases "key" -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -aliases "entry","value" - -$result = @{ - changed = $false -} - -Function Get-PropertyValue { - param( - [Parameter(Mandatory=$true)][Microsoft.Win32.RegistryKey]$Key, - [String]$Name - ) - - $value = $Key.GetValue($Name, $null, [Microsoft.Win32.RegistryValueOptions]::None) - if ($null -eq $value) { - # Property does not exist or the key's (Default) is not set - return $null - } - - $raw_value = $Key.GetValue($Name, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) - - if ($Name -eq "") { - # The key's (Default) will fail on GetValueKind - $type = [Microsoft.Win32.RegistryValueKind]::String - } else { - $type = $Key.GetValueKind($Name) - } - - if ($type -in @([Microsoft.Win32.RegistryValueKind]::Binary, [Microsoft.Win32.RegistryValueKind]::None)) { - $formatted_raw_value = [System.Collections.Generic.List`1[String]]@() - foreach ($byte in $value) { - $formatted_raw_value.Add("0x{0:x2}" -f $byte) - } - $raw_value = $formatted_raw_value - } elseif ($type -eq [Microsoft.Win32.RegistryValueKind]::DWord) { - # .NET returns the value as a signed integer, we need to make it unsigned - $value = [UInt32]("0x{0:x}" -f $value) - $raw_value = $value - } elseif ($type -eq [Microsoft.Win32.RegistryValueKind]::QWord) { - $value = [UInt64]("0x{0:x}" -f $value) - $raw_value = $value - } - - $return_type = switch($type.ToString()) { - "Binary" { "REG_BINARY" } - "String" { "REG_SZ" } - "DWord" { "REG_DWORD" } - "QWord" { "REG_QWORD" } - "MultiString" { "REG_MULTI_SZ" } - "ExpandString" { "REG_EXPAND_SZ" } - "None" { "REG_NONE" } - default { "Unknown - $($type.ToString())" } - } - - return @{ - type = $return_type - value = $value - raw_value = $raw_value - } -} - -# Will validate the key parameter to make sure it matches known format -if ($path -notmatch "^HK(CC|CR|CU|LM|U):\\") { - Fail-Json -obj $result -message "path: $path is not a valid registry path, see module documentation for examples." -} - -$registry_path = (Split-Path -Path $path -NoQualifier).Substring(1) # removes the hive: and leading \ -$registry_hive = switch(Split-Path -Path $path -Qualifier) { - "HKCR:" { [Microsoft.Win32.Registry]::ClassesRoot } - "HKCC:" { [Microsoft.Win32.Registry]::CurrentConfig } - "HKCU:" { [Microsoft.Win32.Registry]::CurrentUser } - "HKLM:" { [Microsoft.Win32.Registry]::LocalMachine } - "HKU:" { [Microsoft.Win32.Registry]::Users } -} - -$key = $null -try { - $key = $registry_hive.OpenSubKey($registry_path, $false) - - if ($null -ne $key) { - if ($null -eq $name) { - $property_info = @{} - foreach ($property in $key.GetValueNames()) { - $property_info.$property = Get-PropertyValue -Key $key -Name $property - } - - # Return the key's (Default) property if it has been defined - $default_value = Get-PropertyValue -Key $key -Name "" - if ($null -ne $default_value) { - $property_info."" = $default_value - } - - $result.exists = $true - $result.properties = $property_info - $result.sub_keys = $key.GetSubKeyNames() - } else { - $property_value = Get-PropertyValue -Key $key -Name $name - if ($null -ne $property_value) { - $result.exists = $true - $result += $property_value - } else { - $result.exists = $false - } - } - } else { - $result.exists = $false - } -} finally { - if ($key) { - $key.Dispose() - } - $registry_hive.Dispose() -} - -Exit-Json -obj $result - diff --git a/lib/ansible/modules/windows/win_reg_stat.py b/lib/ansible/modules/windows/win_reg_stat.py deleted file mode 100644 index 6b76c971ed..0000000000 --- a/lib/ansible/modules/windows/win_reg_stat.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_reg_stat -version_added: "2.3" -short_description: Get information about Windows registry keys -description: -- Like M(win_file), M(win_reg_stat) will return whether the key/property exists. -- It also returns the sub keys and properties of the key specified. -- If specifying a property name through I(property), it will return the information specific for that property. -options: - path: - description: The full registry key path including the hive to search for. - type: str - required: yes - aliases: [ key ] - name: - description: - - The registry property name to get information for, the return json will not include the sub_keys and properties entries for the I(key) specified. - - Set to an empty string to target the registry key's C((Default)) property value. - type: str - aliases: [ entry, value, property ] -notes: -- The C(properties) return value will contain an empty string key C("") that refers to the key's C(Default) value. If - the value has not been set then this key is not returned. -seealso: -- module: win_regedit -- module: win_regmerge -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Obtain information about a registry key using short form - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion - register: current_version - -- name: Obtain information about a registry key property - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion - name: CommonFilesDir - register: common_files_dir - -- name: Obtain the registry key's (Default) property - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion - name: '' - register: current_version_default -''' - -RETURN = r''' -changed: - description: Whether anything was changed. - returned: always - type: bool - sample: true -exists: - description: States whether the registry key/property exists. - returned: success and path/property exists - type: bool - sample: true -properties: - description: A dictionary containing all the properties and their values in the registry key. - returned: success, path exists and property not specified - type: dict - sample: { - "" : { - "raw_value": "", - "type": "REG_SZ", - "value": "" - }, - "binary_property" : { - "raw_value": ["0x01", "0x16"], - "type": "REG_BINARY", - "value": [1, 22] - }, - "multi_string_property" : { - "raw_value": ["a", "b"], - "type": "REG_MULTI_SZ", - "value": ["a", "b"] - } - } -sub_keys: - description: A list of all the sub keys of the key specified. - returned: success, path exists and property not specified - type: list - sample: [ - "AppHost", - "Casting", - "DateTime" - ] -raw_value: - description: Returns the raw value of the registry property, REG_EXPAND_SZ has no string expansion, REG_BINARY or REG_NONE is in hex 0x format. - REG_NONE, this value is a hex string in the 0x format. - returned: success, path/property exists and property specified - type: str - sample: '%ProgramDir%\\Common Files' -type: - description: The property type. - returned: success, path/property exists and property specified - type: str - sample: "REG_EXPAND_SZ" -value: - description: The value of the property. - returned: success, path/property exists and property specified - type: str - sample: 'C:\\Program Files\\Common Files' -''' diff --git a/lib/ansible/modules/windows/win_regedit.ps1 b/lib/ansible/modules/windows/win_regedit.ps1 deleted file mode 100644 index c56b48335d..0000000000 --- a/lib/ansible/modules/windows/win_regedit.ps1 +++ /dev/null @@ -1,495 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Adam Keech <akeech@chathamfinancial.com> -# Copyright: (c) 2015, Josh Ludwig <jludwig@chathamfinancial.com> -# Copyright: (c) 2017, Jordan Borean <jborean93@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.PrivilegeUtil - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$path = Get-AnsibleParam -obj $params -name "path" -type "str" -failifempty $true -aliases "key" -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -aliases "entry","value" -$data = Get-AnsibleParam -obj $params -name "data" -$type = Get-AnsibleParam -obj $params -name "type" -type "str" -default "string" -validateset "none","binary","dword","expandstring","multistring","string","qword" -aliases "datatype" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" -$delete_key = Get-AnsibleParam -obj $params -name "delete_key" -type "bool" -default $true -$hive = Get-AnsibleParam -obj $params -name "hive" -type "path" - -$result = @{ - changed = $false - data_changed = $false - data_type_changed = $false -} - -if ($diff_mode) { - $result.diff = @{ - before = "" - after = "" - } -} - -$registry_util = @' -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace Ansible.WinRegedit -{ - internal class NativeMethods - { - [DllImport("advapi32.dll", CharSet = CharSet.Unicode)] - public static extern int RegLoadKeyW( - UInt32 hKey, - string lpSubKey, - string lpFile); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode)] - public static extern int RegUnLoadKeyW( - UInt32 hKey, - string lpSubKey); - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2})", message, base.Message, errorCode); - } - public override string Message { get { return _msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - public class Hive : IDisposable - { - private const UInt32 SCOPE = 0x80000002; // HKLM - private string hiveKey; - private bool loaded = false; - - public Hive(string hiveKey, string hivePath) - { - this.hiveKey = hiveKey; - int ret = NativeMethods.RegLoadKeyW(SCOPE, hiveKey, hivePath); - if (ret != 0) - throw new Win32Exception(ret, String.Format("Failed to load registry hive at {0}", hivePath)); - loaded = true; - } - - public static void UnloadHive(string hiveKey) - { - int ret = NativeMethods.RegUnLoadKeyW(SCOPE, hiveKey); - if (ret != 0) - throw new Win32Exception(ret, String.Format("Failed to unload registry hive at {0}", hiveKey)); - } - - public void Dispose() - { - if (loaded) - { - // Make sure the garbage collector disposes all unused handles and waits until it is complete - GC.Collect(); - GC.WaitForPendingFinalizers(); - - UnloadHive(hiveKey); - loaded = false; - } - GC.SuppressFinalize(this); - } - ~Hive() { this.Dispose(); } - } -} -'@ - -# fire a warning if the property name isn't specified, the (Default) key ($null) can only be a string -if ($null -eq $name -and $type -ne "string") { - Add-Warning -obj $result -message "the data type when name is not specified can only be 'string', the type has automatically been converted" - $type = "string" -} - -# Check that the registry path is in PSDrive format: HKCC, HKCR, HKCU, HKLM, HKU -if ($path -notmatch "^HK(CC|CR|CU|LM|U):\\") { - Fail-Json $result "path: $path is not a valid powershell path, see module documentation for examples." -} - -# Add a warning if the path does not contains a \ and is not the leaf path -$registry_path = (Split-Path -Path $path -NoQualifier).Substring(1) # removes the hive: and leading \ -$registry_leaf = Split-Path -Path $path -Leaf -if ($registry_path -ne $registry_leaf -and -not $registry_path.Contains('\')) { - $msg = "path is not using '\' as a separator, support for '/' as a separator will be removed in a future Ansible version" - Add-DeprecationWarning -obj $result -message $msg -version 2.12 - $registry_path = $registry_path.Replace('/', '\') -} - -# Simplified version of Convert-HexStringToByteArray from -# https://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert -# Expects a hex in the format you get when you run reg.exe export, -# and converts to a byte array so powershell can modify binary registry entries -# import format is like 'hex:be,ef,be,ef,be,ef,be,ef,be,ef' -Function Convert-RegExportHexStringToByteArray($string) { - # Remove 'hex:' from the front of the string if present - $string = $string.ToLower() -replace '^hex\:','' - - # Remove whitespace and any other non-hex crud. - $string = $string -replace '[^a-f0-9\\,x\-\:]','' - - # Turn commas into colons - $string = $string -replace ',',':' - - # Maybe there's nothing left over to convert... - if ($string.Length -eq 0) { - return ,@() - } - - # Split string with or without colon delimiters. - if ($string.Length -eq 1) { - return ,@([System.Convert]::ToByte($string,16)) - } elseif (($string.Length % 2 -eq 0) -and ($string.IndexOf(":") -eq -1)) { - return ,@($string -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}) - } elseif ($string.IndexOf(":") -ne -1) { - return ,@($string -split ':+' | foreach-object {[System.Convert]::ToByte($_,16)}) - } else { - return ,@() - } -} - -Function Compare-RegistryProperties($existing, $new) { - # Outputs $true if the property values don't match - if ($existing -is [Array]) { - (Compare-Object -ReferenceObject $existing -DifferenceObject $new -SyncWindow 0).Length -ne 0 - } else { - $existing -cne $new - } -} - -Function Get-DiffValue { - param( - [Parameter(Mandatory=$true)][Microsoft.Win32.RegistryValueKind]$Type, - [Parameter(Mandatory=$true)][Object]$Value - ) - - $diff = @{ type = $Type.ToString(); value = $Value } - - $enum = [Microsoft.Win32.RegistryValueKind] - if ($Type -in @($enum::Binary, $enum::None)) { - $diff.value = [System.Collections.Generic.List`1[String]]@() - foreach ($dec_value in $Value) { - $diff.value.Add("0x{0:x2}" -f $dec_value) - } - } elseif ($Type -eq $enum::DWord) { - $diff.value = "0x{0:x8}" -f $Value - } elseif ($Type -eq $enum::QWord) { - $diff.value = "0x{0:x16}" -f $Value - } - - return $diff -} - -Function Set-StateAbsent { - param( - # Used for diffs and exception messages to match up against Ansible input - [Parameter(Mandatory=$true)][String]$PrintPath, - [Parameter(Mandatory=$true)][Microsoft.Win32.RegistryKey]$Hive, - [Parameter(Mandatory=$true)][String]$Path, - [String]$Name, - [Switch]$DeleteKey - ) - - $key = $Hive.OpenSubKey($Path, $true) - if ($null -eq $key) { - # Key does not exist, no need to delete anything - return - } - - try { - if ($DeleteKey -and -not $Name) { - # delete_key=yes is set and name is null/empty, so delete the entire key - $key.Dispose() - $key = $null - if (-not $check_mode) { - try { - $Hive.DeleteSubKeyTree($Path, $false) - } catch { - Fail-Json -obj $result -message "failed to delete registry key at $($PrintPath): $($_.Exception.Message)" - } - } - $result.changed = $true - - if ($diff_mode) { - $result.diff.before = @{$PrintPath = @{}} - $result.diff.after = @{} - } - } else { - # delete_key=no or name is not null/empty, delete the property not the full key - $property = $key.GetValue($Name) - if ($null -eq $property) { - # property does not exist - return - } - $property_type = $key.GetValueKind($Name) # used for the diff - - if (-not $check_mode) { - try { - $key.DeleteValue($Name) - } catch { - Fail-Json -obj $result -message "failed to delete registry property '$Name' at $($PrintPath): $($_.Exception.Message)" - } - } - - $result.changed = $true - if ($diff_mode) { - $diff_value = Get-DiffValue -Type $property_type -Value $property - $result.diff.before = @{ $PrintPath = @{ $Name = $diff_value } } - $result.diff.after = @{ $PrintPath = @{} } - } - } - } finally { - if ($key) { - $key.Dispose() - } - } -} - -Function Set-StatePresent { - param( - [Parameter(Mandatory=$true)][String]$PrintPath, - [Parameter(Mandatory=$true)][Microsoft.Win32.RegistryKey]$Hive, - [Parameter(Mandatory=$true)][String]$Path, - [String]$Name, - [Object]$Data, - [Microsoft.Win32.RegistryValueKind]$Type - ) - - $key = $Hive.OpenSubKey($Path, $true) - try { - if ($null -eq $key) { - # the key does not exist, create it so the next steps work - if (-not $check_mode) { - try { - $key = $Hive.CreateSubKey($Path) - } catch { - Fail-Json -obj $result -message "failed to create registry key at $($PrintPath): $($_.Exception.Message)" - } - } - $result.changed = $true - - if ($diff_mode) { - $result.diff.before = @{} - $result.diff.after = @{$PrintPath = @{}} - } - } elseif ($diff_mode) { - # Make sure the diff is in an expected state for the key - $result.diff.before = @{$PrintPath = @{}} - $result.diff.after = @{$PrintPath = @{}} - } - - if ($null -eq $key -or $null -eq $Data) { - # Check mode and key was created above, we cannot do any more work, or $Data is $null which happens when - # we create a new key but haven't explicitly set the data - return - } - - $property = $key.GetValue($Name, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) - if ($null -ne $property) { - # property exists, need to compare the values and type - $existing_type = $key.GetValueKind($name) - $change_value = $false - - if ($Type -ne $existing_type) { - $change_value = $true - $result.data_type_changed = $true - $data_mismatch = Compare-RegistryProperties -existing $property -new $Data - if ($data_mismatch) { - $result.data_changed = $true - } - } else { - $data_mismatch = Compare-RegistryProperties -existing $property -new $Data - if ($data_mismatch) { - $change_value = $true - $result.data_changed = $true - } - } - - if ($change_value) { - if (-not $check_mode) { - try { - $key.SetValue($Name, $Data, $Type) - } catch { - Fail-Json -obj $result -message "failed to change registry property '$Name' at $($PrintPath): $($_.Exception.Message)" - } - } - $result.changed = $true - - if ($diff_mode) { - $result.diff.before.$PrintPath.$Name = Get-DiffValue -Type $existing_type -Value $property - $result.diff.after.$PrintPath.$Name = Get-DiffValue -Type $Type -Value $Data - } - } elseif ($diff_mode) { - $diff_value = Get-DiffValue -Type $existing_type -Value $property - $result.diff.before.$PrintPath.$Name = $diff_value - $result.diff.after.$PrintPath.$Name = $diff_value - } - } else { - # property doesn't exist just create a new one - if (-not $check_mode) { - try { - $key.SetValue($Name, $Data, $Type) - } catch { - Fail-Json -obj $result -message "failed to create registry property '$Name' at $($PrintPath): $($_.Exception.Message)" - } - } - $result.changed = $true - - if ($diff_mode) { - $result.diff.after.$PrintPath.$Name = Get-DiffValue -Type $Type -Value $Data - } - } - } finally { - if ($key) { - $key.Dispose() - } - } -} - -# convert property names "" to $null as "" refers to (Default) -if ($name -eq "") { - $name = $null -} - -# convert the data to the required format -if ($type -in @("binary", "none")) { - if ($null -eq $data) { - $data = "" - } - - # convert the data from string to byte array if in hex: format - if ($data -is [String]) { - $data = [byte[]](Convert-RegExportHexStringToByteArray -string $data) - } elseif ($data -is [Int]) { - if ($data -gt 255) { - Fail-Json $result "cannot convert binary data '$data' to byte array, please specify this value as a yaml byte array or a comma separated hex value string" - } - $data = [byte[]]@([byte]$data) - } elseif ($data -is [Array]) { - $data = [byte[]]$data - } -} elseif ($type -in @("dword", "qword")) { - # dword's and dword's don't allow null values, set to 0 - if ($null -eq $data) { - $data = 0 - } - - if ($data -is [String]) { - # if the data is a string we need to convert it to an unsigned int64 - # it needs to be unsigned as Ansible passes in an unsigned value while - # powershell uses a signed data type. The value will then be converted - # below - $data = [UInt64]$data - } - - if ($type -eq "dword") { - if ($data -gt [UInt32]::MaxValue) { - Fail-Json $result "data cannot be larger than 0xffffffff when type is dword" - } elseif ($data -gt [Int32]::MaxValue) { - # when dealing with larger int32 (> 2147483647 or 0x7FFFFFFF) powershell - # automatically converts it to a signed int64. We need to convert this to - # signed int32 by parsing the hex string value. - $data = "0x$("{0:x}" -f $data)" - } - $data = [Int32]$data - } else { - if ($data -gt [UInt64]::MaxValue) { - Fail-Json $result "data cannot be larger than 0xffffffffffffffff when type is qword" - } elseif ($data -gt [Int64]::MaxValue) { - $data = "0x$("{0:x}" -f $data)" - } - $data = [Int64]$data - } -} elseif ($type -in @("string", "expandstring") -and $name) { - # a null string or expandstring must be empty quotes - # Only do this if $name has been defined (not the default key) - if ($null -eq $data) { - $data = "" - } -} elseif ($type -eq "multistring") { - # convert the data for a multistring to a String[] array - if ($null -eq $data) { - $data = [String[]]@() - } elseif ($data -isnot [Array]) { - $new_data = New-Object -TypeName String[] -ArgumentList 1 - $new_data[0] = $data.ToString([CultureInfo]::InvariantCulture) - $data = $new_data - } else { - $new_data = New-Object -TypeName String[] -ArgumentList $data.Count - foreach ($entry in $data) { - $new_data[$data.IndexOf($entry)] = $entry.ToString([CultureInfo]::InvariantCulture) - } - $data = $new_data - } -} - -# convert the type string to the .NET class -$type = [System.Enum]::Parse([Microsoft.Win32.RegistryValueKind], $type, $true) - -$registry_hive = switch(Split-Path -Path $path -Qualifier) { - "HKCR:" { [Microsoft.Win32.Registry]::ClassesRoot } - "HKCC:" { [Microsoft.Win32.Registry]::CurrentConfig } - "HKCU:" { [Microsoft.Win32.Registry]::CurrentUser } - "HKLM:" { [Microsoft.Win32.Registry]::LocalMachine } - "HKU:" { [Microsoft.Win32.Registry]::Users } -} -$loaded_hive = $null -try { - if ($hive) { - if (-not (Test-Path -LiteralPath $hive)) { - Fail-Json -obj $result -message "hive at path '$hive' is not valid or accessible, cannot load hive" - } - - $original_tmp = $env:TMP - $env:TMP = $_remote_tmp - Add-Type -TypeDefinition $registry_util - $env:TMP = $original_tmp - - try { - Set-AnsiblePrivilege -Name SeBackupPrivilege -Value $true - Set-AnsiblePrivilege -Name SeRestorePrivilege -Value $true - } catch [System.ComponentModel.Win32Exception] { - Fail-Json -obj $result -message "failed to enable SeBackupPrivilege and SeRestorePrivilege for the current process: $($_.Exception.Message)" - } - - if (Test-Path -Path HKLM:\ANSIBLE) { - Add-Warning -obj $result -message "hive already loaded at HKLM:\ANSIBLE, had to unload hive for win_regedit to continue" - try { - [Ansible.WinRegedit.Hive]::UnloadHive("ANSIBLE") - } catch [System.ComponentModel.Win32Exception] { - Fail-Json -obj $result -message "failed to unload registry hive HKLM:\ANSIBLE from $($hive): $($_.Exception.Message)" - } - } - - try { - $loaded_hive = New-Object -TypeName Ansible.WinRegedit.Hive -ArgumentList "ANSIBLE", $hive - } catch [System.ComponentModel.Win32Exception] { - Fail-Json -obj $result -message "failed to load registry hive from '$hive' to HKLM:\ANSIBLE: $($_.Exception.Message)" - } - } - - if ($state -eq "present") { - Set-StatePresent -PrintPath $path -Hive $registry_hive -Path $registry_path -Name $name -Data $data -Type $type - } else { - Set-StateAbsent -PrintPath $path -Hive $registry_hive -Path $registry_path -Name $name -DeleteKey:$delete_key - } -} finally { - $registry_hive.Dispose() - if ($loaded_hive) { - $loaded_hive.Dispose() - } -} - -Exit-Json $result - diff --git a/lib/ansible/modules/windows/win_regedit.py b/lib/ansible/modules/windows/win_regedit.py deleted file mode 100644 index 2c0fff7124..0000000000 --- a/lib/ansible/modules/windows/win_regedit.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Adam Keech <akeech@chathamfinancial.com> -# Copyright: (c) 2015, Josh Ludwig <jludwig@chathamfinancial.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - - -DOCUMENTATION = r''' ---- -module: win_regedit -version_added: '2.0' -short_description: Add, change, or remove registry keys and values -description: -- Add, modify or remove registry keys and values. -- More information about the windows registry from Wikipedia - U(https://en.wikipedia.org/wiki/Windows_Registry). -options: - path: - description: - - Name of the registry path. - - 'Should be in one of the following registry hives: HKCC, HKCR, HKCU, - HKLM, HKU.' - type: str - required: yes - aliases: [ key ] - name: - description: - - Name of the registry entry in the above C(path) parameters. - - If not provided, or empty then the '(Default)' property for the key will - be used. - type: str - aliases: [ entry, value ] - data: - description: - - Value of the registry entry C(name) in C(path). - - If not specified then the value for the property will be null for the - corresponding C(type). - - Binary and None data should be expressed in a yaml byte array or as comma - separated hex values. - - An easy way to generate this is to run C(regedit.exe) and use the - I(export) option to save the registry values to a file. - - In the exported file, binary value will look like C(hex:be,ef,be,ef), the - C(hex:) prefix is optional. - - DWORD and QWORD values should either be represented as a decimal number - or a hex value. - - Multistring values should be passed in as a list. - - See the examples for more details on how to format this data. - type: str - type: - description: - - The registry value data type. - type: str - choices: [ binary, dword, expandstring, multistring, string, qword ] - default: string - aliases: [ datatype ] - state: - description: - - The state of the registry entry. - type: str - choices: [ absent, present ] - default: present - delete_key: - description: - - When C(state) is 'absent' then this will delete the entire key. - - If C(no) then it will only clear out the '(Default)' property for - that key. - type: bool - default: yes - version_added: '2.4' - hive: - description: - - A path to a hive key like C:\Users\Default\NTUSER.DAT to load in the - registry. - - This hive is loaded under the HKLM:\ANSIBLE key which can then be used - in I(name) like any other path. - - This can be used to load the default user profile registry hive or any - other hive saved as a file. - - Using this function requires the user to have the C(SeRestorePrivilege) - and C(SeBackupPrivilege) privileges enabled. - type: path - version_added: '2.5' -notes: -- Check-mode C(-C/--check) and diff output C(-D/--diff) are supported, so that you can test every change against the active configuration before - applying changes. -- Beware that some registry hives (C(HKEY_USERS) in particular) do not allow to create new registry paths in the root folder. -- Since ansible 2.4, when checking if a string registry value has changed, a case-sensitive test is used. Previously the test was case-insensitive. -seealso: -- module: win_reg_stat -- module: win_regmerge -author: -- Adam Keech (@smadam813) -- Josh Ludwig (@joshludwig) -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Create registry path MyCompany - win_regedit: - path: HKCU:\Software\MyCompany - -- name: Add or update registry path MyCompany, with entry 'hello', and containing 'world' - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: world - -- name: Add or update registry path MyCompany, with dword entry 'hello', and containing 1337 as the decimal value - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: 1337 - type: dword - -- name: Add or update registry path MyCompany, with dword entry 'hello', and containing 0xff2500ae as the hex value - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: 0xff2500ae - type: dword - -- name: Add or update registry path MyCompany, with binary entry 'hello', and containing binary data in hex-string format - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: hex:be,ef,be,ef,be,ef,be,ef,be,ef - type: binary - -- name: Add or update registry path MyCompany, with binary entry 'hello', and containing binary data in yaml format - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: [0xbe,0xef,0xbe,0xef,0xbe,0xef,0xbe,0xef,0xbe,0xef] - type: binary - -- name: Add or update registry path MyCompany, with expand string entry 'hello' - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: '%appdata%\local' - type: expandstring - -- name: Add or update registry path MyCompany, with multi string entry 'hello' - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - data: ['hello', 'world'] - type: multistring - -- name: Disable keyboard layout hotkey for all users (changes existing) - win_regedit: - path: HKU:\.DEFAULT\Keyboard Layout\Toggle - name: Layout Hotkey - data: 3 - type: dword - -- name: Disable language hotkey for current users (adds new) - win_regedit: - path: HKCU:\Keyboard Layout\Toggle - name: Language Hotkey - data: 3 - type: dword - -- name: Remove registry path MyCompany (including all entries it contains) - win_regedit: - path: HKCU:\Software\MyCompany - state: absent - delete_key: yes - -- name: Clear the existing (Default) entry at path MyCompany - win_regedit: - path: HKCU:\Software\MyCompany - state: absent - delete_key: no - -- name: Remove entry 'hello' from registry path MyCompany - win_regedit: - path: HKCU:\Software\MyCompany - name: hello - state: absent - -- name: Change default mouse trailing settings for new users - win_regedit: - path: HKLM:\ANSIBLE\Control Panel\Mouse - name: MouseTrails - data: 10 - type: str - state: present - hive: C:\Users\Default\NTUSER.dat -''' - -RETURN = r''' -data_changed: - description: Whether this invocation changed the data in the registry value. - returned: success - type: bool - sample: false -data_type_changed: - description: Whether this invocation changed the datatype of the registry value. - returned: success - type: bool - sample: true -''' diff --git a/lib/ansible/modules/windows/win_service.ps1 b/lib/ansible/modules/windows/win_service.ps1 deleted file mode 100644 index 9c2a1cc1f5..0000000000 --- a/lib/ansible/modules/windows/win_service.ps1 +++ /dev/null @@ -1,463 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Chris Hoffman <choffman@chathamfinancial.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name '_ansible_check_mode' -type 'bool' -default $false - -$dependencies = Get-AnsibleParam -obj $params -name 'dependencies' -type 'list' -default $null -$dependency_action = Get-AnsibleParam -obj $params -name 'dependency_action' -type 'str' -default 'set' -validateset 'add','remove','set' -$description = Get-AnsibleParam -obj $params -name 'description' -type 'str' -$desktop_interact = Get-AnsibleParam -obj $params -name 'desktop_interact' -type 'bool' -default $false -$display_name = Get-AnsibleParam -obj $params -name 'display_name' -type 'str' -$force_dependent_services = Get-AnsibleParam -obj $params -name 'force_dependent_services' -type 'bool' -default $false -$name = Get-AnsibleParam -obj $params -name 'name' -type 'str' -failifempty $true -$password = Get-AnsibleParam -obj $params -name 'password' -type 'str' -$path = Get-AnsibleParam -obj $params -name 'path' -$start_mode = Get-AnsibleParam -obj $params -name 'start_mode' -type 'str' -validateset 'auto','manual','disabled','delayed' -$state = Get-AnsibleParam -obj $params -name 'state' -type 'str' -validateset 'started','stopped','restarted','absent','paused' -$username = Get-AnsibleParam -obj $params -name 'username' -type 'str' - -$result = @{ - changed = $false -} - -# parse the username to SID and back so we get the full username with domain in a way WMI understands -if ($null -ne $username) { - if ($username -eq "LocalSystem") { - $username_sid = "S-1-5-18" - } else { - $username_sid = Convert-ToSID -account_name $username - } - - # the SYSTEM account is a special beast, Win32_Service Change requires StartName to be LocalSystem - # to specify LocalSystem/NT AUTHORITY\SYSTEM - if ($username_sid -eq "S-1-5-18") { - $username = "LocalSystem" - $password = $null - } else { - # Win32_Service, password must be "" and not $null when setting to LocalService or NetworkService - if ($username_sid -in @("S-1-5-19", "S-1-5-20")) { - $password = "" - } - $username = Convert-FromSID -sid $username_sid - } -} -if ($null -ne $password -and $null -eq $username) { - Fail-Json $result "The argument 'username' must be supplied with 'password'" -} -if ($desktop_interact -eq $true -and (-not ($username -eq "LocalSystem" -or $null -eq $username))) { - Fail-Json $result "Can only set 'desktop_interact' to true when 'username' equals 'LocalSystem'" -} -if ($null -ne $path) { - $path = [System.Environment]::ExpandEnvironmentVariables($path) -} - -Function Get-ServiceInfo($name) { - # Need to get new objects so we have the latest info - $svc = Get-Service | Where-Object { $_.Name -eq $name -or $_.DisplayName -eq $name } - $wmi_svc = Get-CimInstance -ClassName Win32_Service -Filter "name='$($svc.Name)'" - - # Delayed start_mode is in reality Automatic (Delayed), need to check reg key for type - $delayed = Get-DelayedStatus -name $svc.Name - $actual_start_mode = $wmi_svc.StartMode.ToString().ToLower() - if ($delayed -and $actual_start_mode -eq 'auto') { - $actual_start_mode = 'delayed' - } - - $existing_dependencies = @() - $existing_depended_by = @() - if ($svc.ServicesDependedOn.Count -gt 0) { - foreach ($dependency in $svc.ServicesDependedOn.Name) { - $existing_dependencies += $dependency - } - } - if ($svc.DependentServices.Count -gt 0) { - foreach ($dependency in $svc.DependentServices.Name) { - $existing_depended_by += $dependency - } - } - $description = $wmi_svc.Description - if ($null -eq $description) { - $description = "" - } - - $result.exists = $true - $result.name = $svc.Name - $result.display_name = $svc.DisplayName - $result.state = $svc.Status.ToString().ToLower() - $result.start_mode = $actual_start_mode - $result.path = $wmi_svc.PathName - $result.description = $description - $result.username = $wmi_svc.StartName - $result.desktop_interact = $wmi_svc.DesktopInteract - $result.dependencies = $existing_dependencies - $result.depended_by = $existing_depended_by - $result.can_pause_and_continue = $svc.CanPauseAndContinue -} - -Function Get-WmiErrorMessage($return_value) { - # These values are derived from https://msdn.microsoft.com/en-us/library/aa384901(v=vs.85).aspx - switch ($return_value) { - 1 { "Not Supported: The request is not supported" } - 2 { "Access Denied: The user did not have the necessary access" } - 3 { "Dependent Services Running: The service cannot be stopped because other services that are running are dependent on it" } - 4 { "Invalid Service Control: The requested control code is not valid, or it is unacceptable to the service" } - 5 { "Service Cannot Accept Control: The requested control code cannot be sent to the service because the state of the service (Win32_BaseService.State property) is equal to 0, 1, or 2" } - 6 { "Service Not Active: The service has not been started" } - 7 { "Service Request Timeout: The service did not respond to the start request in a timely fashion" } - 8 { "Unknown Failure: Unknown failure when starting the service" } - 9 { "Path Not Found: The directory path to the service executable file was not found" } - 10 { "Service Already Running: The service is already running" } - 11 { "Service Database Locked: The database to add a new service is locked" } - 12 { "Service Dependency Deleted: A dependency this service relies on has been removed from the system" } - 13 { "Service Dependency Failure: The service failed to find the service needed from a dependent service" } - 14 { "Service Disabled: The service has been disabled from the system" } - 15 { "Service Logon Failed: The service does not have the correct authentication to run on the system" } - 16 { "Service Marked For Deletion: This service is being removed from the system" } - 17 { "Service No Thread: The service has no execution thread" } - 18 { "Status Circular Dependency: The service has circular dependencies when it starts" } - 19 { "Status Duplicate Name: A service is running under the same name" } - 20 { "Status Invalid Name: The service name has invalid characters" } - 21 { "Status Invalid Parameter: Invalid parameters have been passed to the service" } - 22 { "Status Invalid Service Account: The account under which this service runs is either invalid or lacks the permissions to run the service" } - 23 { "Status Service Exists: The service exists in the database of services available from the system" } - 24 { "Service Already Paused: The service is currently paused in the system" } - default { "Other Error" } - } -} - -Function Get-DelayedStatus($name) { - $delayed_key = "HKLM:\System\CurrentControlSet\Services\$name" - try { - $delayed = ConvertTo-Bool ((Get-ItemProperty -LiteralPath $delayed_key).DelayedAutostart) - } catch { - $delayed = $false - } - - $delayed -} - -Function Set-ServiceStartMode($svc, $start_mode) { - if ($result.start_mode -ne $start_mode) { - try { - $delayed_key = "HKLM:\System\CurrentControlSet\Services\$($svc.Name)" - # Original start up type was auto (delayed) and we want auto, need to removed delayed key - if ($start_mode -eq 'auto' -and $result.start_mode -eq 'delayed') { - Set-ItemProperty -LiteralPath $delayed_key -Name "DelayedAutostart" -Value 0 -WhatIf:$check_mode - # Original start up type was auto and we want auto (delayed), need to add delayed key - } elseif ($start_mode -eq 'delayed' -and $result.start_mode -eq 'auto') { - Set-ItemProperty -LiteralPath $delayed_key -Name "DelayedAutostart" -Value 1 -WhatIf:$check_mode - # Original start up type was not auto or auto (delayed), need to change to auto and add delayed key - } elseif ($start_mode -eq 'delayed') { - $svc | Set-Service -StartupType "auto" -WhatIf:$check_mode - Set-ItemProperty -LiteralPath $delayed_key -Name "DelayedAutostart" -Value 1 -WhatIf:$check_mode - # Original start up type was not what we were looking for, just change to that type - } else { - $svc | Set-Service -StartupType $start_mode -WhatIf:$check_mode - } - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } -} - -Function Set-ServiceAccount($wmi_svc, $username_sid, $username, $password) { - if ($result.username -eq "LocalSystem") { - $actual_sid = "S-1-5-18" - } else { - $actual_sid = Convert-ToSID -account_name $result.username - } - - if ($actual_sid -ne $username_sid) { - $change_arguments = @{ - StartName = $username - StartPassword = $password - DesktopInteract = $result.desktop_interact - } - # need to disable desktop interact when not using the SYSTEM account - if ($username_sid -ne "S-1-5-18") { - $change_arguments.DesktopInteract = $false - } - - #WMI.Change doesn't support -WhatIf, cannot fully test with check_mode - if (-not $check_mode) { - $return = $wmi_svc | Invoke-CimMethod -MethodName Change -Arguments $change_arguments - if ($return.ReturnValue -ne 0) { - $error_msg = Get-WmiErrorMessage -return_value $result.ReturnValue - Fail-Json -obj $result -message "Failed to set service account to $($username): $($return.ReturnValue) - $error_msg" - } - } - - $result.changed = $true - } -} - -Function Set-ServiceDesktopInteract($wmi_svc, $desktop_interact) { - if ($result.desktop_interact -ne $desktop_interact) { - if (-not $check_mode) { - $return = $wmi_svc | Invoke-CimMethod -MethodName Change -Arguments @{DesktopInteract = $desktop_interact} - if ($return.ReturnValue -ne 0) { - $error_msg = Get-WmiErrorMessage -return_value $return.ReturnValue - Fail-Json -obj $result -message "Failed to set desktop interact $($desktop_interact): $($return.ReturnValue) - $error_msg" - } - } - - $result.changed = $true - } -} - -Function Set-ServiceDisplayName($svc, $display_name) { - if ($result.display_name -ne $display_name) { - try { - $svc | Set-Service -DisplayName $display_name -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } -} - -Function Set-ServiceDescription($svc, $description) { - if ($result.description -ne $description) { - try { - $svc | Set-Service -Description $description -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } -} - -Function Set-ServicePath($name, $path) { - if ($result.path -ne $path) { - try { - Set-ItemProperty -LiteralPath "HKLM:\System\CurrentControlSet\Services\$name" -Name ImagePath -Value $path -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } -} - -Function Set-ServiceDependencies($wmi_svc, $dependency_action, $dependencies) { - $existing_dependencies = $result.dependencies - [System.Collections.ArrayList]$new_dependencies = @() - - if ($dependency_action -eq 'set') { - foreach ($dependency in $dependencies) { - $new_dependencies.Add($dependency) - } - } else { - $new_dependencies = $existing_dependencies - foreach ($dependency in $dependencies) { - if ($dependency_action -eq 'remove') { - if ($new_dependencies -contains $dependency) { - $new_dependencies.Remove($dependency) - } - } elseif ($dependency_action -eq 'add') { - if ($new_dependencies -notcontains $dependency) { - $new_dependencies.Add($dependency) - } - } - } - } - - $will_change = $false - foreach ($dependency in $new_dependencies) { - if ($existing_dependencies -notcontains $dependency) { - $will_change = $true - } - } - foreach ($dependency in $existing_dependencies) { - if ($new_dependencies -notcontains $dependency) { - $will_change = $true - } - } - - if ($will_change -eq $true) { - if (-not $check_mode) { - $return = $wmi_svc | Invoke-CimMethod -MethodName Change -Arguments @{ServiceDependencies = $new_dependencies} - if ($return.ReturnValue -ne 0) { - $error_msg = Get-WmiErrorMessage -return_value $return.ReturnValue - $dep_string = $new_dependencies -join ", " - Fail-Json -obj $result -message "Failed to set service dependencies $($dep_string): $($return.ReturnValue) - $error_msg" - } - } - - $result.changed = $true - } -} - -Function Set-ServiceState($svc, $wmi_svc, $state) { - if ($state -eq "started" -and $result.state -ne "running") { - if ($result.state -eq "paused") { - try { - $svc | Resume-Service -WhatIf:$check_mode - } catch { - Fail-Json $result "failed to start service from paused state $($svc.Name): $($_.Exception.Message)" - } - } else { - try { - $svc | Start-Service -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - } - - $result.changed = $true - } - - if ($state -eq "stopped" -and $result.state -ne "stopped") { - try { - $svc | Stop-Service -Force:$force_dependent_services -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } - - if ($state -eq "restarted") { - try { - $svc | Restart-Service -Force:$force_dependent_services -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - - $result.changed = $true - } - - if ($state -eq "paused" -and $result.state -ne "paused") { - # check that we can actually pause the service - if ($result.can_pause_and_continue -eq $false) { - Fail-Json $result "failed to pause service $($svc.Name): The service does not support pausing" - } - - try { - $svc | Suspend-Service -WhatIf:$check_mode - } catch { - Fail-Json $result "failed to pause service $($svc.Name): $($_.Exception.Message)" - } - $result.changed = $true - } - - if ($state -eq "absent") { - try { - $svc | Stop-Service -Force:$force_dependent_services -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - if (-not $check_mode) { - $return = $wmi_svc | Invoke-CimMethod -MethodName Delete - if ($return.ReturnValue -ne 0) { - $error_msg = Get-WmiErrorMessage -return_value $return.ReturnValue - Fail-Json -obj $result -message "Failed to delete service $($svc.Name): $($return.ReturnValue) - $error_msg" - } - } - - $result.changed = $true - } -} - -Function Set-ServiceConfiguration($svc) { - $wmi_svc = Get-CimInstance -ClassName Win32_Service -Filter "name='$($svc.Name)'" - Get-ServiceInfo -name $svc.Name - if ($desktop_interact -eq $true -and (-not ($result.username -eq 'LocalSystem' -or $username -eq 'LocalSystem'))) { - Fail-Json $result "Can only set desktop_interact to true when service is run with/or 'username' equals 'LocalSystem'" - } - - if ($null -ne $start_mode) { - Set-ServiceStartMode -svc $svc -start_mode $start_mode - } - - if ($null -ne $username) { - Set-ServiceAccount -wmi_svc $wmi_svc -username_sid $username_sid -username $username -password $password - } - - if ($null -ne $display_name) { - Set-ServiceDisplayName -svc $svc -display_name $display_name - } - - if ($null -ne $desktop_interact) { - Set-ServiceDesktopInteract -wmi_svc $wmi_svc -desktop_interact $desktop_interact - } - - if ($null -ne $description) { - Set-ServiceDescription -svc $svc -description $description - } - - if ($null -ne $path) { - Set-ServicePath -name $svc.Name -path $path - } - - if ($null -ne $dependencies) { - Set-ServiceDependencies -wmi_svc $wmi_svc -dependency_action $dependency_action -dependencies $dependencies - } - - if ($null -ne $state) { - Set-ServiceState -svc $svc -wmi_svc $wmi_svc -state $state - } -} - -# need to use Where-Object as -Name doesn't work with [] in the service name -# https://github.com/ansible/ansible/issues/37621 -$svc = Get-Service | Where-Object { $_.Name -eq $name -or $_.DisplayName -eq $name } -if ($svc) { - Set-ServiceConfiguration -svc $svc -} else { - $result.exists = $false - if ($state -ne 'absent') { - # Check if path is defined, if so create the service - if ($null -ne $path) { - try { - New-Service -Name $name -BinaryPathname $path -WhatIf:$check_mode - } catch { - Fail-Json $result $_.Exception.Message - } - $result.changed = $true - - $svc = Get-Service | Where-Object { $_.Name -eq $name } - Set-ServiceConfiguration -svc $svc - } else { - # We will only reach here if the service is installed and the state is not absent - # Will check if any of the default actions are set and fail as we cannot action it - if ($null -ne $start_mode -or - $null -ne $state -or - $null -ne $username -or - $null -ne $password -or - $null -ne $display_name -or - $null -ne $description -or - $desktop_interact -ne $false -or - $null -ne $dependencies -or - $dependency_action -ne 'set') { - Fail-Json $result "Service '$name' is not installed, need to set 'path' to create a new service" - } - } - } -} - -# After making a change, let's get the service info again unless we deleted it -if ($state -eq 'absent') { - # Recreate result so it doesn't have the extra meta data now that is has been deleted - $changed = $result.changed - $result = @{ - changed = $changed - exists = $false - } -} elseif ($null -ne $svc) { - Get-ServiceInfo -name $name -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_service.py b/lib/ansible/modules/windows/win_service.py deleted file mode 100644 index 2fc19f57c9..0000000000 --- a/lib/ansible/modules/windows/win_service.py +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Chris Hoffman <choffman@chathamfinancial.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_service -version_added: '1.7' -short_description: Manage and query Windows services -description: -- Manage and query Windows services. -- For non-Windows targets, use the M(service) module instead. -options: - dependencies: - description: - - A list of service dependencies to set for this particular service. - - This should be a list of service names and not the display name of the - service. - - This works by C(dependency_action) to either add/remove or set the - services in this list. - type: list - version_added: '2.3' - dependency_action: - description: - - Used in conjunction with C(dependency) to either add the dependencies to - the existing service dependencies. - - Remove the dependencies to the existing dependencies. - - Set the dependencies to only the values in the list replacing the - existing dependencies. - type: str - choices: [ add, remove, set ] - default: set - version_added: '2.3' - desktop_interact: - description: - - Whether to allow the service user to interact with the desktop. - - This should only be set to C(yes) when using the C(LocalSystem) username. - type: bool - default: no - version_added: '2.3' - description: - description: - - The description to set for the service. - type: str - version_added: '2.3' - display_name: - description: - - The display name to set for the service. - type: str - version_added: '2.3' - force_dependent_services: - description: - - If C(yes), stopping or restarting a service with dependent services will - force the dependent services to stop or restart also. - - If C(no), stopping or restarting a service with dependent services may - fail. - type: bool - default: no - version_added: '2.3' - name: - description: - - Name of the service. - - If only the name parameter is specified, the module will report - on whether the service exists or not without making any changes. - required: yes - type: str - path: - description: - - The path to the executable to set for the service. - type: str - version_added: '2.3' - password: - description: - - The password to set the service to start as. - - This and the C(username) argument must be supplied together. - - If specifying C(LocalSystem), C(NetworkService) or C(LocalService) this field - must be an empty string and not null. - type: str - version_added: '2.3' - start_mode: - description: - - Set the startup type for the service. - - A newly created service will default to C(auto). - - C(delayed) added in Ansible 2.3 - type: str - choices: [ auto, delayed, disabled, manual ] - state: - description: - - The desired state of the service. - - C(started)/C(stopped)/C(absent)/C(paused) are idempotent actions that will not run - commands unless necessary. - - C(restarted) will always bounce the service. - - C(absent) was added in Ansible 2.3 - - C(paused) was added in Ansible 2.4 - - Only services that support the paused state can be paused, you can - check the return value C(can_pause_and_continue). - - You can only pause a service that is already started. - - A newly created service will default to C(stopped). - type: str - choices: [ absent, paused, started, stopped, restarted ] - username: - description: - - The username to set the service to start as. - - This and the C(password) argument must be supplied together when using - a local or domain account. - - Set to C(LocalSystem) to use the SYSTEM account. - - A newly created service will default to C(LocalSystem). - - If using a custom user account, it must have the C(SeServiceLogonRight) - granted to be able to start up. You can use the M(win_user_right) module - to grant this user right for you. - type: str - version_added: '2.3' -seealso: -- module: service -- module: win_nssm -- module: win_user_right -author: -- Chris Hoffman (@chrishoffman) -''' - -EXAMPLES = r''' -- name: Restart a service - win_service: - name: spooler - state: restarted - -- name: Set service startup mode to auto and ensure it is started - win_service: - name: spooler - start_mode: auto - state: started - -- name: Pause a service - win_service: - name: Netlogon - state: paused - -- name: Ensure that WinRM is started when the system has settled - win_service: - name: WinRM - start_mode: delayed - -# A new service will also default to the following values: -# - username: LocalSystem -# - state: stopped -# - start_mode: auto -- name: Create a new service - win_service: - name: service name - path: C:\temp\test.exe - -- name: Create a new service with extra details - win_service: - name: service name - path: C:\temp\test.exe - display_name: Service Name - description: A test service description - -- name: Remove a service - win_service: - name: service name - state: absent - -- name: Check if a service is installed - win_service: - name: service name - register: service_info - -# This is required to be set for non-service accounts that need to run as a service -- name: Grant domain account the SeServiceLogonRight user right - win_user_right: - name: SeServiceLogonRight - users: - - DOMAIN\User - action: add - -- name: Set the log on user to a domain account - win_service: - name: service name - state: restarted - username: DOMAIN\User - password: Password - -- name: Set the log on user to a local account - win_service: - name: service name - state: restarted - username: .\Administrator - password: Password - -- name: Set the log on user to Local System - win_service: - name: service name - state: restarted - username: LocalSystem - password: '' - -- name: Set the log on user to Local System and allow it to interact with the desktop - win_service: - name: service name - state: restarted - username: LocalSystem - password: "" - desktop_interact: yes - -- name: Set the log on user to Network Service - win_service: - name: service name - state: restarted - username: NT AUTHORITY\NetworkService - password: '' - -- name: Set the log on user to Local Service - win_service: - name: service name - state: restarted - username: NT AUTHORITY\LocalService - password: '' - -- name: Set dependencies to ones only in the list - win_service: - name: service name - dependencies: [ service1, service2 ] - -- name: Add dependencies to existing dependencies - win_service: - name: service name - dependencies: [ service1, service2 ] - dependency_action: add - -- name: Remove dependencies from existing dependencies - win_service: - name: service name - dependencies: - - service1 - - service2 - dependency_action: remove -''' - -RETURN = r''' -exists: - description: Whether the service exists or not. - returned: success - type: bool - sample: true -name: - description: The service name or id of the service. - returned: success and service exists - type: str - sample: CoreMessagingRegistrar -display_name: - description: The display name of the installed service. - returned: success and service exists - type: str - sample: CoreMessaging -state: - description: The current running status of the service. - returned: success and service exists - type: str - sample: stopped -start_mode: - description: The startup type of the service. - returned: success and service exists - type: str - sample: manual -path: - description: The path to the service executable. - returned: success and service exists - type: str - sample: C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork -can_pause_and_continue: - description: Whether the service can be paused and unpaused. - returned: success and service exists - type: bool - sample: true -description: - description: The description of the service. - returned: success and service exists - type: str - sample: Manages communication between system components. -username: - description: The username that runs the service. - returned: success and service exists - type: str - sample: LocalSystem -desktop_interact: - description: Whether the current user is allowed to interact with the desktop. - returned: success and service exists - type: bool - sample: false -dependencies: - description: A list of services that is depended by this service. - returned: success and service exists - type: list - sample: false -depended_by: - description: A list of services that depend on this service. - returned: success and service exists - type: list - sample: false -''' diff --git a/lib/ansible/modules/windows/win_service_info.ps1 b/lib/ansible/modules/windows/win_service_info.ps1 deleted file mode 100644 index 783d470f76..0000000000 --- a/lib/ansible/modules/windows/win_service_info.ps1 +++ /dev/null @@ -1,207 +0,0 @@ -#!powershell - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#AnsibleRequires -CSharpUtil Ansible.Service - -$spec = @{ - options = @{ - name = @{ type = "str" } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$name = $module.Params.name - -$module.Result.exists = $false -$module.Result.services = @(foreach ($rawService in (Get-Service -Name $name -ErrorAction SilentlyContinue)) { - try { - $service = New-Object -TypeName Ansible.Service.Service -ArgumentList @( - $rawService.Name, [Ansible.Service.ServiceRights]'EnumerateDependents, QueryConfig, QueryStatus' - ) - } catch [Ansible.Service.ServiceManagerException] { - # ERROR_ACCESS_DENIED, ignore the service and continue on. - if ($_.Exception.InnerException -and $_.Exception.InnerException.NativeErrorCode -eq 5) { - $module.Warn("Failed to access service '$($rawService.Name) to get more info, ignoring") - continue - } - - throw - } - $module.Result.exists = $true - - $controlsAccepted = @($service.ControlsAccepted.ToString() -split ',' | ForEach-Object -Process { - switch ($_.Trim()) { - Stop { 'stop' } - PauseContinue { 'pause_continue' } - Shutdown { 'shutdown' } - ParamChange { 'param_change' } - NetbindChange { 'netbind_change' } - HardwareProfileChange { 'hardware_profile_change' } - PowerEvent { 'power_event' } - SessionChange { 'session_change' } - PreShutdown { 'pre_shutdown' } - } - }) - - $rawFailureActions = $service.FailureActions - $failureActions = @(foreach ($action in $rawFailureActions.Actions) { - [Ordered]@{ - type = switch ($action.Type) { - None { 'none' } - Reboot { 'reboot' } - Restart { 'restart' } - RunCommand { 'run_command' } - } - delay_ms = $action.Delay - } - }) - - # LaunchProtection is only valid in Windows 8.1 (2012 R2) or above. - $launchProtection = 'none' - if ($service.LaunchProtection) { - $launchProtection = switch ($service.LaunchProtection) { - None { 'none' } - Windows { 'windows' } - WindowsLight { 'windows_light' } - AntimalwareLight { 'antimalware_light' } - } - } - - $serviceFlags = @($service.ServiceFlags.ToString() -split ',' | ForEach-Object -Process { - switch ($_.Trim()) { - RunsInSystemProcess { 'runs_in_system_process' } - } - }) - - # The ServiceType value can contain other flags which are represented by other properties, this strips them out - # so we don't include them in the service_type return value. - $serviceType = [uint32]$service.ServiceType -band -bnot [uint32][Ansible.Service.ServiceType]::InteractiveProcess - $serviceType = $serviceType -band -bnot [uint32][Ansible.Service.ServiceType]::UserServiceInstance - $serviceType = switch (([Ansible.Service.ServiceType]$serviceType).ToString()) { - KernelDriver { 'kernel_driver' } - FileSystemDriver { 'file_system_driver' } - Adapter { 'adapter' } - RecognizerDriver { 'recognizer_driver' } - Win32OwnProcess { 'win32_own_process' } - Win32ShareProcess { 'win32_share_process' } - UserOwnprocess { 'user_own_process' } - UserShareProcess { 'user_share_process' } - PkgService { 'pkg_service' } - } - - $startType = switch ($service.StartType) { - BootStart { 'boot_start' } - SystemStart { 'system_start' } - AutoStart { 'auto' } - DemandStart { 'manual' } - Disabled { 'disabled' } - AutoStartDelayed { 'delayed' } - } - - $state = switch ($service.State) { - Stopped { 'stopped' } - StartPending { 'start_pending' } - StopPending { 'stop_pending' } - Running { 'started' } - ContinuePending { 'continue_pending' } - PausePending { 'pause_pending' } - paused { 'paused' } - } - - $triggers = @(foreach ($trigger in $service.Triggers) { - [Ordered]@{ - action = switch($trigger.Action) { - ServiceStart { 'start_service' } - ServiceStop { 'stop_service' } - } - type = switch($trigger.Type) { - DeviceInterfaceArrival { 'device_interface_arrival' } - IpAddressAvailability { 'ip_address_availability' } - DomainJoin { 'domain_join' } - FirewallPortEvent { 'firewall_port_event' } - GroupPolicy { 'group_policy' } - NetworkEndpoint { 'network_endpoint' } - Custom { 'custom' } - } - sub_type = switch($trigger.SubType.ToString()) { - ([Ansible.Service.Trigger]::NAMED_PIPE_EVENT_GUID) { 'named_pipe_event' } - ([Ansible.Service.Trigger]::RPC_INTERFACE_EVENT_GUID) { 'rpc_interface_event' } - ([Ansible.Service.Trigger]::DOMAIN_JOIN_GUID) { 'domain_join' } - ([Ansible.Service.Trigger]::DOMAIN_LEAVE_GUID) { 'domain_leave' } - ([Ansible.Service.Trigger]::FIREWALL_PORT_OPEN_GUID) { 'firewall_port_open' } - ([Ansible.Service.Trigger]::FIREWALL_PORT_CLOSE_GUID) { 'firewall_port_close' } - ([Ansible.Service.Trigger]::MACHINE_POLICY_PRESENT_GUID) { 'machine_policy_present' } - ([Ansible.Service.Trigger]::USER_POLICY_PRESENT_GUID) { 'user_policy_present' } - ([Ansible.Service.Trigger]::NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID) { 'network_first_ip_arrival' } - ([Ansible.Service.Trigger]::NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID) { 'network_last_ip_removal' } - default { 'custom' } - } - sub_type_guid = $trigger.SubType.ToString() - data_items = @(foreach ($dataItem in $trigger.DataItems) { - $dataValue = $dataItem.Data - - # We only need to convert byte and byte[] to a Base64 string, the rest can be serialised as is. - if ($dataValue -is [byte]) { - $dataValue = [byte[]]@($dataValue) - } - - if ($dataValue -is [byte[]]) { - $dataValue = [System.Convert]::ToBase64String($dataValue) - } - - [Ordered]@{ - type = switch ($dataItem.Type) { - Binary { 'binary' } - String { 'string' } - Level { 'level' } - KeywordAny { 'keyword_any' } - KeywordAll { 'keyword_all' } - } - data = $dataValue - } - }) - } - }) - - # These should closely reflect the options for win_service - [Ordered]@{ - checkpoint = $service.Checkpoint - controls_accepted = $controlsAccepted - dependencies = $service.DependentOn - dependency_of = $service.DependedBy - description = $service.Description - desktop_interact = $service.ServiceType.HasFlag([Ansible.Service.ServiceType]::InteractiveProcess) - display_name = $service.DisplayName - error_control = $service.ErrorControl.ToString().ToLowerInvariant() - failure_actions = $failureActions - failure_actions_on_non_crash_failure = $service.FailureActionsOnNonCrashFailures - failure_command = $rawFailureActions.Command - failure_reboot_msg = $rawFailureActions.RebootMsg - failure_reset_period_sec = $rawFailureActions.ResetPeriod - launch_protection = $launchProtection - load_order_group = $service.LoadOrderGroup - name = $service.ServiceName - path = $service.Path - pre_shutdown_timeout_ms = $service.PreShutdownTimeout - preferred_node = $service.PreferredNode - process_id = $service.ProcessId - required_privileges = $service.RequiredPrivileges - service_exit_code = $service.ServiceExitCode - service_flags = $serviceFlags - service_type = $serviceType - sid_info = $service.ServiceSidInfo.ToString().ToLowerInvariant() - start_mode = $startType - state = $state - triggers = $triggers - username = $service.Account.Value - wait_hint_ms = $service.WaitHint - win32_exit_code = $service.Win32ExitCode - } -}) - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_service_info.py b/lib/ansible/modules/windows/win_service_info.py deleted file mode 100644 index a3fbf49d87..0000000000 --- a/lib/ansible/modules/windows/win_service_info.py +++ /dev/null @@ -1,294 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_service_info -version_added: '2.10' -short_description: Gather information about Windows services -description: -- Gather information about all or a specific installed Windows service(s). -options: - name: - description: - - If specified, this is used to match the C(name) or C(display_name) of the Windows service to get the info for. - - Can be a wildcard to match multiple services but the wildcard will only be matched on the C(name) of the service - and not C(display_name). - - If omitted then all services will returned. - type: str -seealso: -- module: win_service -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Get info for all installed services - win_service_info: - register: service_info - -- name: Get info for a single service - win_service_info: - name: WinRM - register: service_info - -- name: Get info for a service using its display name - win_service_info: - name: Windows Remote Management (WS-Management) - -- name: Find all services that start with 'win' - win_service_info: - name: win* -''' - -RETURN = r''' -exists: - description: Whether any services were found based on the criteria specified. - returned: always - type: bool - sample: true -services: - description: - - A list of service(s) that were found based on the criteria. - - Will be an empty list if no services were found. - returned: always - type: list - elements: dict - contains: - checkpoint: - description: - - A check-point value that the service increments periodically to report its progress. - type: int - sample: 0 - controls_accepted: - description: - - A list of controls that the service can accept. - - Common controls are C(stop), C(pause_continue), C(shutdown). - type: list - elements: str - sample: ['stop', 'shutdown'] - dependencies: - description: - - A list of services by their C(name) that this service is dependent on. - type: list - elements: str - sample: ['HTTP', 'RPCSS'] - dependency_of: - description: - - A list of services by their C(name) that depend on this service. - type: list - elements: str - sample: ['upnphost', 'WMPNetworkSvc'] - description: - description: - - The description of the service. - type: str - sample: Example description of the Windows service. - desktop_interact: - description: - - Whether the service can interact with the desktop, only valid for services running as C(SYSTEM). - type: bool - sample: false - display_name: - description: - - The display name to be used by SCM to identify the service. - type: str - sample: Windows Remote Management (WS-Management) - error_control: - description: - - The action to take if a service fails to start. - - Common values are C(critical), C(ignore), C(normal), C(severe). - type: str - sample: normal - failure_actions: - description: - - A list of failure actions to run in the event of a failure. - type: list - elements: dict - contains: - delay_ms: - description: - - The time to wait, in milliseconds, before performing the specified action. - type: int - sample: 120000 - type: - description: - - The action that will be performed. - - Common values are C(none), C(reboot), C(restart), C(run_command). - type: str - sample: run_command - failure_action_on_non_crash_failure: - description: - - Controls when failure actions are fired based on how the service was stopped. - type: bool - sample: false - failure_command: - description: - - The command line that will be run when a C(run_command) failure action is fired. - type: str - sample: runme.exe - failure_reboot_msg: - description: - - The message to be broadcast to server users before rebooting when a C(reboot) failure action is fired. - type: str - sample: Service failed, rebooting host. - failure_reset_period_sec: - description: - - The time, in seconds, after which to reset the failure count to zero. - type: int - sample: 86400 - launch_protection: - description: - - The protection type of the service. - - Common values are C(none), C(windows), C(windows_light), or C(antimalware_light). - type: str - sample: none - load_order_group: - description: - - The name of the load ordering group to which the service belongs. - - Will be an empty string if it does not belong to any group. - type: str - sample: My group - name: - description: - - The name of the service. - type: str - sample: WinRM - path: - description: - - The path to the service binary and any arguments used when starting the service. - - The binary part can be quoted to ensure any spaces in path are not treated as arguments. - type: str - sample: 'C:\Windows\System32\svchost.exe -k netsvcs -p' - pre_shutdown_timeout_ms: - description: - - The preshutdown timeout out value in milliseconds. - type: int - sample: 10000 - preferred_node: - description: - - The node number for the preferred node. - - This will be C(null) if the Windows host has no NUMA configuration. - type: int - sample: 0 - process_id: - description: - - The process identifier of the running service. - type: int - sample: 5135 - required_privileges: - description: - - A list of privileges that the service requires and will run with - type: list - elements: str - sample: ['SeBackupPrivilege', 'SeRestorePrivilege'] - service_exit_code: - description: - - A service-specific error code that is set while the service is starting or stopping. - type: int - sample: 0 - service_flags: - description: - - Shows more information about the behaviour of a running service. - - Currently the only flag that can be set is C(runs_in_system_process). - type: list - elements: str - sample: [ 'runs_in_system_process' ] - service_type: - description: - - The type of service. - - Common types are C(win32_own_process), C(win32_share_process), C(user_own_process), C(user_share_process), - C(kernel_driver). - type: str - sample: win32_own_process - sid_info: - description: - - The behavior of how the service's access token is generated and how to add the service SID to the token. - - Common values are C(none), C(restricted), or C(unrestricted). - type: str - sample: none - start_mode: - description: - - When the service is set to start. - - Common values are C(auto), C(manual), C(disabled), C(delayed). - type: str - sample: auto - state: - description: - - The current running state of the service. - - Common values are C(stopped), C(start_pending), C(stop_pending), C(started), C(continue_pending), - C(pause_pending), C(paused). - type: str - sample: started - triggers: - description: - - A list of triggers defined for the service. - type: list - elements: dict - contains: - action: - description: - - The action to perform once triggered, can be C(start_service) or C(stop_service). - type: str - sample: start_service - data_items: - description: - - A list of trigger data items that contain trigger specific data. - - A trigger can contain 0 or multiple data items. - type: list - elements: dict - contains: - data: - description: - - The trigger data item value. - - Can be a string, list of string, int, or base64 string of binary data. - type: complex - sample: named pipe - type: - description: - - The type of C(data) for the trigger. - - Common values are C(string), C(binary), C(level), C(keyword_any), or C(keyword_all). - type: str - sample: string - sub_type: - description: - - The trigger event sub type that is specific to each C(type). - - Common values are C(named_pipe_event), C(domain_join), C(domain_leave), C(firewall_port_open), and others. - type: str - sample: - sub_type_guid: - description: - - The guid which represents the trigger sub type. - type: str - sample: 1ce20aba-9851-4421-9430-1ddeb766e809 - type: - description: - - The trigger event type. - - Common values are C(custom), C(rpc_interface_event), C(domain_join), C(group_policy), and others. - type: str - sample: domain_join - username: - description: - - The username used to run the service. - - Can be null for user services and certain driver services. - type: str - sample: NT AUTHORITY\SYSTEM - wait_hint_ms: - description: - - The estimated time in milliseconds required for a pending start, stop, pause,or continue operations. - type: int - sample: 0 - win32_exitcode: - description: - - The error code returned from the service binary once it has stopped. - - When set to C(1066) then a service specific error is returned on C(service_exit_code). - type: int - sample: 0 -''' diff --git a/lib/ansible/modules/windows/win_share.ps1 b/lib/ansible/modules/windows/win_share.ps1 deleted file mode 100644 index d48f74d07e..0000000000 --- a/lib/ansible/modules/windows/win_share.ps1 +++ /dev/null @@ -1,267 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -#Functions -Function NormalizeAccounts { - param( - [parameter(valuefrompipeline=$true)] - $users - ) - - $users = $users.Trim() - If ($users -eq "") { - $splitUsers = [Collections.Generic.List[String]] @() - } - Else { - $splitUsers = [Collections.Generic.List[String]] $users.Split(",") - } - - $normalizedUsers = [Collections.Generic.List[String]] @() - ForEach($splitUser in $splitUsers) { - $sid = Convert-ToSID -account_name $splitUser - if (!$sid) { - Fail-Json $result "$splitUser is not a valid user or group on the host machine or domain" - } - - $normalizedUser = (New-Object System.Security.Principal.SecurityIdentifier($sid)).Translate([System.Security.Principal.NTAccount]) - $normalizedUsers.Add($normalizedUser) - } - - return ,$normalizedUsers -} - -$result = @{ - changed = $false - actions = @() # More for debug purposes -} - -$params = Parse-Args $args -supports_check_mode $true - -# While the -SmbShare cmdlets have a -WhatIf parameter, they don't honor it, need to skip the cmdlet if in check mode -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" -$rule_action = Get-AnsibleParam -obj $params -name "rule_action" -type "str" -default "set" -validateset "set","add" - -if (-not (Get-Command -Name Get-SmbShare -ErrorAction SilentlyContinue)) { - Fail-Json $result "The current host does not support the -SmbShare cmdlets required by this module. Please run on Server 2012 or Windows 8 and later" -} - -$share = Get-SmbShare -Name $name -ErrorAction SilentlyContinue -If ($state -eq "absent") { - If ($share) { - # See message around -WhatIf where $check_mode is defined - if (-not $check_mode) { - Remove-SmbShare -Force -Name $name | Out-Null - } - $result.actions += "Remove-SmbShare -Force -Name $name" - $result.changed = $true - } -} Else { - $path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true - $description = Get-AnsibleParam -obj $params -name "description" -type "str" -default "" - - $permissionList = Get-AnsibleParam -obj $params -name "list" -type "bool" -default $false - $folderEnum = if ($permissionList) { "Unrestricted" } else { "AccessBased" } - - $permissionRead = Get-AnsibleParam -obj $params -name "read" -type "str" -default "" | NormalizeAccounts - $permissionChange = Get-AnsibleParam -obj $params -name "change" -type "str" -default "" | NormalizeAccounts - $permissionFull = Get-AnsibleParam -obj $params -name "full" -type "str" -default "" | NormalizeAccounts - $permissionDeny = Get-AnsibleParam -obj $params -name "deny" -type "str" -default "" | NormalizeAccounts - - $cachingMode = Get-AnsibleParam -obj $params -name "caching_mode" -type "str" -default "Manual" -validateSet "BranchCache","Documents","Manual","None","Programs","Unknown" - $encrypt = Get-AnsibleParam -obj $params -name "encrypt" -type "bool" -default $false - - If (-Not (Test-Path -Path $path)) { - Fail-Json $result "$path directory does not exist on the host" - } - - # normalize path and remove slash at the end - $path = (Get-Item $path).FullName -replace "\\$" - - # need to (re-)create share - If (-not $share) { - if (-not $check_mode) { - New-SmbShare -Name $name -Path $path | Out-Null - } - $share = Get-SmbShare -Name $name -ErrorAction SilentlyContinue - - $result.changed = $true - $result.actions += "New-SmbShare -Name $name -Path $path" - # if in check mode we cannot run the below as no share exists so just - # exit early - if ($check_mode) { - Exit-Json -obj $result - } - } - If ($share.Path -ne $path) { - if (-not $check_mode) { - Remove-SmbShare -Force -Name $name | Out-Null - New-SmbShare -Name $name -Path $path | Out-Null - } - $share = Get-SmbShare -Name $name -ErrorAction SilentlyContinue - $result.changed = $true - $result.actions += "Remove-SmbShare -Force -Name $name" - $result.actions += "New-SmbShare -Name $name -Path $path" - } - - # updates - If ($share.Description -ne $description) { - if (-not $check_mode) { - Set-SmbShare -Force -Name $name -Description $description | Out-Null - } - $result.changed = $true - $result.actions += "Set-SmbShare -Force -Name $name -Description $description" - } - If ($share.FolderEnumerationMode -ne $folderEnum) { - if (-not $check_mode) { - Set-SmbShare -Force -Name $name -FolderEnumerationMode $folderEnum | Out-Null - } - $result.changed = $true - $result.actions += "Set-SmbShare -Force -Name $name -FolderEnumerationMode $folderEnum" - } - if ($share.CachingMode -ne $cachingMode) { - if (-not $check_mode) { - Set-SmbShare -Force -Name $name -CachingMode $cachingMode | Out-Null - } - $result.changed = $true - $result.actions += "Set-SmbShare -Force -Name $name -CachingMode $cachingMode" - } - if ($share.EncryptData -ne $encrypt) { - if (-not $check_mode) { - Set-SmbShare -Force -Name $name -EncryptData $encrypt | Out-Null - } - $result.changed = $true - $result.actions += "Set-SmbShare -Force -Name $name -EncryptData $encrypt" - } - - # clean permissions that imply others - ForEach ($user in $permissionFull) { - $permissionChange.remove($user) | Out-Null - $permissionRead.remove($user) | Out-Null - } - ForEach ($user in $permissionChange) { - $permissionRead.remove($user) | Out-Null - } - - # remove permissions - $permissions = Get-SmbShareAccess -Name $name - if($rule_action -eq "set") { - ForEach ($permission in $permissions) { - If ($permission.AccessControlType -eq "Deny") { - $cim_count = 0 - foreach ($count in $permissions) { - $cim_count++ - } - # Don't remove the Deny entry for Everyone if there are no other permissions set (cim_count == 1) - if (-not ($permission.AccountName -eq 'Everyone' -and $cim_count -eq 1)) { - If (-not ($permissionDeny.Contains($permission.AccountName))) { - if (-not $check_mode) { - Unblock-SmbShareAccess -Force -Name $name -AccountName $permission.AccountName | Out-Null - } - $result.changed = $true - $result.actions += "Unblock-SmbShareAccess -Force -Name $name -AccountName $($permission.AccountName)" - } else { - # Remove from the deny list as it already has the permissions - $permissionDeny.remove($permission.AccountName) | Out-Null - } - } - } ElseIf ($permission.AccessControlType -eq "Allow") { - If ($permission.AccessRight -eq "Full") { - If (-not ($permissionFull.Contains($permission.AccountName))) { - if (-not $check_mode) { - Revoke-SmbShareAccess -Force -Name $name -AccountName $permission.AccountName | Out-Null - } - $result.changed = $true - $result.actions += "Revoke-SmbShareAccess -Force -Name $name -AccountName $($permission.AccountName)" - - Continue - } - - # user got requested permissions - $permissionFull.remove($permission.AccountName) | Out-Null - } ElseIf ($permission.AccessRight -eq "Change") { - If (-not ($permissionChange.Contains($permission.AccountName))) { - if (-not $check_mode) { - Revoke-SmbShareAccess -Force -Name $name -AccountName $permission.AccountName | Out-Null - } - $result.changed = $true - $result.actions += "Revoke-SmbShareAccess -Force -Name $name -AccountName $($permission.AccountName)" - - Continue - } - - # user got requested permissions - $permissionChange.remove($permission.AccountName) | Out-Null - } ElseIf ($permission.AccessRight -eq "Read") { - If (-not ($permissionRead.Contains($permission.AccountName))) { - if (-not $check_mode) { - Revoke-SmbShareAccess -Force -Name $name -AccountName $permission.AccountName | Out-Null - } - $result.changed = $true - $result.actions += "Revoke-SmbShareAccess -Force -Name $name -AccountName $($permission.AccountName)" - - Continue - } - - # user got requested permissions - $permissionRead.Remove($permission.AccountName) | Out-Null - } - } - } - } ElseIf ($rule_action -eq "add") { - ForEach($permission in $permissions) { - If ($permission.AccessControlType -eq "Deny") { - If ($permissionDeny.Contains($permission.AccountName)) { - $permissionDeny.Remove($permission.AccountName) - } - } ElseIf ($permission.AccessControlType -eq "Allow") { - If ($permissionFull.Contains($permission.AccountName) -and $permission.AccessRight -eq "Full") { - $permissionFull.Remove($permission.AccountName) - } ElseIf ($permissionChange.Contains($permission.AccountName) -and $permission.AccessRight -eq "Change") { - $permissionChange.Remove($permission.AccountName) - } ElseIf ($permissionRead.Contains($permission.AccountName) -and $permission.AccessRight -eq "Read") { - $permissionRead.Remove($permission.AccountName) - } - } - } - } - - # add missing permissions - ForEach ($user in $permissionRead) { - if (-not $check_mode) { - Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight "Read" | Out-Null - } - $result.changed = $true - $result.actions += "Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight Read" - } - ForEach ($user in $permissionChange) { - if (-not $check_mode) { - Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight "Change" | Out-Null - } - $result.changed = $true - $result.actions += "Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight Change" - } - ForEach ($user in $permissionFull) { - if (-not $check_mode) { - Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight "Full" | Out-Null - } - $result.changed = $true - $result.actions += "Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight Full" - } - ForEach ($user in $permissionDeny) { - if (-not $check_mode) { - Block-SmbShareAccess -Force -Name $name -AccountName $user | Out-Null - } - $result.changed = $true - $result.actions += "Block-SmbShareAccess -Force -Name $name -AccountName $user" - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_share.py b/lib/ansible/modules/windows/win_share.py deleted file mode 100644 index c0b005a5ad..0000000000 --- a/lib/ansible/modules/windows/win_share.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_share -version_added: "2.1" -short_description: Manage Windows shares -description: - - Add, modify or remove Windows share and set share permissions. -requirements: - - As this module used newer cmdlets like New-SmbShare this can only run on - Windows 8 / Windows 2012 or newer. - - This is due to the reliance on the WMI provider MSFT_SmbShare - U(https://msdn.microsoft.com/en-us/library/hh830471) which was only added - with these Windows releases. -options: - name: - description: - - Share name. - type: str - required: yes - path: - description: - - Share directory. - type: path - required: yes - state: - description: - - Specify whether to add C(present) or remove C(absent) the specified share. - type: str - choices: [ absent, present ] - default: present - description: - description: - - Share description. - type: str - list: - description: - - Specify whether to allow or deny file listing, in case user has no permission on share. Also known as Access-Based Enumeration. - type: bool - default: no - read: - description: - - Specify user list that should get read access on share, separated by comma. - type: str - change: - description: - - Specify user list that should get read and write access on share, separated by comma. - type: str - full: - description: - - Specify user list that should get full access on share, separated by comma. - type: str - deny: - description: - - Specify user list that should get no access, regardless of implied access on share, separated by comma. - type: str - caching_mode: - description: - - Set the CachingMode for this share. - type: str - choices: [ BranchCache, Documents, Manual, None, Programs, Unknown ] - default: Manual - version_added: "2.3" - encrypt: - description: Sets whether to encrypt the traffic to the share or not. - type: bool - default: no - version_added: "2.4" - rule_action: - description: Whether to add or set (replace) access control entries. - type: str - choices: [ set, add ] - default: set - version_added: "2.10" -author: - - Hans-Joachim Kliemeck (@h0nIg) - - David Baumann (@daBONDi) - - Shachaf Goldstein (@Shachaf92) -''' - -EXAMPLES = r''' -# Playbook example -# Add share and set permissions ---- -- name: Add secret share - win_share: - name: internal - description: top secret share - path: C:\shares\internal - list: no - full: Administrators,CEO - read: HR-Global - deny: HR-External - -- name: Add public company share - win_share: - name: company - description: top secret share - path: C:\shares\company - list: yes - full: Administrators,CEO - read: Global - -- name: Remove previously added share - win_share: - name: internal - state: absent -''' - -RETURN = r''' -actions: - description: A list of action cmdlets that were run by the module. - returned: success - type: list - sample: ['New-SmbShare -Name share -Path C:\temp'] -''' diff --git a/lib/ansible/modules/windows/win_shell.ps1 b/lib/ansible/modules/windows/win_shell.ps1 deleted file mode 100644 index 54aef8de12..0000000000 --- a/lib/ansible/modules/windows/win_shell.ps1 +++ /dev/null @@ -1,138 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.CommandUtil -#Requires -Module Ansible.ModuleUtils.FileUtil - -# TODO: add check mode support - -Set-StrictMode -Version 2 -$ErrorActionPreference = "Stop" - -# Cleanse CLIXML from stderr (sift out error stream data, discard others for now) -Function Cleanse-Stderr($raw_stderr) { - Try { - # NB: this regex isn't perfect, but is decent at finding CLIXML amongst other stderr noise - If($raw_stderr -match "(?s)(?<prenoise1>.*)#< CLIXML(?<prenoise2>.*)(?<clixml><Objs.+</Objs>)(?<postnoise>.*)") { - $clixml = [xml]$matches["clixml"] - - $merged_stderr = "{0}{1}{2}{3}" -f @( - $matches["prenoise1"], - $matches["prenoise2"], - # filter out just the Error-tagged strings for now, and zap embedded CRLF chars - ($clixml.Objs.ChildNodes | Where-Object { $_.Name -eq 'S' } | Where-Object { $_.S -eq 'Error' } | ForEach-Object { $_.'#text'.Replace('_x000D__x000A_','') } | Out-String), - $matches["postnoise"]) | Out-String - - return $merged_stderr.Trim() - - # FUTURE: parse/return other streams - } - Else { - $raw_stderr - } - } - Catch { - "***EXCEPTION PARSING CLIXML: $_***" + $raw_stderr - } -} - -$params = Parse-Args $args -supports_check_mode $false - -$raw_command_line = Get-AnsibleParam -obj $params -name "_raw_params" -type "str" -failifempty $true -$chdir = Get-AnsibleParam -obj $params -name "chdir" -type "path" -$executable = Get-AnsibleParam -obj $params -name "executable" -type "path" -$creates = Get-AnsibleParam -obj $params -name "creates" -type "path" -$removes = Get-AnsibleParam -obj $params -name "removes" -type "path" -$stdin = Get-AnsibleParam -obj $params -name "stdin" -type "str" -$no_profile = Get-AnsibleParam -obj $params -name "no_profile" -type "bool" -default $false -$output_encoding_override = Get-AnsibleParam -obj $params -name "output_encoding_override" -type "str" - -$raw_command_line = $raw_command_line.Trim() - -$result = @{ - changed = $true - cmd = $raw_command_line -} - -if ($creates -and $(Test-AnsiblePath -Path $creates)) { - Exit-Json @{msg="skipped, since $creates exists";cmd=$raw_command_line;changed=$false;skipped=$true;rc=0} -} - -if ($removes -and -not $(Test-AnsiblePath -Path $removes)) { - Exit-Json @{msg="skipped, since $removes does not exist";cmd=$raw_command_line;changed=$false;skipped=$true;rc=0} -} - -$exec_args = $null -If(-not $executable -or $executable -eq "powershell") { - $exec_application = "powershell.exe" - - # force input encoding to preamble-free UTF8 so PS sub-processes (eg, Start-Job) don't blow up - $raw_command_line = "[Console]::InputEncoding = New-Object Text.UTF8Encoding `$false; " + $raw_command_line - - # Base64 encode the command so we don't have to worry about the various levels of escaping - $encoded_command = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($raw_command_line)) - - if ($stdin) { - $exec_args = "-encodedcommand $encoded_command" - } else { - $exec_args = "-noninteractive -encodedcommand $encoded_command" - } - - if ($no_profile) { - $exec_args = "-noprofile $exec_args" - } -} -Else { - # FUTURE: support arg translation from executable (or executable_args?) to process arguments for arbitrary interpreter? - $exec_application = $executable - if (-not ($exec_application.EndsWith(".exe"))) { - $exec_application = "$($exec_application).exe" - } - $exec_args = "/c $raw_command_line" -} - -$command = "`"$exec_application`" $exec_args" -$run_command_arg = @{ - command = $command -} -if ($chdir) { - $run_command_arg['working_directory'] = $chdir -} -if ($stdin) { - $run_command_arg['stdin'] = $stdin -} -if ($output_encoding_override) { - $run_command_arg['output_encoding_override'] = $output_encoding_override -} - -$start_datetime = [DateTime]::UtcNow -try { - $command_result = Run-Command @run_command_arg -} catch { - $result.changed = $false - try { - $result.rc = $_.Exception.NativeErrorCode - } catch { - $result.rc = 2 - } - Fail-Json -obj $result -message $_.Exception.Message -} - -# TODO: decode CLIXML stderr output (and other streams?) -$result.stdout = $command_result.stdout -$result.stderr = Cleanse-Stderr $command_result.stderr -$result.rc = $command_result.rc - -$end_datetime = [DateTime]::UtcNow -$result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") -$result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff") - -If ($result.rc -ne 0) { - Fail-Json -obj $result -message "non-zero return code" -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_shell.py b/lib/ansible/modules/windows/win_shell.py deleted file mode 100644 index ee2cd76240..0000000000 --- a/lib/ansible/modules/windows/win_shell.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Ansible, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_shell -short_description: Execute shell commands on target hosts -version_added: 2.2 -description: - - The C(win_shell) module takes the command name followed by a list of space-delimited arguments. - It is similar to the M(win_command) module, but runs - the command via a shell (defaults to PowerShell) on the target host. - - For non-Windows targets, use the M(shell) module instead. -options: - free_form: - description: - - The C(win_shell) module takes a free form command to run. - - There is no parameter actually named 'free form'. See the examples! - type: str - required: yes - creates: - description: - - A path or path filter pattern; when the referenced path exists on the target host, the task will be skipped. - type: path - removes: - description: - - A path or path filter pattern; when the referenced path B(does not) exist on the target host, the task will be skipped. - type: path - chdir: - description: - - Set the specified path as the current working directory before executing a command - type: path - executable: - description: - - Change the shell used to execute the command (eg, C(cmd)). - - The target shell must accept a C(/c) parameter followed by the raw command line to be executed. - type: path - stdin: - description: - - Set the stdin of the command directly to the specified value. - type: str - version_added: '2.5' - no_profile: - description: - - Do not load the user profile before running a command. This is only valid - when using PowerShell as the executable. - type: bool - default: no - version_added: '2.8' - output_encoding_override: - description: - - This option overrides the encoding of stdout/stderr output. - - You can use this option when you need to run a command which ignore the console's codepage. - - You should only need to use this option in very rare circumstances. - - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). - See U(https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings). - type: str - version_added: '2.10' -notes: - - If you want to run an executable securely and predictably, it may be - better to use the M(win_command) module instead. Best practices when writing - playbooks will follow the trend of using M(win_command) unless C(win_shell) is - explicitly required. When running ad-hoc commands, use your best judgement. - - WinRM will not return from a command execution until all child processes created have exited. - Thus, it is not possible to use C(win_shell) to spawn long-running child or background processes. - Consider creating a Windows service for managing background processes. -seealso: -- module: psexec -- module: raw -- module: script -- module: shell -- module: win_command -- module: win_psexec -author: - - Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -# Execute a command in the remote shell; stdout goes to the specified -# file on the remote. -- win_shell: C:\somescript.ps1 >> C:\somelog.txt - -# Change the working directory to somedir/ before executing the command. -- win_shell: C:\somescript.ps1 >> C:\somelog.txt chdir=C:\somedir - -# You can also use the 'args' form to provide the options. This command -# will change the working directory to somedir/ and will only run when -# somedir/somelog.txt doesn't exist. -- win_shell: C:\somescript.ps1 >> C:\somelog.txt - args: - chdir: C:\somedir - creates: C:\somelog.txt - -# Run a command under a non-Powershell interpreter (cmd in this case) -- win_shell: echo %HOMEDIR% - args: - executable: cmd - register: homedir_out - -- name: Run multi-lined shell commands - win_shell: | - $value = Test-Path -Path C:\temp - if ($value) { - Remove-Item -Path C:\temp -Force - } - New-Item -Path C:\temp -ItemType Directory - -- name: Retrieve the input based on stdin - win_shell: '$string = [Console]::In.ReadToEnd(); Write-Output $string.Trim()' - args: - stdin: Input message -''' - -RETURN = r''' -msg: - description: Changed. - returned: always - type: bool - sample: true -start: - description: The command execution start time. - returned: always - type: str - sample: '2016-02-25 09:18:26.429568' -end: - description: The command execution end time. - returned: always - type: str - sample: '2016-02-25 09:18:26.755339' -delta: - description: The command execution delta time. - returned: always - type: str - sample: '0:00:00.325771' -stdout: - description: The command standard output. - returned: always - type: str - sample: 'Clustering node rabbit@slave1 with rabbit@master ...' -stderr: - description: The command standard error. - returned: always - type: str - sample: 'ls: cannot access foo: No such file or directory' -cmd: - description: The command executed by the task. - returned: always - type: str - sample: 'rabbitmqctl join_cluster rabbit@master' -rc: - description: The command return code (0 means success). - returned: always - type: int - sample: 0 -stdout_lines: - description: The command standard output split in lines. - returned: always - type: list - sample: [u'Clustering node rabbit@slave1 with rabbit@master ...'] -''' diff --git a/lib/ansible/modules/windows/win_stat.ps1 b/lib/ansible/modules/windows/win_stat.ps1 deleted file mode 100644 index 071eb11ceb..0000000000 --- a/lib/ansible/modules/windows/win_stat.ps1 +++ /dev/null @@ -1,186 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.FileUtil -#Requires -Module Ansible.ModuleUtils.LinkUtil - -function ConvertTo-Timestamp($start_date, $end_date) { - if ($start_date -and $end_date) { - return (New-TimeSpan -Start $start_date -End $end_date).TotalSeconds - } -} - -function Get-FileChecksum($path, $algorithm) { - switch ($algorithm) { - 'md5' { $sp = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider } - 'sha1' { $sp = New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider } - 'sha256' { $sp = New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider } - 'sha384' { $sp = New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider } - 'sha512' { $sp = New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider } - default { Fail-Json -obj $result -message "Unsupported hash algorithm supplied '$algorithm'" } - } - - $fp = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) - try { - $hash = [System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower() - } finally { - $fp.Dispose() - } - - return $hash -} - -function Get-FileInfo { - param([String]$Path, [Switch]$Follow) - - $info = Get-AnsibleItem -Path $Path -ErrorAction SilentlyContinue - $link_info = $null - if ($null -ne $info) { - try { - $link_info = Get-Link -link_path $info.FullName - } catch { - $module.Warn("Failed to check/get link info for file: $($_.Exception.Message)") - } - - # If follow=true we want to follow the link all the way back to root object - if ($Follow -and $null -ne $link_info -and $link_info.Type -in @("SymbolicLink", "JunctionPoint")) { - $info, $link_info = Get-FileInfo -Path $link_info.AbsolutePath -Follow - } - } - - return $info, $link_info -} - -$spec = @{ - options = @{ - path = @{ type='path'; required=$true; aliases=@( 'dest', 'name' ) } - get_checksum = @{ type='bool'; default=$true } - checksum_algorithm = @{ type='str'; default='sha1'; choices=@( 'md5', 'sha1', 'sha256', 'sha384', 'sha512' ) } - follow = @{ type='bool'; default=$false } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$path = $module.Params.path -$get_checksum = $module.Params.get_checksum -$checksum_algorithm = $module.Params.checksum_algorithm -$follow = $module.Params.follow - -$module.Result.stat = @{ exists=$false } - -Load-LinkUtils -$info, $link_info = Get-FileInfo -Path $path -Follow:$follow -If ($null -ne $info) { - $epoch_date = Get-Date -Date "01/01/1970" - $attributes = @() - foreach ($attribute in ($info.Attributes -split ',')) { - $attributes += $attribute.Trim() - } - - # default values that are always set, specific values are set below this - # but are kept commented for easier readability - $stat = @{ - exists = $true - attributes = $info.Attributes.ToString() - isarchive = ($attributes -contains "Archive") - isdir = $false - ishidden = ($attributes -contains "Hidden") - isjunction = $false - islnk = $false - isreadonly = ($attributes -contains "ReadOnly") - isreg = $false - isshared = $false - nlink = 1 # Number of links to the file (hard links), overriden below if islnk - # lnk_target = islnk or isjunction Target of the symlink. Note that relative paths remain relative - # lnk_source = islnk os isjunction Target of the symlink normalized for the remote filesystem - hlnk_targets = @() - creationtime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.CreationTime) - lastaccesstime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.LastAccessTime) - lastwritetime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.LastWriteTime) - # size = a file and directory - calculated below - path = $info.FullName - filename = $info.Name - # extension = a file - # owner = set outsite this dict in case it fails - # sharename = a directory and isshared is True - # checksum = a file and get_checksum: True - } - try { - $stat.owner = $info.GetAccessControl().Owner - } catch { - # may not have rights, historical behaviour was to just set to $null - # due to ErrorActionPreference being set to "Continue" - $stat.owner = $null - } - - # values that are set according to the type of file - if ($info.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) { - $stat.isdir = $true - $share_info = Get-CimInstance -ClassName Win32_Share -Filter "Path='$($stat.path -replace '\\', '\\')'" - if ($null -ne $share_info) { - $stat.isshared = $true - $stat.sharename = $share_info.Name - } - - try { - $size = 0 - foreach ($file in $info.EnumerateFiles("*", [System.IO.SearchOption]::AllDirectories)) { - $size += $file.Length - } - $stat.size = $size - } catch { - $stat.size = 0 - } - } else { - $stat.extension = $info.Extension - $stat.isreg = $true - $stat.size = $info.Length - - if ($get_checksum) { - try { - $stat.checksum = Get-FileChecksum -path $path -algorithm $checksum_algorithm - } catch { - $module.FailJson("Failed to get hash of file, set get_checksum to False to ignore this error: $($_.Exception.Message)", $_) - } - } - } - - # Get symbolic link, junction point, hard link info - if ($null -ne $link_info) { - switch ($link_info.Type) { - "SymbolicLink" { - $stat.islnk = $true - $stat.isreg = $false - $stat.lnk_target = $link_info.TargetPath - $stat.lnk_source = $link_info.AbsolutePath - break - } - "JunctionPoint" { - $stat.isjunction = $true - $stat.isreg = $false - $stat.lnk_target = $link_info.TargetPath - $stat.lnk_source = $link_info.AbsolutePath - break - } - "HardLink" { - $stat.lnk_type = "hard" - $stat.nlink = $link_info.HardTargets.Count - - # remove current path from the targets - $hlnk_targets = $link_info.HardTargets | Where-Object { $_ -ne $stat.path } - $stat.hlnk_targets = @($hlnk_targets) - break - } - } - } - - $module.Result.stat = $stat -} - -$module.ExitJson() - diff --git a/lib/ansible/modules/windows/win_stat.py b/lib/ansible/modules/windows/win_stat.py deleted file mode 100644 index 0676b5b235..0000000000 --- a/lib/ansible/modules/windows/win_stat.py +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_stat -version_added: "1.7" -short_description: Get information about Windows files -description: - - Returns information about a Windows file. - - For non-Windows targets, use the M(stat) module instead. -options: - path: - description: - - The full path of the file/object to get the facts of; both forward and - back slashes are accepted. - type: path - required: yes - aliases: [ dest, name ] - get_checksum: - description: - - Whether to return a checksum of the file (default sha1) - type: bool - default: yes - version_added: "2.1" - checksum_algorithm: - description: - - Algorithm to determine checksum of file. - - Will throw an error if the host is unable to use specified algorithm. - type: str - default: sha1 - choices: [ md5, sha1, sha256, sha384, sha512 ] - version_added: "2.3" - follow: - description: - - Whether to follow symlinks or junction points. - - In the case of C(path) pointing to another link, then that will - be followed until no more links are found. - type: bool - default: no - version_added: "2.8" -seealso: -- module: stat -- module: win_acl -- module: win_file -- module: win_owner -author: -- Chris Church (@cchurch) -''' - -EXAMPLES = r''' -- name: Obtain information about a file - win_stat: - path: C:\foo.ini - register: file_info - -- name: Obtain information about a folder - win_stat: - path: C:\bar - register: folder_info - -- name: Get MD5 checksum of a file - win_stat: - path: C:\foo.ini - get_checksum: yes - checksum_algorithm: md5 - register: md5_checksum - -- debug: - var: md5_checksum.stat.checksum - -- name: Get SHA1 checksum of file - win_stat: - path: C:\foo.ini - get_checksum: yes - register: sha1_checksum - -- debug: - var: sha1_checksum.stat.checksum - -- name: Get SHA256 checksum of file - win_stat: - path: C:\foo.ini - get_checksum: yes - checksum_algorithm: sha256 - register: sha256_checksum - -- debug: - var: sha256_checksum.stat.checksum -''' - -RETURN = r''' -changed: - description: Whether anything was changed - returned: always - type: bool - sample: true -stat: - description: dictionary containing all the stat data - returned: success - type: complex - contains: - attributes: - description: Attributes of the file at path in raw form. - returned: success, path exists - type: str - sample: "Archive, Hidden" - checksum: - description: The checksum of a file based on checksum_algorithm specified. - returned: success, path exist, path is a file, get_checksum == True - checksum_algorithm specified is supported - type: str - sample: 09cb79e8fc7453c84a07f644e441fd81623b7f98 - creationtime: - description: The create time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - exists: - description: If the path exists or not. - returned: success - type: bool - sample: true - extension: - description: The extension of the file at path. - returned: success, path exists, path is a file - type: str - sample: ".ps1" - filename: - description: The name of the file (without path). - returned: success, path exists, path is a file - type: str - sample: foo.ini - hlnk_targets: - description: List of other files pointing to the same file (hard links), excludes the current file. - returned: success, path exists - type: list - sample: - - C:\temp\file.txt - - C:\Windows\update.log - isarchive: - description: If the path is ready for archiving or not. - returned: success, path exists - type: bool - sample: true - isdir: - description: If the path is a directory or not. - returned: success, path exists - type: bool - sample: true - ishidden: - description: If the path is hidden or not. - returned: success, path exists - type: bool - sample: true - isjunction: - description: If the path is a junction point or not. - returned: success, path exists - type: bool - sample: true - islnk: - description: If the path is a symbolic link or not. - returned: success, path exists - type: bool - sample: true - isreadonly: - description: If the path is read only or not. - returned: success, path exists - type: bool - sample: true - isreg: - description: If the path is a regular file. - returned: success, path exists - type: bool - sample: true - isshared: - description: If the path is shared or not. - returned: success, path exists - type: bool - sample: true - lastaccesstime: - description: The last access time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - lastwritetime: - description: The last modification time of the file represented in seconds since epoch. - returned: success, path exists - type: float - sample: 1477984205.15 - lnk_source: - description: Target of the symlink normalized for the remote filesystem. - returned: success, path exists and the path is a symbolic link or junction point - type: str - sample: C:\temp\link - lnk_target: - description: Target of the symlink. Note that relative paths remain relative. - returned: success, path exists and the path is a symbolic link or junction point - type: str - sample: ..\link - nlink: - description: Number of links to the file (hard links). - returned: success, path exists - type: int - sample: 1 - owner: - description: The owner of the file. - returned: success, path exists - type: str - sample: BUILTIN\Administrators - path: - description: The full absolute path to the file. - returned: success, path exists, file exists - type: str - sample: C:\foo.ini - sharename: - description: The name of share if folder is shared. - returned: success, path exists, file is a directory and isshared == True - type: str - sample: file-share - size: - description: The size in bytes of a file or folder. - returned: success, path exists, file is not a link - type: int - sample: 1024 -''' diff --git a/lib/ansible/modules/windows/win_tempfile.ps1 b/lib/ansible/modules/windows/win_tempfile.ps1 deleted file mode 100644 index 9a1a717439..0000000000 --- a/lib/ansible/modules/windows/win_tempfile.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic - -Function New-TempFile { - Param ([string]$path, [string]$prefix, [string]$suffix, [string]$type, [bool]$checkmode) - $temppath = $null - $curerror = $null - $attempt = 0 - - # Since we don't know if the file already exists, we try 5 times with a random name - do { - $attempt += 1 - $randomname = [System.IO.Path]::GetRandomFileName() - $temppath = (Join-Path -Path $path -ChildPath "$prefix$randomname$suffix") - Try { - $file = New-Item -Path $temppath -ItemType $type -WhatIf:$checkmode - # Makes sure we get the full absolute path of the created temp file and not a relative or DOS 8.3 dir - if (-not $checkmode) { - $temppath = $file.FullName - } else { - # Just rely on GetFulLpath for check mode - $temppath = [System.IO.Path]::GetFullPath($temppath) - } - } Catch { - $temppath = $null - $curerror = $_ - } - } until (($null -ne $temppath) -or ($attempt -ge 5)) - - # If it fails 5 times, something is wrong and we have to report the details - if ($null -eq $temppath) { - $module.FailJson("No random temporary file worked in $attempt attempts. Error: $($curerror.Exception.Message)", $curerror) - } - - return $temppath.ToString() -} - -$spec = @{ - options = @{ - path = @{ type='path'; default='%TEMP%'; aliases=@( 'dest' ) } - state = @{ type='str'; default='file'; choices=@( 'directory', 'file') } - prefix = @{ type='str'; default='ansible.' } - suffix = @{ type='str' } - } - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$path = $module.Params.path -$state = $module.Params.state -$prefix = $module.Params.prefix -$suffix = $module.Params.suffix - -# Expand environment variables on non-path types -if ($null -ne $prefix) { - $prefix = [System.Environment]::ExpandEnvironmentVariables($prefix) -} -if ($null -ne $suffix) { - $suffix = [System.Environment]::ExpandEnvironmentVariables($suffix) -} - -$module.Result.changed = $true -$module.Result.state = $state - -$module.Result.path = New-TempFile -Path $path -Prefix $prefix -Suffix $suffix -Type $state -CheckMode $module.CheckMode - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_tempfile.py b/lib/ansible/modules/windows/win_tempfile.py deleted file mode 100644 index 58dd650137..0000000000 --- a/lib/ansible/modules/windows/win_tempfile.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python -# coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_tempfile -version_added: "2.3" -short_description: Creates temporary files and directories -description: - - Creates temporary files and directories. - - For non-Windows targets, please use the M(tempfile) module instead. -options: - state: - description: - - Whether to create file or directory. - type: str - choices: [ directory, file ] - default: file - path: - description: - - Location where temporary file or directory should be created. - - If path is not specified default system temporary directory (%TEMP%) will be used. - type: path - default: '%TEMP%' - aliases: [ dest ] - prefix: - description: - - Prefix of file/directory name created by module. - type: str - default: ansible. - suffix: - description: - - Suffix of file/directory name created by module. - type: str - default: '' -seealso: -- module: tempfile -author: -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r""" -- name: Create temporary build directory - win_tempfile: - state: directory - suffix: build - -- name: Create temporary file - win_tempfile: - state: file - suffix: temp -""" - -RETURN = r''' -path: - description: The absolute path to the created file or directory. - returned: success - type: str - sample: C:\Users\Administrator\AppData\Local\Temp\ansible.bMlvdk -''' diff --git a/lib/ansible/modules/windows/win_template.py b/lib/ansible/modules/windows/win_template.py deleted file mode 100644 index bd8b2492fa..0000000000 --- a/lib/ansible/modules/windows/win_template.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a virtual module that is entirely implemented server side - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_template -version_added: "1.9.2" -short_description: Template a file out to a remote server -options: - backup: - description: - - Determine whether a backup should be created. - - When set to C(yes), create a backup file including the timestamp information - so you can get the original file back if you somehow clobbered it incorrectly. - type: bool - default: no - version_added: '2.8' - newline_sequence: - default: '\r\n' - force: - version_added: '2.4' -notes: -- Beware fetching files from windows machines when creating templates because certain tools, such as Powershell ISE, - and regedit's export facility add a Byte Order Mark as the first character of the file, which can cause tracebacks. -- You can use the M(win_copy) module with the C(content:) option if you prefer the template inline, as part of the - playbook. -- For Linux you can use M(template) which uses '\\n' as C(newline_sequence) by default. -seealso: -- module: win_copy -- module: copy -- module: template -author: -- Jon Hawkesworth (@jhawkesworth) -extends_documentation_fragment: -- template_common -''' - -EXAMPLES = r''' -- name: Create a file from a Jinja2 template - win_template: - src: /mytemplates/file.conf.j2 - dest: C:\Temp\file.conf - -- name: Create a Unix-style file from a Jinja2 template - win_template: - src: unix/config.conf.j2 - dest: C:\share\unix\config.conf - newline_sequence: '\n' - backup: yes -''' - -RETURN = r''' -backup_file: - description: Name of the backup file that was created. - returned: if backup=yes - type: str - sample: C:\Path\To\File.txt.11540.20150212-220915.bak -''' diff --git a/lib/ansible/modules/windows/win_updates.ps1 b/lib/ansible/modules/windows/win_updates.ps1 deleted file mode 100644 index b8ef807a37..0000000000 --- a/lib/ansible/modules/windows/win_updates.ps1 +++ /dev/null @@ -1,591 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Matt Davis <mdavis@rolpdog.com> -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - -$category_names = Get-AnsibleParam -obj $params -name "category_names" -type "list" -default @("CriticalUpdates", "SecurityUpdates", "UpdateRollups") -$log_path = Get-AnsibleParam -obj $params -name "log_path" -type "path" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "installed" -validateset "installed", "searched", "downloaded" -$blacklist = Get-AnsibleParam -obj $params -name "blacklist" -type "list" -$whitelist = Get-AnsibleParam -obj $params -name "whitelist" -type "list" -$server_selection = Get-AnsibleParam -obj $params -name "server_selection" -type "string" -default "default" -validateset "default", "managed_server", "windows_update" - -# For backwards compatibility -Function Get-CategoryMapping ($category_name) { - switch -exact ($category_name) { - "CriticalUpdates" {return "Critical Updates"} - "DefinitionUpdates" {return "Definition Updates"} - "DeveloperKits" {return "Developer Kits"} - "FeaturePacks" {return "Feature Packs"} - "SecurityUpdates" {return "Security Updates"} - "ServicePacks" {return "Service Packs"} - "UpdateRollups" {return "Update Rollups"} - default {return $category_name} - } -} - -$category_names = $category_names | ForEach-Object { Get-CategoryMapping -category_name $_ } - -$common_functions = { - Function Write-DebugLog($msg) { - $date_str = Get-Date -Format u - $msg = "$date_str $msg" - - Write-Debug -Message $msg - if ($null -ne $log_path -and (-not $check_mode)) { - Add-Content -Path $log_path -Value $msg - } - } -} - -$update_script_block = { - Param( - [hashtable]$arguments - ) - - $ErrorActionPreference = "Stop" - $DebugPreference = "Continue" - - Function Start-Updates { - Param( - $category_names, - $log_path, - $state, - $blacklist, - $whitelist, - $server_selection - ) - - $result = @{ - changed = $false - updates = @{} - filtered_updates = @{} - } - - Write-DebugLog -msg "Creating Windows Update session..." - try { - $session = New-Object -ComObject Microsoft.Update.Session - } catch { - $result.failed = $true - $result.msg = "Failed to create Microsoft.Update.Session COM object: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Create Windows Update searcher..." - try { - $searcher = $session.CreateUpdateSearcher() - } catch { - $result.failed = $true - $result.msg = "Failed to create Windows Update search from session: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Setting the Windows Update Agent source catalog..." - Write-DebugLog -msg "Requested search source is '$($server_selection)'" - try { - $server_selection_value = switch ($server_selection) { - "default" { 0 ; break } - "managed_server" { 1 ; break } - "windows_update" { 2 ; break } - } - $searcher.serverselection = $server_selection_value - Write-DebugLog -msg "Search source set to '$($server_selection)' (ServerSelection = $($server_selection_value))" - } - catch { - $result.failed = $true - $result.msg = "Failed to set Windows Update Agent search source: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Searching for updates to install" - try { - $search_result = $searcher.Search("IsInstalled = 0") - } catch { - $result.failed = $true - $result.msg = "Failed to search for updates: $($_.Exception.Message)" - return $result - } - Write-DebugLog -msg "Found $($search_result.Updates.Count) updates" - - Write-DebugLog -msg "Creating update collection..." - try { - $updates_to_install = New-Object -ComObject Microsoft.Update.UpdateColl - } catch { - $result.failed = $true - $result.msg = "Failed to create update collection object: $($_.Exception.Message)" - return $result - } - - foreach ($update in $search_result.Updates) { - $update_info = @{ - title = $update.Title - # TODO: pluck the first KB out (since most have just one)? - kb = $update.KBArticleIDs - id = $update.Identity.UpdateId - installed = $false - categories = @($update.Categories | ForEach-Object { $_.Name }) - } - - # validate update again blacklist/whitelist/post_category_names/hidden - $whitelist_match = $false - foreach ($whitelist_entry in $whitelist) { - if ($update_info.title -imatch $whitelist_entry) { - $whitelist_match = $true - break - } - foreach ($kb in $update_info.kb) { - if ("KB$kb" -imatch $whitelist_entry) { - $whitelist_match = $true - break - } - } - } - if ($whitelist.Length -gt 0 -and -not $whitelist_match) { - Write-DebugLog -msg "Skipping update $($update_info.id) - $($update_info.title) as it was not found in the whitelist" - $update_info.filtered_reason = "whitelist" - $result.filtered_updates[$update_info.id] = $update_info - continue - } - - $blacklist_match = $false - foreach ($blacklist_entry in $blacklist) { - if ($update_info.title -imatch $blacklist_entry) { - $blacklist_match = $true - break - } - foreach ($kb in $update_info.kb) { - if ("KB$kb" -imatch $blacklist_entry) { - $blacklist_match = $true - break - } - } - } - if ($blacklist_match) { - Write-DebugLog -msg "Skipping update $($update_info.id) - $($update_info.title) as it was found in the blacklist" - $update_info.filtered_reason = "blacklist" - $result.filtered_updates[$update_info.id] = $update_info - continue - } - - if ($update.IsHidden) { - Write-DebugLog -msg "Skipping update $($update_info.title) as it was hidden" - $update_info.filtered_reason = "skip_hidden" - $result.filtered_updates[$update_info.id] = $update_info - continue - } - - $category_match = $false - foreach ($match_cat in $category_names) { - if ($update_info.categories -ieq $match_cat) { - $category_match = $true - break - } - } - if ($category_names.Length -gt 0 -and -not $category_match) { - Write-DebugLog -msg "Skipping update $($update_info.id) - $($update_info.title) as it was not found in the category names filter" - $update_info.filtered_reason = "category_names" - $result.filtered_updates[$update_info.id] = $update_info - continue - } - - if (-not $update.EulaAccepted) { - Write-DebugLog -msg "Accepting EULA for $($update_info.id)" - try { - $update.AcceptEula() - } catch { - $result.failed = $true - $result.msg = "Failed to accept EULA for update $($update_info.id) - $($update_info.title)" - return $result - } - } - - Write-DebugLog -msg "Adding update $($update_info.id) - $($update_info.title)" - $updates_to_install.Add($update) > $null - - $result.updates[$update_info.id] = $update_info - } - - Write-DebugLog -msg "Calculating pre-install reboot requirement..." - - # calculate this early for check mode, and to see if we should allow updates to continue - $result.reboot_required = (New-Object -ComObject Microsoft.Update.SystemInfo).RebootRequired - $result.found_update_count = $updates_to_install.Count - $result.installed_update_count = 0 - - # Early exit of check mode/state=searched as it cannot do more after this - if ($check_mode -or $state -eq "searched") { - Write-DebugLog -msg "Check mode: exiting..." - Write-DebugLog -msg "Return value:`r`n$(ConvertTo-Json -InputObject $result -Depth 99)" - - if ($updates_to_install.Count -gt 0 -and ($state -ne "searched")) { - $result.changed = $true - } - return $result - } - - if ($updates_to_install.Count -gt 0) { - if ($result.reboot_required) { - Write-DebugLog -msg "FATAL: A reboot is required before more updates can be installed" - $result.failed = $true - $result.msg = "A reboot is required before more updates can be installed" - return $result - } - Write-DebugLog -msg "No reboot is pending..." - } else { - # no updates to install exit here - return $result - } - - Write-DebugLog -msg "Downloading updates..." - $update_index = 1 - foreach ($update in $updates_to_install) { - $update_number = "($update_index of $($updates_to_install.Count))" - if ($update.IsDownloaded) { - Write-DebugLog -msg "Update $update_number $($update.Identity.UpdateId) already downloaded, skipping..." - $update_index++ - continue - } - - Write-DebugLog -msg "Creating downloader object..." - try { - $dl = $session.CreateUpdateDownloader() - } catch { - $result.failed = $true - $result.msg = "Failed to create downloader object: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Creating download collection..." - try { - $dl.Updates = New-Object -ComObject Microsoft.Update.UpdateColl - } catch { - $result.failed = $true - $result.msg = "Failed to create download collection object: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Adding update $update_number $($update.Identity.UpdateId)" - $dl.Updates.Add($update) > $null - - Write-DebugLog -msg "Downloading $update_number $($update.Identity.UpdateId)" - try { - $download_result = $dl.Download() - } catch { - $result.failed = $true - $result.msg = "Failed to download update $update_number $($update.Identity.UpdateId) - $($update.Title): $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Download result code for $update_number $($update.Identity.UpdateId) = $($download_result.ResultCode)" - # FUTURE: configurable download retry - if ($download_result.ResultCode -ne 2) { # OperationResultCode orcSucceeded - $result.failed = $true - $result.msg = "Failed to download update $update_number $($update.Identity.UpdateId) - $($update.Title): Download Result $($download_result.ResultCode)" - return $result - } - - $result.changed = $true - $update_index++ - } - - # Early exit for download-only - if ($state -eq "downloaded") { - Write-DebugLog -msg "Downloaded $($updates_to_install.Count) updates..." - $result.failed = $false - $result.msg = "Downloaded $($updates_to_install.Count) updates" - return $result - } - - Write-DebugLog -msg "Installing updates..." - # install as a batch so the reboot manager will suppress intermediate reboots - - Write-DebugLog -msg "Creating installer object..." - try { - $installer = $session.CreateUpdateInstaller() - } catch { - $result.failed = $true - $result.msg = "Failed to create Update Installer object: $($_.Exception.Message)" - return $result - } - - Write-DebugLog -msg "Creating install collection..." - try { - $installer.Updates = New-Object -ComObject Microsoft.Update.UpdateColl - } catch { - $result.failed = $true - $result.msg = "Failed to create Update Collection object: $($_.Exception.Message)" - return $result - } - - foreach ($update in $updates_to_install) { - Write-DebugLog -msg "Adding update $($update.Identity.UpdateID)" - $installer.Updates.Add($update) > $null - } - - # FUTURE: use BeginInstall w/ progress reporting so we can at least log intermediate install results - try { - $install_result = $installer.Install() - } catch { - $result.failed = $true - $result.msg = "Failed to install update from Update Collection: $($_.Exception.Message)" - return $result - } - - $update_success_count = 0 - $update_fail_count = 0 - - # WU result API requires us to index in to get the install results - $update_index = 0 - foreach ($update in $updates_to_install) { - $update_number = "($($update_index + 1) of $($updates_to_install.Count))" - try { - $update_result = $install_result.GetUpdateResult($update_index) - } catch { - $result.failed = $true - $result.msg = "Failed to get update result for update $update_number $($update.Identity.UpdateID) - $($update.Title): $($_.Exception.Message)" - return $result - } - $update_resultcode = $update_result.ResultCode - $update_hresult = $update_result.HResult - - $update_index++ - - $update_dict = $result.updates[$update.Identity.UpdateID] - if ($update_resultcode -eq 2) { # OperationResultCode orcSucceeded - $update_success_count++ - $update_dict.installed = $true - Write-DebugLog -msg "Update $update_number $($update.Identity.UpdateID) succeeded" - } else { - $update_fail_count++ - $update_dict.installed = $false - $update_dict.failed = $true - $update_dict.failure_hresult_code = $update_hresult - Write-DebugLog -msg "Update $update_number $($update.Identity.UpdateID) failed, resultcode: $update_resultcode, hresult: $update_hresult" - } - } - - Write-DebugLog -msg "Performing post-install reboot requirement check..." - $result.reboot_required = (New-Object -ComObject Microsoft.Update.SystemInfo).RebootRequired - $result.installed_update_count = $update_success_count - $result.failed_update_count = $update_fail_count - - if ($updates_success_count -gt 0) { - $result.changed = $true - } - - if ($update_fail_count -gt 0) { - $result.failed = $true - $result.msg = "Failed to install one or more updates" - return $result - } - - Write-DebugLog -msg "Return value:`r`n$(ConvertTo-Json -InputObject $result -Depth 99)" - - return $result - } - - $check_mode = $arguments.check_mode - try { - return @{ - job_output = Start-Updates @arguments - } - } catch { - Write-DebugLog -msg "Fatal exception: $($_.Exception.Message) at $($_.ScriptStackTrace)" - return @{ - job_output = @{ - failed = $true - msg = $_.Exception.Message - location = $_.ScriptStackTrace - } - } - } -} - -Function Start-Natively($common_functions, $script) { - $runspace_pool = [RunspaceFactory]::CreateRunspacePool() - $runspace_pool.Open() - - try { - $ps_pipeline = [PowerShell]::Create() - $ps_pipeline.RunspacePool = $runspace_pool - - # add the common script functions - $ps_pipeline.AddScript($common_functions) > $null - - # add the update script block and required parameters - $ps_pipeline.AddStatement().AddScript($script) > $null - $ps_pipeline.AddParameter("arguments", @{ - category_names = $category_names - log_path = $log_path - state = $state - blacklist = $blacklist - whitelist = $whitelist - check_mode = $check_mode - server_selection = $server_selection - }) > $null - - $output = $ps_pipeline.Invoke() - } finally { - $runspace_pool.Close() - } - - $result = $output[0].job_output - if ($ps_pipeline.HadErrors) { - $result.failed = $true - - # if the msg wasn't set, then add a generic error to at least tell the user something - if (-not ($result.ContainsKey("msg"))) { - $result.msg = "Unknown failure when executing native update script block" - $result.errors = $ps_pipeline.Streams.Error - } - } - - Write-DebugLog -msg "Native job completed with output: $($result | Out-String -Width 300)" - - return ,$result -} - -Function Remove-ScheduledJob($name) { - $scheduled_job = Get-ScheduledJob -Name $name -ErrorAction SilentlyContinue - - if ($null -ne $scheduled_job) { - Write-DebugLog -msg "Scheduled Job $name exists, ensuring it is not running..." - $scheduler = New-Object -ComObject Schedule.Service - Write-DebugLog -msg "Connecting to scheduler service..." - $scheduler.Connect() - Write-DebugLog -msg "Getting running tasks named $name" - $running_tasks = @($scheduler.GetRunningTasks(0) | Where-Object { $_.Name -eq $name }) - - foreach ($task_to_stop in $running_tasks) { - Write-DebugLog -msg "Stopping running task $($task_to_stop.InstanceGuid)..." - $task_to_stop.Stop() - } - - <# FUTURE: add a global waithandle for this to release any other waiters. Wait-Job - and/or polling will block forever, since the killed job object in the parent - session doesn't know it's been killed :( #> - Unregister-ScheduledJob -Name $name - } -} - -Function Start-AsScheduledTask($common_functions, $script) { - $job_name = "ansible-win-updates" - Remove-ScheduledJob -name $job_name - - $job_args = @{ - ScriptBlock = $script - Name = $job_name - ArgumentList = @( - @{ - category_names = $category_names - log_path = $log_path - state = $state - blacklist = $blacklist - whitelist = $whitelist - check_mode = $check_mode - server_selection = $server_selection - } - ) - ErrorAction = "Stop" - ScheduledJobOption = @{ RunElevated=$True; StartIfOnBatteries=$True; StopIfGoingOnBatteries=$False } - InitializationScript = $common_functions - } - - Write-DebugLog -msg "Registering scheduled job with args $($job_args | Out-String -Width 300)" - $scheduled_job = Register-ScheduledJob @job_args - - # RunAsTask isn't available in PS3 - fall back to a 2s future trigger - if ($scheduled_job | Get-Member -Name RunAsTask) { - Write-DebugLog -msg "Starting scheduled job (PS4+ method)" - $scheduled_job.RunAsTask() - } else { - Write-DebugLog -msg "Starting scheduled job (PS3 method)" - Add-JobTrigger -InputObject $scheduled_job -trigger $(New-JobTrigger -Once -At $(Get-Date).AddSeconds(2)) - } - - $sw = [System.Diagnostics.Stopwatch]::StartNew() - $job = $null - - Write-DebugLog -msg "Waiting for job completion..." - - # Wait-Job can fail for a few seconds until the scheduled task starts - poll for it... - while ($null -eq $job) { - Start-Sleep -Milliseconds 100 - if ($sw.ElapsedMilliseconds -ge 30000) { # tasks scheduled right after boot on 2008R2 can take awhile to start... - Fail-Json -msg "Timed out waiting for scheduled task to start" - } - - # FUTURE: configurable timeout so we don't block forever? - # FUTURE: add a global WaitHandle in case another instance kills our job, so we don't block forever - $job = Wait-Job -Name $scheduled_job.Name -ErrorAction SilentlyContinue - } - - $sw = [System.Diagnostics.Stopwatch]::StartNew() - - # NB: output from scheduled jobs is delayed after completion (including the sub-objects after the primary Output object is available) - while (($null -eq $job.Output -or -not ($job.Output | Get-Member -Name Key -ErrorAction Ignore) -or -not $job.Output.Key.Contains("job_output")) -and $sw.ElapsedMilliseconds -lt 15000) { - Write-DebugLog -msg "Waiting for job output to populate..." - Start-Sleep -Milliseconds 500 - } - - # NB: fallthru on both timeout and success - $ret = @{ - ErrorOutput = $job.Error - WarningOutput = $job.Warning - VerboseOutput = $job.Verbose - DebugOutput = $job.Debug - } - - if ($null -eq $job.Output -or -not $job.Output.Keys.Contains('job_output')) { - $ret.Output = @{failed = $true; msg = "job output was lost"} - } else { - $ret.Output = $job.Output.job_output # sub-object returned, can only be accessed as a property for some reason - } - - try { # this shouldn't be fatal, but can fail with both Powershell errors and COM Exceptions, hence the dual error-handling... - Unregister-ScheduledJob -Name $job_name -Force -ErrorAction Continue - } catch { - Write-DebugLog "Error unregistering job after execution: $($_.Exception.ToString()) $($_.ScriptStackTrace)" - } - Write-DebugLog -msg "Scheduled job completed with output: $($re.Output | Out-String -Width 300)" - - return $ret.Output -} - -# source the common code into the current scope so we can call it -. $common_functions - -<# Most of the Windows Update Agent API will not run under a remote token, -which a remote WinRM session always has. Using become can bypass this -limitation but it is not always an option with older hosts. win_updates checks -if WUA is available in the current logon process and does either of the below; - - * If become is used then it will run the windows update process natively - without any of the scheduled task hackery - * If become is not used then it will run the windows update process under - a scheduled job. -#> -try { - (New-Object -ComObject Microsoft.Update.Session).CreateUpdateInstaller().IsBusy > $null - $wua_available = $true -} catch { - $wua_available = $false -} - -if ($wua_available) { - Write-DebugLog -msg "WUA is available in current logon process, running natively" - $result = Start-Natively -common_functions $common_functions -script $update_script_block -} else { - Write-DebugLog -msg "WUA is not available in current logon process, running with scheduled task" - $result = Start-AsScheduledTask -common_functions $common_functions -script $update_script_block -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_updates.py b/lib/ansible/modules/windows/win_updates.py deleted file mode 100644 index b88143eedc..0000000000 --- a/lib/ansible/modules/windows/win_updates.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Matt Davis <mdavis_ansible@rolpdog.com> -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'core'} - - -DOCUMENTATION = r''' ---- -module: win_updates -version_added: "2.0" -short_description: Download and install Windows updates -description: - - Searches, downloads, and installs Windows updates synchronously by automating the Windows Update client. -options: - blacklist: - description: - - A list of update titles or KB numbers that can be used to specify - which updates are to be excluded from installation. - - If an available update does match one of the entries, then it is - skipped and not installed. - - Each entry can either be the KB article or Update title as a regex - according to the PowerShell regex rules. - type: list - version_added: '2.5' - category_names: - description: - - A scalar or list of categories to install updates from. To get the list - of categories, run the module with C(state=searched). The category must - be the full category string, but is case insensitive. - - Some possible categories are Application, Connectors, Critical Updates, - Definition Updates, Developer Kits, Feature Packs, Guidance, Security - Updates, Service Packs, Tools, Update Rollups and Updates. - type: list - default: [ CriticalUpdates, SecurityUpdates, UpdateRollups ] - reboot: - description: - - Ansible will automatically reboot the remote host if it is required - and continue to install updates after the reboot. - - This can be used instead of using a M(win_reboot) task after this one - and ensures all updates for that category is installed in one go. - - Async does not work when C(reboot=yes). - type: bool - default: no - version_added: '2.5' - reboot_timeout: - description: - - The time in seconds to wait until the host is back online from a - reboot. - - This is only used if C(reboot=yes) and a reboot is required. - default: 1200 - version_added: '2.5' - server_selection: - description: - - Defines the Windows Update source catalog. - - C(default) Use the default search source. For many systems default is - set to the Microsoft Windows Update catalog. Systems participating in - Windows Server Update Services (WSUS), Systems Center Configuration - Manager (SCCM), or similar corporate update server environments may - default to those managed update sources instead of the Windows Update - catalog. - - C(managed_server) Use a managed server catalog. For environments - utilizing Windows Server Update Services (WSUS), Systems Center - Configuration Manager (SCCM), or similar corporate update servers, this - option selects the defined corporate update source. - - C(windows_update) Use the Microsoft Windows Update catalog. - type: str - choices: [ default, managed_server, windows_update ] - default: default - version_added: '2.8' - state: - description: - - Controls whether found updates are downloaded or installed or listed - - This module also supports Ansible check mode, which has the same effect as setting state=searched - type: str - choices: [ installed, searched, downloaded ] - default: installed - log_path: - description: - - If set, C(win_updates) will append update progress to the specified file. The directory must already exist. - type: path - whitelist: - description: - - A list of update titles or KB numbers that can be used to specify - which updates are to be searched or installed. - - If an available update does not match one of the entries, then it - is skipped and not installed. - - Each entry can either be the KB article or Update title as a regex - according to the PowerShell regex rules. - - The whitelist is only validated on updates that were found based on - I(category_names). It will not force the module to install an update - if it was not in the category specified. - type: list - version_added: '2.5' - use_scheduled_task: - description: - - Will not auto elevate the remote process with I(become) and use a - scheduled task instead. - - Set this to C(yes) when using this module with async on Server 2008, - 2008 R2, or Windows 7, or on Server 2008 that is not authenticated - with basic or credssp. - - Can also be set to C(yes) on newer hosts where become does not work - due to further privilege restrictions from the OS defaults. - type: bool - default: no - version_added: '2.6' -notes: -- C(win_updates) must be run by a user with membership in the local Administrators group. -- C(win_updates) will use the default update service configured for the machine (Windows Update, Microsoft Update, WSUS, etc). -- C(win_updates) will I(become) SYSTEM using I(runas) unless C(use_scheduled_task) is C(yes) -- By default C(win_updates) does not manage reboots, but will signal when a - reboot is required with the I(reboot_required) return value, as of Ansible v2.5 - C(reboot) can be used to reboot the host if required in the one task. -- C(win_updates) can take a significant amount of time to complete (hours, in some cases). - Performance depends on many factors, including OS version, number of updates, system load, and update server load. -- Beware that just after C(win_updates) reboots the system, the Windows system may not have settled yet - and some base services could be in limbo. This can result in unexpected behavior. - Check the examples for ways to mitigate this. -- More information about PowerShell and how it handles RegEx strings can be - found at U(https://technet.microsoft.com/en-us/library/2007.11.powershell.aspx). -seealso: -- module: win_chocolatey -- module: win_feature -- module: win_hotfix -- module: win_package -author: -- Matt Davis (@nitzmahone) -''' - -EXAMPLES = r''' -- name: Install all security, critical, and rollup updates without a scheduled task - win_updates: - category_names: - - SecurityUpdates - - CriticalUpdates - - UpdateRollups - -- name: Install only security updates as a scheduled task for Server 2008 - win_updates: - category_names: SecurityUpdates - use_scheduled_task: yes - -- name: Search-only, return list of found updates (if any), log to C:\ansible_wu.txt - win_updates: - category_names: SecurityUpdates - state: searched - log_path: C:\ansible_wu.txt - -- name: Install all security updates with automatic reboots - win_updates: - category_names: - - SecurityUpdates - reboot: yes - -- name: Install only particular updates based on the KB numbers - win_updates: - category_name: - - SecurityUpdates - whitelist: - - KB4056892 - - KB4073117 - -- name: Exclude updates based on the update title - win_updates: - category_name: - - SecurityUpdates - - CriticalUpdates - blacklist: - - Windows Malicious Software Removal Tool for Windows - - \d{4}-\d{2} Cumulative Update for Windows Server 2016 - -# One way to ensure the system is reliable just after a reboot, is to set WinRM to a delayed startup -- name: Ensure WinRM starts when the system has settled and is ready to work reliably - win_service: - name: WinRM - start_mode: delayed - -# Optionally, you can increase the reboot_timeout to survive long updates during reboot -- name: Ensure we wait long enough for the updates to be applied during reboot - win_updates: - reboot: yes - reboot_timeout: 3600 - -# Search and download Windows updates -- name: Search and download Windows updates without installing them - win_updates: - state: downloaded -''' - -RETURN = r''' -reboot_required: - description: True when the target server requires a reboot to complete updates (no further updates can be installed until after a reboot). - returned: success - type: bool - sample: true - -updates: - description: List of updates that were found/installed. - returned: success - type: complex - sample: - contains: - title: - description: Display name. - returned: always - type: str - sample: "Security Update for Windows Server 2012 R2 (KB3004365)" - kb: - description: A list of KB article IDs that apply to the update. - returned: always - type: list - elements: str - sample: [ '3004365' ] - id: - description: Internal Windows Update GUID. - returned: always - type: str - sample: "fb95c1c8-de23-4089-ae29-fd3351d55421" - installed: - description: Was the update successfully installed. - returned: always - type: bool - sample: true - categories: - description: A list of category strings for this update. - returned: always - type: list - elements: str - sample: [ 'Critical Updates', 'Windows Server 2012 R2' ] - failure_hresult_code: - description: The HRESULT code from a failed update. - returned: on install failure - type: bool - sample: 2147942402 - -filtered_updates: - description: List of updates that were found but were filtered based on - I(blacklist), I(whitelist) or I(category_names). The return value is in - the same form as I(updates), along with I(filtered_reason). - returned: success - type: complex - sample: see the updates return value - contains: - filtered_reason: - description: The reason why this update was filtered. - returned: always - type: str - sample: 'skip_hidden' - -found_update_count: - description: The number of updates found needing to be applied. - returned: success - type: int - sample: 3 -installed_update_count: - description: The number of updates successfully installed or downloaded. - returned: success - type: int - sample: 2 -failed_update_count: - description: The number of updates that failed to install. - returned: always - type: int - sample: 0 -''' diff --git a/lib/ansible/modules/windows/win_uri.ps1 b/lib/ansible/modules/windows/win_uri.ps1 deleted file mode 100644 index 09ccf1b0b3..0000000000 --- a/lib/ansible/modules/windows/win_uri.ps1 +++ /dev/null @@ -1,185 +0,0 @@ -#!powershell - -# Copyright: (c) 2015, Corwin Brown <corwin@corwinbrown.com> -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.CamelConversion -#Requires -Module Ansible.ModuleUtils.FileUtil -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.WebRequest - -$spec = @{ - options = @{ - url = @{ type = "str"; required = $true } - content_type = @{ type = "str" } - body = @{ type = "raw" } - dest = @{ type = "path" } - creates = @{ type = "path" } - method = @{ default = "GET" } - removes = @{ type = "path" } - return_content = @{ type = "bool"; default = $false } - status_code = @{ type = "list"; elements = "int"; default = @(200) } - - # Defined for the alias backwards compatibility, remove once aliases are removed - url_username = @{ - aliases = @("user", "username") - deprecated_aliases = @( - @{ name = "user"; version = "2.14" }, - @{ name = "username"; version = "2.14" } - ) - } - url_password = @{ - aliases = @("password") - deprecated_aliases = @( - @{ name = "password"; version = "2.14" } - ) - } - } - supports_check_mode = $true -} -$spec = Merge-WebRequestSpec -ModuleSpec $spec - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$url = $module.Params.url -$method = $module.Params.method.ToUpper() -$content_type = $module.Params.content_type -$body = $module.Params.body -$dest = $module.Params.dest -$creates = $module.Params.creates -$removes = $module.Params.removes -$return_content = $module.Params.return_content -$status_code = $module.Params.status_code - -$JSON_CANDIDATES = @('text', 'json', 'javascript') - -$module.Result.elapsed = 0 -$module.Result.url = $url - -if (-not ($method -cmatch '^[A-Z]+$')) { - $module.FailJson("Parameter 'method' needs to be a single word in uppercase, like GET or POST.") -} - -if ($creates -and (Test-AnsiblePath -Path $creates)) { - $module.Result.skipped = $true - $module.Result.msg = "The 'creates' file or directory ($creates) already exists." - $module.ExitJson() -} - -if ($removes -and -not (Test-AnsiblePath -Path $removes)) { - $module.Result.skipped = $true - $module.Result.msg = "The 'removes' file or directory ($removes) does not exist." - $module.ExitJson() -} - -$client = Get-AnsibleWebRequest -Uri $url -Module $module - -if ($null -ne $content_type) { - $client.ContentType = $content_type -} - -$response_script = { - param($Response, $Stream) - - ForEach ($prop in $Response.PSObject.Properties) { - $result_key = Convert-StringToSnakeCase -string $prop.Name - $prop_value = $prop.Value - # convert and DateTime values to ISO 8601 standard - if ($prop_value -is [System.DateTime]) { - $prop_value = $prop_value.ToString("o", [System.Globalization.CultureInfo]::InvariantCulture) - } - $module.Result.$result_key = $prop_value - } - - # manually get the headers as not all of them are in the response properties - foreach ($header_key in $Response.Headers.GetEnumerator()) { - $header_value = $Response.Headers[$header_key] - $header_key = $header_key.Replace("-", "") # replace - with _ for snake conversion - $header_key = Convert-StringToSnakeCase -string $header_key - $module.Result.$header_key = $header_value - } - - # we only care about the return body if we need to return the content or create a file - if ($return_content -or $dest) { - # copy to a MemoryStream so we can read it multiple times - $memory_st = New-Object -TypeName System.IO.MemoryStream - try { - $Stream.CopyTo($memory_st) - - if ($return_content) { - $memory_st.Seek(0, [System.IO.SeekOrigin]::Begin) > $null - $content_bytes = $memory_st.ToArray() - $module.Result.content = [System.Text.Encoding]::UTF8.GetString($content_bytes) - if ($module.Result.ContainsKey("content_type") -and $module.Result.content_type -Match ($JSON_CANDIDATES -join '|')) { - try { - $module.Result.json = ([Ansible.Basic.AnsibleModule]::FromJson($module.Result.content)) - } catch [System.ArgumentException] { - # Simply continue, since 'text' might be anything - } - } - } - - if ($dest) { - $memory_st.Seek(0, [System.IO.SeekOrigin]::Begin) > $null - $changed = $true - - if (Test-AnsiblePath -Path $dest) { - $actual_checksum = Get-FileChecksum -path $dest -algorithm "sha1" - - $sp = New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider - $content_checksum = [System.BitConverter]::ToString($sp.ComputeHash($memory_st)).Replace("-", "").ToLower() - - if ($actual_checksum -eq $content_checksum) { - $changed = $false - } - } - - $module.Result.changed = $changed - if ($changed -and (-not $module.CheckMode)) { - $memory_st.Seek(0, [System.IO.SeekOrigin]::Begin) > $null - $file_stream = [System.IO.File]::Create($dest) - try { - $memory_st.CopyTo($file_stream) - } finally { - $file_stream.Flush() - $file_stream.Close() - } - } - } - } finally { - $memory_st.Close() - } - } - - if ($status_code -notcontains $Response.StatusCode) { - $module.FailJson("Status code of request '$([int]$Response.StatusCode)' is not in list of valid status codes $status_code : $($Response.StatusCode)'.") - } -} - -$body_st = $null -if ($null -ne $body) { - if ($body -is [System.Collections.IDictionary] -or $body -is [System.Collections.IList]) { - $body_string = ConvertTo-Json -InputObject $body -Compress - } elseif ($body -isnot [String]) { - $body_string = $body.ToString() - } else { - $body_string = $body - } - $buffer = [System.Text.Encoding]::UTF8.GetBytes($body_string) - - $body_st = New-Object -TypeName System.IO.MemoryStream -ArgumentList @(,$buffer) -} - -try { - Invoke-WithWebRequest -Module $module -Request $client -Script $response_script -Body $body_st -IgnoreBadResponse -} catch { - $module.FailJson("Unhandled exception occurred when sending web request. Exception: $($_.Exception.Message)", $_) -} finally { - if ($null -ne $body_st) { - $body_st.Dispose() - } -} - -$module.ExitJson() diff --git a/lib/ansible/modules/windows/win_uri.py b/lib/ansible/modules/windows/win_uri.py deleted file mode 100644 index 8eb61423cf..0000000000 --- a/lib/ansible/modules/windows/win_uri.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Corwin Brown <corwin@corwinbrown.com> -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_uri -version_added: '2.1' -short_description: Interacts with webservices -description: -- Interacts with FTP, HTTP and HTTPS web services. -- Supports Digest, Basic and WSSE HTTP authentication mechanisms. -- For non-Windows targets, use the M(uri) module instead. -options: - url: - description: - - Supports FTP, HTTP or HTTPS URLs in the form of (ftp|http|https)://host.domain:port/path. - type: str - required: yes - method: - description: - - The HTTP Method of the request or response. - type: str - default: GET - content_type: - description: - - Sets the "Content-Type" header. - type: str - body: - description: - - The body of the HTTP request/response to the web service. - type: raw - dest: - description: - - Output the response body to a file. - type: path - version_added: '2.3' - creates: - description: - - A filename, when it already exists, this step will be skipped. - type: path - version_added: '2.4' - removes: - description: - - A filename, when it does not exist, this step will be skipped. - type: path - version_added: '2.4' - return_content: - description: - - Whether or not to return the body of the response as a "content" key in - the dictionary result. If the reported Content-type is - "application/json", then the JSON is additionally loaded into a key - called C(json) in the dictionary results. - type: bool - default: no - version_added: '2.4' - status_code: - description: - - A valid, numeric, HTTP status code that signifies success of the request. - - Can also be comma separated list of status codes. - type: list - elements: int - default: [ 200 ] - version_added: '2.4' - url_username: - description: - - The username to use for authentication. - - Was originally called I(user) but was changed to I(url_username) in - Ansible 2.9. - - The aliases I(user) and I(username) are deprecated and will be removed in - Ansible 2.14. - aliases: - - user - - username - version_added: "2.4" - url_password: - description: - - The password for I(url_username). - - Was originally called I(password) but was changed to I(url_password) in - Ansible 2.9. - - The alias I(password) is deprecated and will be removed in Ansible 2.14. - aliases: - - password - version_added: "2.4" - follow_redirects: - version_added: "2.4" - maximum_redirection: - version_added: "2.4" - client_cert: - version_added: "2.4" - client_cert_password: - version_added: "2.5" - use_proxy: - version_added: "2.9" - proxy_url: - version_added: "2.9" - proxy_username: - version_added: "2.9" - proxy_password: - version_added: "2.9" -extends_documentation_fragment: -- url_windows -seealso: -- module: uri -- module: win_get_url -author: -- Corwin Brown (@blakfeld) -- Dag Wieers (@dagwieers) -''' - -EXAMPLES = r''' -- name: Perform a GET and Store Output - win_uri: - url: http://example.com/endpoint - register: http_output - -# Set a HOST header to hit an internal webserver: -- name: Hit a Specific Host on the Server - win_uri: - url: http://example.com/ - method: GET - headers: - host: www.somesite.com - -- name: Perform a HEAD on an Endpoint - win_uri: - url: http://www.example.com/ - method: HEAD - -- name: POST a Body to an Endpoint - win_uri: - url: http://www.somesite.com/ - method: POST - body: "{ 'some': 'json' }" -''' - -RETURN = r''' -elapsed: - description: The number of seconds that elapsed while performing the download. - returned: always - type: float - sample: 23.2 -url: - description: The Target URL. - returned: always - type: str - sample: https://www.ansible.com -status_code: - description: The HTTP Status Code of the response. - returned: success - type: int - sample: 200 -status_description: - description: A summary of the status. - returned: success - type: str - sample: OK -content: - description: The raw content of the HTTP response. - returned: success and return_content is True - type: str - sample: '{"foo": "bar"}' -content_length: - description: The byte size of the response. - returned: success - type: int - sample: 54447 -json: - description: The json structure returned under content as a dictionary. - returned: success and Content-Type is "application/json" or "application/javascript" and return_content is True - type: dict - sample: {"this-is-dependent": "on the actual return content"} -''' diff --git a/lib/ansible/modules/windows/win_user.ps1 b/lib/ansible/modules/windows/win_user.ps1 deleted file mode 100644 index 54905cb2eb..0000000000 --- a/lib/ansible/modules/windows/win_user.ps1 +++ /dev/null @@ -1,273 +0,0 @@ -#!powershell - -# Copyright: (c) 2014, Paul Durivage <paul.durivage@rackspace.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.AccessToken -#Requires -Module Ansible.ModuleUtils.Legacy - -######## -$ADS_UF_PASSWD_CANT_CHANGE = 64 -$ADS_UF_DONT_EXPIRE_PASSWD = 65536 - -$adsi = [ADSI]"WinNT://$env:COMPUTERNAME" - -function Get-User($user) { - $adsi.Children | Where-Object {$_.SchemaClassName -eq 'user' -and $_.Name -eq $user } - return -} - -function Get-UserFlag($user, $flag) { - If ($user.UserFlags[0] -band $flag) { - $true - } - Else { - $false - } -} - -function Set-UserFlag($user, $flag) { - $user.UserFlags = ($user.UserFlags[0] -BOR $flag) -} - -function Clear-UserFlag($user, $flag) { - $user.UserFlags = ($user.UserFlags[0] -BXOR $flag) -} - -function Get-Group($grp) { - $adsi.Children | Where-Object { $_.SchemaClassName -eq 'Group' -and $_.Name -eq $grp } - return -} - -Function Test-LocalCredential { - param([String]$Username, [String]$Password) - - try { - $handle = [Ansible.AccessToken.TokenUtil]::LogonUser($Username, $null, $Password, "Network", "Default") - $handle.Dispose() - $valid_credentials = $true - } catch [Ansible.AccessToken.Win32Exception] { - # following errors indicate the creds are correct but the user was - # unable to log on for other reasons, which we don't care about - $success_codes = @( - 0x0000052F, # ERROR_ACCOUNT_RESTRICTION - 0x00000530, # ERROR_INVALID_LOGON_HOURS - 0x00000531, # ERROR_INVALID_WORKSTATION - 0x00000569 # ERROR_LOGON_TYPE_GRANTED - ) - - if ($_.Exception.NativeErrorCode -eq 0x0000052E) { - # ERROR_LOGON_FAILURE - the user or pass was incorrect - $valid_credentials = $false - } elseif ($_.Exception.NativeErrorCode -in $success_codes) { - $valid_credentials = $true - } else { - # an unknown failure, reraise exception - throw $_ - } - } - return $valid_credentials -} - -######## - -$params = Parse-Args $args; - -$result = @{ - changed = $false -}; - -$username = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$fullname = Get-AnsibleParam -obj $params -name "fullname" -type "str" -$description = Get-AnsibleParam -obj $params -name "description" -type "str" -$password = Get-AnsibleParam -obj $params -name "password" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent","query" -$update_password = Get-AnsibleParam -obj $params -name "update_password" -type "str" -default "always" -validateset "always","on_create" -$password_expired = Get-AnsibleParam -obj $params -name "password_expired" -type "bool" -$password_never_expires = Get-AnsibleParam -obj $params -name "password_never_expires" -type "bool" -$user_cannot_change_password = Get-AnsibleParam -obj $params -name "user_cannot_change_password" -type "bool" -$account_disabled = Get-AnsibleParam -obj $params -name "account_disabled" -type "bool" -$account_locked = Get-AnsibleParam -obj $params -name "account_locked" -type "bool" -$groups = Get-AnsibleParam -obj $params -name "groups" -$groups_action = Get-AnsibleParam -obj $params -name "groups_action" -type "str" -default "replace" -validateset "add","remove","replace" - -If ($null -ne $account_locked -and $account_locked) { - Fail-Json $result "account_locked must be set to 'no' if provided" -} - -If ($null -ne $groups) { - If ($groups -is [System.String]) { - [string[]]$groups = $groups.Split(",") - } - ElseIf ($groups -isnot [System.Collections.IList]) { - Fail-Json $result "groups must be a string or array" - } - $groups = $groups | ForEach-Object { ([string]$_).Trim() } | Where-Object { $_ } - If ($null -eq $groups) { - $groups = @() - } -} - -$user_obj = Get-User $username - -If ($state -eq 'present') { - # Add or update user - try { - If (-not $user_obj) { - $user_obj = $adsi.Create("User", $username) - If ($null -ne $password) { - $user_obj.SetPassword($password) - } - $user_obj.SetInfo() - $result.changed = $true - } - ElseIf (($null -ne $password) -and ($update_password -eq 'always')) { - # ValidateCredentials will fail if either of these are true- just force update... - If($user_obj.AccountDisabled -or $user_obj.PasswordExpired) { - $password_match = $false - } - Else { - try { - $password_match = Test-LocalCredential -Username $username -Password $password - } catch [System.ComponentModel.Win32Exception] { - Fail-Json -obj $result -message "Failed to validate the user's credentials: $($_.Exception.Message)" - } - } - - If (-not $password_match) { - $user_obj.SetPassword($password) - $result.changed = $true - } - } - If (($null -ne $fullname) -and ($fullname -ne $user_obj.FullName[0])) { - $user_obj.FullName = $fullname - $result.changed = $true - } - If (($null -ne $description) -and ($description -ne $user_obj.Description[0])) { - $user_obj.Description = $description - $result.changed = $true - } - If (($null -ne $password_expired) -and ($password_expired -ne ($user_obj.PasswordExpired | ConvertTo-Bool))) { - $user_obj.PasswordExpired = If ($password_expired) { 1 } Else { 0 } - $result.changed = $true - } - If (($null -ne $password_never_expires) -and ($password_never_expires -ne (Get-UserFlag $user_obj $ADS_UF_DONT_EXPIRE_PASSWD))) { - If ($password_never_expires) { - Set-UserFlag $user_obj $ADS_UF_DONT_EXPIRE_PASSWD - } - Else { - Clear-UserFlag $user_obj $ADS_UF_DONT_EXPIRE_PASSWD - } - $result.changed = $true - } - If (($null -ne $user_cannot_change_password) -and ($user_cannot_change_password -ne (Get-UserFlag $user_obj $ADS_UF_PASSWD_CANT_CHANGE))) { - If ($user_cannot_change_password) { - Set-UserFlag $user_obj $ADS_UF_PASSWD_CANT_CHANGE - } - Else { - Clear-UserFlag $user_obj $ADS_UF_PASSWD_CANT_CHANGE - } - $result.changed = $true - } - If (($null -ne $account_disabled) -and ($account_disabled -ne $user_obj.AccountDisabled)) { - $user_obj.AccountDisabled = $account_disabled - $result.changed = $true - } - If (($null -ne $account_locked) -and ($account_locked -ne $user_obj.IsAccountLocked)) { - $user_obj.IsAccountLocked = $account_locked - $result.changed = $true - } - If ($result.changed) { - $user_obj.SetInfo() - } - If ($null -ne $groups) { - [string[]]$current_groups = $user_obj.Groups() | ForEach-Object { $_.GetType().InvokeMember("Name", "GetProperty", $null, $_, $null) } - If (($groups_action -eq "remove") -or ($groups_action -eq "replace")) { - ForEach ($grp in $current_groups) { - If ((($groups_action -eq "remove") -and ($groups -contains $grp)) -or (($groups_action -eq "replace") -and ($groups -notcontains $grp))) { - $group_obj = Get-Group $grp - If ($group_obj) { - $group_obj.Remove($user_obj.Path) - $result.changed = $true - } - Else { - Fail-Json $result "group '$grp' not found" - } - } - } - } - If (($groups_action -eq "add") -or ($groups_action -eq "replace")) { - ForEach ($grp in $groups) { - If ($current_groups -notcontains $grp) { - $group_obj = Get-Group $grp - If ($group_obj) { - $group_obj.Add($user_obj.Path) - $result.changed = $true - } - Else { - Fail-Json $result "group '$grp' not found" - } - } - } - } - } - } - catch { - Fail-Json $result $_.Exception.Message - } -} -ElseIf ($state -eq 'absent') { - # Remove user - try { - If ($user_obj) { - $username = $user_obj.Name.Value - $adsi.delete("User", $user_obj.Name.Value) - $result.changed = $true - $result.msg = "User '$username' deleted successfully" - $user_obj = $null - } else { - $result.msg = "User '$username' was not found" - } - } - catch { - Fail-Json $result $_.Exception.Message - } -} - -try { - If ($user_obj -and $user_obj -is [System.DirectoryServices.DirectoryEntry]) { - $user_obj.RefreshCache() - $result.name = $user_obj.Name[0] - $result.fullname = $user_obj.FullName[0] - $result.path = $user_obj.Path - $result.description = $user_obj.Description[0] - $result.password_expired = ($user_obj.PasswordExpired | ConvertTo-Bool) - $result.password_never_expires = (Get-UserFlag $user_obj $ADS_UF_DONT_EXPIRE_PASSWD) - $result.user_cannot_change_password = (Get-UserFlag $user_obj $ADS_UF_PASSWD_CANT_CHANGE) - $result.account_disabled = $user_obj.AccountDisabled - $result.account_locked = $user_obj.IsAccountLocked - $result.sid = (New-Object System.Security.Principal.SecurityIdentifier($user_obj.ObjectSid.Value, 0)).Value - $user_groups = @() - ForEach ($grp in $user_obj.Groups()) { - $group_result = @{ - name = $grp.GetType().InvokeMember("Name", "GetProperty", $null, $grp, $null) - path = $grp.GetType().InvokeMember("ADsPath", "GetProperty", $null, $grp, $null) - } - $user_groups += $group_result; - } - $result.groups = $user_groups - $result.state = "present" - } - Else { - $result.name = $username - if ($state -eq 'query') { - $result.msg = "User '$username' was not found" - } - $result.state = "absent" - } -} -catch { - Fail-Json $result $_.Exception.Message -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_user.py b/lib/ansible/modules/windows/win_user.py deleted file mode 100644 index 5fc0633d06..0000000000 --- a/lib/ansible/modules/windows/win_user.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2014, Matt Martz <matt@sivel.net>, and others -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'core'} - -DOCUMENTATION = r''' ---- -module: win_user -version_added: "1.7" -short_description: Manages local Windows user accounts -description: - - Manages local Windows user accounts. - - For non-Windows targets, use the M(user) module instead. -options: - name: - description: - - Name of the user to create, remove or modify. - type: str - required: yes - fullname: - description: - - Full name of the user. - type: str - version_added: "1.9" - description: - description: - - Description of the user. - type: str - version_added: "1.9" - password: - description: - - Optionally set the user's password to this (plain text) value. - type: str - update_password: - description: - - C(always) will update passwords if they differ. C(on_create) will - only set the password for newly created users. - type: str - choices: [ always, on_create ] - default: always - version_added: "1.9" - password_expired: - description: - - C(yes) will require the user to change their password at next login. - - C(no) will clear the expired password flag. - type: bool - version_added: "1.9" - password_never_expires: - description: - - C(yes) will set the password to never expire. - - C(no) will allow the password to expire. - type: bool - version_added: "1.9" - user_cannot_change_password: - description: - - C(yes) will prevent the user from changing their password. - - C(no) will allow the user to change their password. - type: bool - version_added: "1.9" - account_disabled: - description: - - C(yes) will disable the user account. - - C(no) will clear the disabled flag. - type: bool - version_added: "1.9" - account_locked: - description: - - C(no) will unlock the user account if locked. - choices: [ 'no' ] - version_added: "1.9" - groups: - description: - - Adds or removes the user from this comma-separated list of groups, - depending on the value of I(groups_action). - - When I(groups_action) is C(replace) and I(groups) is set to the empty - string ('groups='), the user is removed from all groups. - version_added: "1.9" - groups_action: - description: - - If C(add), the user is added to each group in I(groups) where not - already a member. - - If C(replace), the user is added as a member of each group in - I(groups) and removed from any other groups. - - If C(remove), the user is removed from each group in I(groups). - type: str - choices: [ add, replace, remove ] - default: replace - version_added: "1.9" - state: - description: - - When C(absent), removes the user account if it exists. - - When C(present), creates or updates the user account. - - When C(query) (new in 1.9), retrieves the user account details - without making any changes. - type: str - choices: [ absent, present, query ] - default: present -seealso: -- module: user -- module: win_domain_membership -- module: win_domain_user -- module: win_group -- module: win_group_membership -- module: win_user_profile -author: - - Paul Durivage (@angstwad) - - Chris Church (@cchurch) -''' - -EXAMPLES = r''' -- name: Ensure user bob is present - win_user: - name: bob - password: B0bP4ssw0rd - state: present - groups: - - Users - -- name: Ensure user bob is absent - win_user: - name: bob - state: absent -''' - -RETURN = r''' -account_disabled: - description: Whether the user is disabled. - returned: user exists - type: bool - sample: false -account_locked: - description: Whether the user is locked. - returned: user exists - type: bool - sample: false -description: - description: The description set for the user. - returned: user exists - type: str - sample: Username for test -fullname: - description: The full name set for the user. - returned: user exists - type: str - sample: Test Username -groups: - description: A list of groups and their ADSI path the user is a member of. - returned: user exists - type: list - sample: [ - { - "name": "Administrators", - "path": "WinNT://WORKGROUP/USER-PC/Administrators" - } - ] -name: - description: The name of the user - returned: always - type: str - sample: username -password_expired: - description: Whether the password is expired. - returned: user exists - type: bool - sample: false -password_never_expires: - description: Whether the password is set to never expire. - returned: user exists - type: bool - sample: true -path: - description: The ADSI path for the user. - returned: user exists - type: str - sample: "WinNT://WORKGROUP/USER-PC/username" -sid: - description: The SID for the user. - returned: user exists - type: str - sample: S-1-5-21-3322259488-2828151810-3939402796-1001 -user_cannot_change_password: - description: Whether the user can change their own password. - returned: user exists - type: bool - sample: false -''' diff --git a/lib/ansible/modules/windows/win_user_right.ps1 b/lib/ansible/modules/windows/win_user_right.ps1 deleted file mode 100644 index 3fac52a8a8..0000000000 --- a/lib/ansible/modules/windows/win_user_right.ps1 +++ /dev/null @@ -1,349 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.SID - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $true -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$users = Get-AnsibleParam -obj $params -name "users" -type "list" -failifempty $true -$action = Get-AnsibleParam -obj $params -name "action" -type "str" -default "set" -validateset "add","remove","set" - -$result = @{ - changed = $false - added = @() - removed = @() -} - -if ($diff_mode) { - $result.diff = @{} -} - -$sec_helper_util = @" -using System; -using System.ComponentModel; -using System.Runtime.InteropServices; -using System.Security.Principal; - -namespace Ansible -{ - public class LsaRightHelper : IDisposable - { - // Code modified from https://gallery.technet.microsoft.com/scriptcenter/Grant-Revoke-Query-user-26e259b0 - - enum Access : int - { - POLICY_READ = 0x20006, - POLICY_ALL_ACCESS = 0x00F0FFF, - POLICY_EXECUTE = 0X20801, - POLICY_WRITE = 0X207F8 - } - - IntPtr lsaHandle; - - const string LSA_DLL = "advapi32.dll"; - const CharSet DEFAULT_CHAR_SET = CharSet.Unicode; - - const uint STATUS_NO_MORE_ENTRIES = 0x8000001a; - const uint STATUS_NO_SUCH_PRIVILEGE = 0xc0000060; - - internal sealed class Sid : IDisposable - { - public IntPtr pSid = IntPtr.Zero; - public SecurityIdentifier sid = null; - - public Sid(string sidString) - { - try - { - sid = new SecurityIdentifier(sidString); - } catch - { - throw new ArgumentException(String.Format("SID string {0} could not be converted to SecurityIdentifier", sidString)); - } - - Byte[] buffer = new Byte[sid.BinaryLength]; - sid.GetBinaryForm(buffer, 0); - - pSid = Marshal.AllocHGlobal(sid.BinaryLength); - Marshal.Copy(buffer, 0, pSid, sid.BinaryLength); - } - - public void Dispose() - { - if (pSid != IntPtr.Zero) - { - Marshal.FreeHGlobal(pSid); - pSid = IntPtr.Zero; - } - GC.SuppressFinalize(this); - } - ~Sid() { Dispose(); } - } - - [StructLayout(LayoutKind.Sequential)] - private struct LSA_OBJECT_ATTRIBUTES - { - public int Length; - public IntPtr RootDirectory; - public IntPtr ObjectName; - public int Attributes; - public IntPtr SecurityDescriptor; - public IntPtr SecurityQualityOfService; - } - - [StructLayout(LayoutKind.Sequential, CharSet = DEFAULT_CHAR_SET)] - private struct LSA_UNICODE_STRING - { - public ushort Length; - public ushort MaximumLength; - [MarshalAs(UnmanagedType.LPWStr)] - public string Buffer; - } - - [StructLayout(LayoutKind.Sequential)] - private struct LSA_ENUMERATION_INFORMATION - { - public IntPtr Sid; - } - - [DllImport(LSA_DLL, CharSet = DEFAULT_CHAR_SET, SetLastError = true)] - private static extern uint LsaOpenPolicy( - LSA_UNICODE_STRING[] SystemName, - ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, - int AccessMask, - out IntPtr PolicyHandle - ); - - [DllImport(LSA_DLL, CharSet = DEFAULT_CHAR_SET, SetLastError = true)] - private static extern uint LsaAddAccountRights( - IntPtr PolicyHandle, - IntPtr pSID, - LSA_UNICODE_STRING[] UserRights, - int CountOfRights - ); - - [DllImport(LSA_DLL, CharSet = DEFAULT_CHAR_SET, SetLastError = true)] - private static extern uint LsaRemoveAccountRights( - IntPtr PolicyHandle, - IntPtr pSID, - bool AllRights, - LSA_UNICODE_STRING[] UserRights, - int CountOfRights - ); - - [DllImport(LSA_DLL, CharSet = DEFAULT_CHAR_SET, SetLastError = true)] - private static extern uint LsaEnumerateAccountsWithUserRight( - IntPtr PolicyHandle, - LSA_UNICODE_STRING[] UserRights, - out IntPtr EnumerationBuffer, - out ulong CountReturned - ); - - [DllImport(LSA_DLL)] - private static extern int LsaNtStatusToWinError(int NTSTATUS); - - [DllImport(LSA_DLL)] - private static extern int LsaClose(IntPtr PolicyHandle); - - [DllImport(LSA_DLL)] - private static extern int LsaFreeMemory(IntPtr Buffer); - - public LsaRightHelper() - { - LSA_OBJECT_ATTRIBUTES lsaAttr; - lsaAttr.RootDirectory = IntPtr.Zero; - lsaAttr.ObjectName = IntPtr.Zero; - lsaAttr.Attributes = 0; - lsaAttr.SecurityDescriptor = IntPtr.Zero; - lsaAttr.SecurityQualityOfService = IntPtr.Zero; - lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES)); - - lsaHandle = IntPtr.Zero; - - LSA_UNICODE_STRING[] system = new LSA_UNICODE_STRING[1]; - system[0] = InitLsaString(""); - - uint ret = LsaOpenPolicy(system, ref lsaAttr, (int)Access.POLICY_ALL_ACCESS, out lsaHandle); - if (ret != 0) - throw new Win32Exception(LsaNtStatusToWinError((int)ret)); - } - - public void AddPrivilege(string sidString, string privilege) - { - uint ret = 0; - using (Sid sid = new Sid(sidString)) - { - LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1]; - privileges[0] = InitLsaString(privilege); - ret = LsaAddAccountRights(lsaHandle, sid.pSid, privileges, 1); - } - if (ret != 0) - throw new Win32Exception(LsaNtStatusToWinError((int)ret)); - } - - public void RemovePrivilege(string sidString, string privilege) - { - uint ret = 0; - using (Sid sid = new Sid(sidString)) - { - LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1]; - privileges[0] = InitLsaString(privilege); - ret = LsaRemoveAccountRights(lsaHandle, sid.pSid, false, privileges, 1); - } - if (ret != 0) - throw new Win32Exception(LsaNtStatusToWinError((int)ret)); - } - - public string[] EnumerateAccountsWithUserRight(string privilege) - { - uint ret = 0; - ulong count = 0; - LSA_UNICODE_STRING[] rights = new LSA_UNICODE_STRING[1]; - rights[0] = InitLsaString(privilege); - IntPtr buffer = IntPtr.Zero; - - ret = LsaEnumerateAccountsWithUserRight(lsaHandle, rights, out buffer, out count); - switch (ret) - { - case 0: - string[] accounts = new string[count]; - for (int i = 0; i < (int)count; i++) - { - LSA_ENUMERATION_INFORMATION LsaInfo = (LSA_ENUMERATION_INFORMATION)Marshal.PtrToStructure( - IntPtr.Add(buffer, i * Marshal.SizeOf(typeof(LSA_ENUMERATION_INFORMATION))), - typeof(LSA_ENUMERATION_INFORMATION)); - - accounts[i] = new SecurityIdentifier(LsaInfo.Sid).ToString(); - } - LsaFreeMemory(buffer); - return accounts; - - case STATUS_NO_MORE_ENTRIES: - return new string[0]; - - case STATUS_NO_SUCH_PRIVILEGE: - throw new ArgumentException(String.Format("Invalid privilege {0} not found in LSA database", privilege)); - - default: - throw new Win32Exception(LsaNtStatusToWinError((int)ret)); - } - } - - static LSA_UNICODE_STRING InitLsaString(string s) - { - // Unicode strings max. 32KB - if (s.Length > 0x7ffe) - throw new ArgumentException("String too long"); - - LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING(); - lus.Buffer = s; - lus.Length = (ushort)(s.Length * sizeof(char)); - lus.MaximumLength = (ushort)(lus.Length + sizeof(char)); - - return lus; - } - - public void Dispose() - { - if (lsaHandle != IntPtr.Zero) - { - LsaClose(lsaHandle); - lsaHandle = IntPtr.Zero; - } - GC.SuppressFinalize(this); - } - ~LsaRightHelper() { Dispose(); } - } -} -"@ - -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $sec_helper_util -$env:TMP = $original_tmp - -Function Compare-UserList($existing_users, $new_users) { - $added_users = [String[]]@() - $removed_users = [String[]]@() - if ($action -eq "add") { - $added_users = [Linq.Enumerable]::Except($new_users, $existing_users) - } elseif ($action -eq "remove") { - $removed_users = [Linq.Enumerable]::Intersect($new_users, $existing_users) - } else { - $added_users = [Linq.Enumerable]::Except($new_users, $existing_users) - $removed_users = [Linq.Enumerable]::Except($existing_users, $new_users) - } - - $change_result = @{ - added = $added_users - removed = $removed_users - } - - return $change_result -} - -# C# class we can use to enumerate/add/remove rights -$lsa_helper = New-Object -TypeName Ansible.LsaRightHelper - -$new_users = [System.Collections.ArrayList]@() -foreach ($user in $users) { - $user_sid = Convert-ToSID -account_name $user - $new_users.Add($user_sid) > $null -} -$new_users = [String[]]$new_users.ToArray() -try { - $existing_users = $lsa_helper.EnumerateAccountsWithUserRight($name) -} catch [ArgumentException] { - Fail-Json -obj $result -message "the specified right $name is not a valid right" -} catch { - Fail-Json -obj $result -message "failed to enumerate existing accounts with right: $($_.Exception.Message)" -} - -$change_result = Compare-UserList -existing_users $existing_users -new_user $new_users -if (($change_result.added.Length -gt 0) -or ($change_result.removed.Length -gt 0)) { - $result.changed = $true - $diff_text = "[$name]`n" - - # used in diff mode calculation - $new_user_list = [System.Collections.ArrayList]$existing_users - foreach ($user in $change_result.removed) { - if (-not $check_mode) { - $lsa_helper.RemovePrivilege($user, $name) - } - $user_name = Convert-FromSID -sid $user - $result.removed += $user_name - $diff_text += "-$user_name`n" - $new_user_list.Remove($user) > $null - } - foreach ($user in $change_result.added) { - if (-not $check_mode) { - $lsa_helper.AddPrivilege($user, $name) - } - $user_name = Convert-FromSID -sid $user - $result.added += $user_name - $diff_text += "+$user_name`n" - $new_user_list.Add($user) > $null - } - - if ($diff_mode) { - if ($new_user_list.Count -eq 0) { - $diff_text = "-$diff_text" - } else { - if ($existing_users.Count -eq 0) { - $diff_text = "+$diff_text" - } - } - $result.diff.prepared = $diff_text - } -} - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_user_right.py b/lib/ansible/modules/windows/win_user_right.py deleted file mode 100644 index 5588208333..0000000000 --- a/lib/ansible/modules/windows/win_user_right.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_user_right -version_added: '2.4' -short_description: Manage Windows User Rights -description: -- Add, remove or set User Rights for a group or users or groups. -- You can set user rights for both local and domain accounts. -options: - name: - description: - - The name of the User Right as shown by the C(Constant Name) value from - U(https://technet.microsoft.com/en-us/library/dd349804.aspx). - - The module will return an error if the right is invalid. - type: str - required: yes - users: - description: - - A list of users or groups to add/remove on the User Right. - - These can be in the form DOMAIN\user-group, user-group@DOMAIN.COM for - domain users/groups. - - For local users/groups it can be in the form user-group, .\user-group, - SERVERNAME\user-group where SERVERNAME is the name of the remote server. - - You can also add special local accounts like SYSTEM and others. - - Can be set to an empty list with I(action=set) to remove all accounts - from the right. - type: list - required: yes - action: - description: - - C(add) will add the users/groups to the existing right. - - C(remove) will remove the users/groups from the existing right. - - C(set) will replace the users/groups of the existing right. - type: str - default: set - choices: [ add, remove, set ] -notes: -- If the server is domain joined this module can change a right but if a GPO - governs this right then the changes won't last. -seealso: -- module: win_group -- module: win_group_membership -- module: win_user -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' ---- -- name: Replace the entries of Deny log on locally - win_user_right: - name: SeDenyInteractiveLogonRight - users: - - Guest - - Users - action: set - -- name: Add account to Log on as a service - win_user_right: - name: SeServiceLogonRight - users: - - .\Administrator - - '{{ansible_hostname}}\local-user' - action: add - -- name: Remove accounts who can create Symbolic links - win_user_right: - name: SeCreateSymbolicLinkPrivilege - users: - - SYSTEM - - Administrators - - DOMAIN\User - - group@DOMAIN.COM - action: remove - -- name: Remove all accounts who cannot log on remote interactively - win_user_right: - name: SeDenyRemoteInteractiveLogonRight - users: [] -''' - -RETURN = r''' -added: - description: A list of accounts that were added to the right, this is empty - if no accounts were added. - returned: success - type: list - sample: ["NT AUTHORITY\\SYSTEM", "DOMAIN\\User"] -removed: - description: A list of accounts that were removed from the right, this is - empty if no accounts were removed. - returned: success - type: list - sample: ["SERVERNAME\\Administrator", "BUILTIN\\Administrators"] -''' diff --git a/lib/ansible/modules/windows/win_wait_for.ps1 b/lib/ansible/modules/windows/win_wait_for.ps1 deleted file mode 100644 index e0a9a720b9..0000000000 --- a/lib/ansible/modules/windows/win_wait_for.ps1 +++ /dev/null @@ -1,259 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.FileUtil - -$ErrorActionPreference = "Stop" - -$params = Parse-Args -arguments $args -supports_check_mode $true - -$connect_timeout = Get-AnsibleParam -obj $params -name "connect_timeout" -type "int" -default 5 -$delay = Get-AnsibleParam -obj $params -name "delay" -type "int" -$exclude_hosts = Get-AnsibleParam -obj $params -name "exclude_hosts" -type "list" -$hostname = Get-AnsibleParam -obj $params -name "host" -type "str" -default "127.0.0.1" -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -$port = Get-AnsibleParam -obj $params -name "port" -type "int" -$regex = Get-AnsibleParam -obj $params -name "regex" -type "str" -aliases "search_regex","regexp" -$sleep = Get-AnsibleParam -obj $params -name "sleep" -type "int" -default 1 -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "started" -validateset "present","started","stopped","absent","drained" -$timeout = Get-AnsibleParam -obj $params -name "timeout" -type "int" -default 300 - -$result = @{ - changed = $false - elapsed = 0 -} - -# validate the input with the various options -if ($null -ne $port -and $null -ne $path) { - Fail-Json $result "port and path parameter can not both be passed to win_wait_for" -} -if ($null -ne $exclude_hosts -and $state -ne "drained") { - Fail-Json $result "exclude_hosts should only be with state=drained" -} -if ($null -ne $path) { - if ($state -in @("stopped","drained")) { - Fail-Json $result "state=$state should only be used for checking a port in the win_wait_for module" - } - - if ($null -ne $exclude_hosts) { - Fail-Json $result "exclude_hosts should only be used when checking a port and state=drained in the win_wait_for module" - } -} - -if ($null -ne $port) { - if ($null -ne $regex) { - Fail-Json $result "regex should by used when checking a string in a file in the win_wait_for module" - } - - if ($null -ne $exclude_hosts -and $state -ne "drained") { - Fail-Json $result "exclude_hosts should be used when state=drained in the win_wait_for module" - } -} - -Function Test-Port($hostname, $port) { - $timeout = $connect_timeout * 1000 - $socket = New-Object -TypeName System.Net.Sockets.TcpClient - $connect = $socket.BeginConnect($hostname, $port, $null, $null) - $wait = $connect.AsyncWaitHandle.WaitOne($timeout, $false) - - if ($wait) { - try { - $socket.EndConnect($connect) | Out-Null - $valid = $true - } catch { - $valid = $false - } - } else { - $valid = $false - } - - $socket.Close() - $socket.Dispose() - - $valid -} - -Function Get-PortConnections($hostname, $port) { - $connections = @() - - $conn_info = [Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties() - if ($hostname -eq "0.0.0.0") { - $active_connections = $conn_info.GetActiveTcpConnections() | Where-Object { $_.LocalEndPoint.Port -eq $port } - } else { - $active_connections = $conn_info.GetActiveTcpConnections() | Where-Object { $_.LocalEndPoint.Address -eq $hostname -and $_.LocalEndPoint.Port -eq $port } - } - - if ($null -ne $active_connections) { - foreach ($active_connection in $active_connections) { - $connections += $active_connection.RemoteEndPoint.Address - } - } - - $connections -} - -$module_start = Get-Date - -if ($null -ne $delay) { - Start-Sleep -Seconds $delay -} - -$attempts = 0 -if ($null -eq $path -and $null -eq $port -and $state -ne "drained") { - Start-Sleep -Seconds $timeout -} elseif ($null -ne $path) { - if ($state -in @("present", "started")) { - # check if the file exists or string exists in file - $start_time = Get-Date - $complete = $false - while (((Get-Date) - $start_time).TotalSeconds -lt $timeout) { - $attempts += 1 - if (Test-AnsiblePath -Path $path) { - if ($null -eq $regex) { - $complete = $true - break - } else { - $file_contents = Get-Content -Path $path -Raw - if ($file_contents -match $regex) { - $complete = $true - break - } - } - } - Start-Sleep -Seconds $sleep - } - - if ($complete -eq $false) { - $result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $result.wait_attempts = $attempts - if ($null -eq $regex) { - Fail-Json $result "timeout while waiting for file $path to be present" - } else { - Fail-Json $result "timeout while waiting for string regex $regex in file $path to match" - } - } - } elseif ($state -in @("absent")) { - # check if the file is deleted or string doesn't exist in file - $start_time = Get-Date - $complete = $false - while (((Get-Date) - $start_time).TotalSeconds -lt $timeout) { - $attempts += 1 - if (Test-AnsiblePath -Path $path) { - if ($null -ne $regex) { - $file_contents = Get-Content -Path $path -Raw - if ($file_contents -notmatch $regex) { - $complete = $true - break - } - } - } else { - $complete = $true - break - } - - Start-Sleep -Seconds $sleep - } - - if ($complete -eq $false) { - $result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $result.wait_attempts = $attempts - if ($null -eq $regex) { - Fail-Json $result "timeout while waiting for file $path to be absent" - } else { - Fail-Json $result "timeout while waiting for string regex $regex in file $path to not match" - } - } - } -} elseif ($null -ne $port) { - if ($state -in @("started","present")) { - # check that the port is online and is listening - $start_time = Get-Date - $complete = $false - while (((Get-Date) - $start_time).TotalSeconds -lt $timeout) { - $attempts += 1 - $port_result = Test-Port -hostname $hostname -port $port - if ($port_result -eq $true) { - $complete = $true - break - } - - Start-Sleep -Seconds $sleep - } - - if ($complete -eq $false) { - $result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $result.wait_attempts = $attempts - Fail-Json $result "timeout while waiting for $($hostname):$port to start listening" - } - } elseif ($state -in @("stopped","absent")) { - # check that the port is offline and is not listening - $start_time = Get-Date - $complete = $false - while (((Get-Date) - $start_time).TotalSeconds -lt $timeout) { - $attempts += 1 - $port_result = Test-Port -hostname $hostname -port $port - if ($port_result -eq $false) { - $complete = $true - break - } - - Start-Sleep -Seconds $sleep - } - - if ($complete -eq $false) { - $result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $result.wait_attempts = $attempts - Fail-Json $result "timeout while waiting for $($hostname):$port to stop listening" - } - } elseif ($state -eq "drained") { - # check that the local port is online but has no active connections - $start_time = Get-Date - $complete = $false - while (((Get-Date) - $start_time).TotalSeconds -lt $timeout) { - $attempts += 1 - $active_connections = Get-PortConnections -hostname $hostname -port $port - if ($null -eq $active_connections) { - $complete = $true - break - } elseif ($active_connections.Count -eq 0) { - # no connections on port - $complete = $true - break - } else { - # there are listeners, check if we should ignore any hosts - if ($null -ne $exclude_hosts) { - $connection_info = $active_connections - foreach ($exclude_host in $exclude_hosts) { - try { - $exclude_ips = [System.Net.Dns]::GetHostAddresses($exclude_host) | ForEach-Object { Write-Output $_.IPAddressToString } - $connection_info = $connection_info | Where-Object { $_ -notin $exclude_ips } - } catch { # ignore invalid hostnames - Add-Warning -obj $result -message "Invalid hostname specified $exclude_host" - } - } - - if ($connection_info.Count -eq 0) { - $complete = $true - break - } - } - } - - Start-Sleep -Seconds $sleep - } - - if ($complete -eq $false) { - $result.elapsed = ((Get-Date) - $module_start).TotalSeconds - $result.wait_attempts = $attempts - Fail-Json $result "timeout while waiting for $($hostname):$port to drain" - } - } -} - -$result.elapsed = ((Get-Date) - $module_start).TotalSeconds -$result.wait_attempts = $attempts - -Exit-Json $result diff --git a/lib/ansible/modules/windows/win_wait_for.py b/lib/ansible/modules/windows/win_wait_for.py deleted file mode 100644 index 85721e7d53..0000000000 --- a/lib/ansible/modules/windows/win_wait_for.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub, actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_wait_for -version_added: '2.4' -short_description: Waits for a condition before continuing -description: -- You can wait for a set amount of time C(timeout), this is the default if - nothing is specified. -- Waiting for a port to become available is useful for when services are not - immediately available after their init scripts return which is true of - certain Java application servers. -- You can wait for a file to exist or not exist on the filesystem. -- This module can also be used to wait for a regex match string to be present - in a file. -- You can wait for active connections to be closed before continuing on a - local port. -options: - connect_timeout: - description: - - The maximum number of seconds to wait for a connection to happen before - closing and retrying. - type: int - default: 5 - delay: - description: - - The number of seconds to wait before starting to poll. - type: int - exclude_hosts: - description: - - The list of hosts or IPs to ignore when looking for active TCP - connections when C(state=drained). - type: list - host: - description: - - A resolvable hostname or IP address to wait for. - - If C(state=drained) then it will only check for connections on the IP - specified, you can use '0.0.0.0' to use all host IPs. - type: str - default: '127.0.0.1' - path: - description: - - The path to a file on the filesystem to check. - - If C(state) is present or started then it will wait until the file - exists. - - If C(state) is absent then it will wait until the file does not exist. - type: path - port: - description: - - The port number to poll on C(host). - type: int - regex: - description: - - Can be used to match a string in a file. - - If C(state) is present or started then it will wait until the regex - matches. - - If C(state) is absent then it will wait until the regex does not match. - - Defaults to a multiline regex. - type: str - aliases: [ "search_regex", "regexp" ] - sleep: - description: - - Number of seconds to sleep between checks. - type: int - default: 1 - state: - description: - - When checking a port, C(started) will ensure the port is open, C(stopped) - will check that is it closed and C(drained) will check for active - connections. - - When checking for a file or a search string C(present) or C(started) will - ensure that the file or string is present, C(absent) will check that the - file or search string is absent or removed. - type: str - choices: [ absent, drained, present, started, stopped ] - default: started - timeout: - description: - - The maximum number of seconds to wait for. - type: int - default: 300 -seealso: -- module: wait_for -- module: win_wait_for_process -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Wait 300 seconds for port 8000 to become open on the host, don't start checking for 10 seconds - win_wait_for: - port: 8000 - delay: 10 - -- name: Wait 150 seconds for port 8000 of any IP to close active connections - win_wait_for: - host: 0.0.0.0 - port: 8000 - state: drained - timeout: 150 - -- name: Wait for port 8000 of any IP to close active connection, ignoring certain hosts - win_wait_for: - host: 0.0.0.0 - port: 8000 - state: drained - exclude_hosts: ['10.2.1.2', '10.2.1.3'] - -- name: Wait for file C:\temp\log.txt to exist before continuing - win_wait_for: - path: C:\temp\log.txt - -- name: Wait until process complete is in the file before continuing - win_wait_for: - path: C:\temp\log.txt - regex: process complete - -- name: Wait until file is removed - win_wait_for: - path: C:\temp\log.txt - state: absent - -- name: Wait until port 1234 is offline but try every 10 seconds - win_wait_for: - port: 1234 - state: absent - sleep: 10 -''' - -RETURN = r''' -wait_attempts: - description: The number of attempts to poll the file or port before module - finishes. - returned: always - type: int - sample: 1 -elapsed: - description: The elapsed seconds between the start of poll and the end of the - module. This includes the delay if the option is set. - returned: always - type: float - sample: 2.1406487 -''' diff --git a/lib/ansible/modules/windows/win_whoami.ps1 b/lib/ansible/modules/windows/win_whoami.ps1 deleted file mode 100644 index 6c9965af7e..0000000000 --- a/lib/ansible/modules/windows/win_whoami.ps1 +++ /dev/null @@ -1,837 +0,0 @@ -#!powershell - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.CamelConversion - -$ErrorActionPreference = "Stop" - -$params = Parse-Args $args -supports_check_mode $true -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$session_util = @' -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Text; - -namespace Ansible -{ - public class SessionInfo - { - // SECURITY_LOGON_SESSION_DATA - public UInt64 LogonId { get; internal set; } - public Sid Account { get; internal set; } - public string LoginDomain { get; internal set; } - public string AuthenticationPackage { get; internal set; } - public SECURITY_LOGON_TYPE LogonType { get; internal set; } - public string LoginTime { get; internal set; } - public string LogonServer { get; internal set; } - public string DnsDomainName { get; internal set; } - public string Upn { get; internal set; } - public ArrayList UserFlags { get; internal set; } - - // TOKEN_STATISTICS - public SECURITY_IMPERSONATION_LEVEL ImpersonationLevel { get; internal set; } - public TOKEN_TYPE TokenType { get; internal set; } - - // TOKEN_GROUPS - public ArrayList Groups { get; internal set; } - public ArrayList Rights { get; internal set; } - - // TOKEN_MANDATORY_LABEL - public Sid Label { get; internal set; } - - // TOKEN_PRIVILEGES - public Hashtable Privileges { get; internal set; } - } - - public class Win32Exception : System.ComponentModel.Win32Exception - { - private string _msg; - public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) { } - public Win32Exception(int errorCode, string message) : base(errorCode) - { - _msg = String.Format("{0} ({1}, Win32ErrorCode {2})", message, base.Message, errorCode); - } - public override string Message { get { return _msg; } } - public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct LSA_UNICODE_STRING - { - public UInt16 Length; - public UInt16 MaximumLength; - public IntPtr buffer; - } - - [StructLayout(LayoutKind.Sequential)] - public struct LUID - { - public UInt32 LowPart; - public Int32 HighPart; - } - - [StructLayout(LayoutKind.Sequential)] - public struct SECURITY_LOGON_SESSION_DATA - { - public UInt32 Size; - public LUID LogonId; - public LSA_UNICODE_STRING Username; - public LSA_UNICODE_STRING LoginDomain; - public LSA_UNICODE_STRING AuthenticationPackage; - public SECURITY_LOGON_TYPE LogonType; - public UInt32 Session; - public IntPtr Sid; - public UInt64 LoginTime; - public LSA_UNICODE_STRING LogonServer; - public LSA_UNICODE_STRING DnsDomainName; - public LSA_UNICODE_STRING Upn; - public UInt32 UserFlags; - public LSA_LAST_INTER_LOGON_INFO LastLogonInfo; - public LSA_UNICODE_STRING LogonScript; - public LSA_UNICODE_STRING ProfilePath; - public LSA_UNICODE_STRING HomeDirectory; - public LSA_UNICODE_STRING HomeDirectoryDrive; - public UInt64 LogoffTime; - public UInt64 KickOffTime; - public UInt64 PasswordLastSet; - public UInt64 PasswordCanChange; - public UInt64 PasswordMustChange; - } - - [StructLayout(LayoutKind.Sequential)] - public struct LSA_LAST_INTER_LOGON_INFO - { - public UInt64 LastSuccessfulLogon; - public UInt64 LastFailedLogon; - public UInt32 FailedAttemptCountSinceLastSuccessfulLogon; - } - - public enum TOKEN_TYPE - { - TokenPrimary = 1, - TokenImpersonation - } - - public enum SECURITY_IMPERSONATION_LEVEL - { - SecurityAnonymous, - SecurityIdentification, - SecurityImpersonation, - SecurityDelegation - } - - public enum SECURITY_LOGON_TYPE - { - System = 0, // Used only by the Sytem account - Interactive = 2, - Network, - Batch, - Service, - Proxy, - Unlock, - NetworkCleartext, - NewCredentials, - RemoteInteractive, - CachedInteractive, - CachedRemoteInteractive, - CachedUnlock - } - - [Flags] - public enum TokenGroupAttributes : uint - { - SE_GROUP_ENABLED = 0x00000004, - SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002, - SE_GROUP_INTEGRITY = 0x00000020, - SE_GROUP_INTEGRITY_ENABLED = 0x00000040, - SE_GROUP_LOGON_ID = 0xC0000000, - SE_GROUP_MANDATORY = 0x00000001, - SE_GROUP_OWNER = 0x00000008, - SE_GROUP_RESOURCE = 0x20000000, - SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010, - } - - [Flags] - public enum UserFlags : uint - { - LOGON_OPTIMIZED = 0x4000, - LOGON_WINLOGON = 0x8000, - LOGON_PKINIT = 0x10000, - LOGON_NOT_OPTMIZED = 0x20000, - } - - [StructLayout(LayoutKind.Sequential)] - public struct SID_AND_ATTRIBUTES - { - public IntPtr Sid; - public UInt32 Attributes; - } - - [StructLayout(LayoutKind.Sequential)] - public struct LUID_AND_ATTRIBUTES - { - public LUID Luid; - public UInt32 Attributes; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOKEN_GROUPS - { - public UInt32 GroupCount; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public SID_AND_ATTRIBUTES[] Groups; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOKEN_MANDATORY_LABEL - { - public SID_AND_ATTRIBUTES Label; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOKEN_STATISTICS - { - public LUID TokenId; - public LUID AuthenticationId; - public UInt64 ExpirationTime; - public TOKEN_TYPE TokenType; - public SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - public UInt32 DynamicCharged; - public UInt32 DynamicAvailable; - public UInt32 GroupCount; - public UInt32 PrivilegeCount; - public LUID ModifiedId; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOKEN_PRIVILEGES - { - public UInt32 PrivilegeCount; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public LUID_AND_ATTRIBUTES[] Privileges; - } - - public class AccessToken : IDisposable - { - public enum TOKEN_INFORMATION_CLASS - { - TokenUser = 1, - TokenGroups, - TokenPrivileges, - TokenOwner, - TokenPrimaryGroup, - TokenDefaultDacl, - TokenSource, - TokenType, - TokenImpersonationLevel, - TokenStatistics, - TokenRestrictedSids, - TokenSessionId, - TokenGroupsAndPrivileges, - TokenSessionReference, - TokenSandBoxInert, - TokenAuditPolicy, - TokenOrigin, - TokenElevationType, - TokenLinkedToken, - TokenElevation, - TokenHasRestrictions, - TokenAccessInformation, - TokenVirtualizationAllowed, - TokenVirtualizationEnabled, - TokenIntegrityLevel, - TokenUIAccess, - TokenMandatoryPolicy, - TokenLogonSid, - TokenIsAppContainer, - TokenCapabilities, - TokenAppContainerSid, - TokenAppContainerNumber, - TokenUserClaimAttributes, - TokenDeviceClaimAttributes, - TokenRestrictedUserClaimAttributes, - TokenRestrictedDeviceClaimAttributes, - TokenDeviceGroups, - TokenRestrictedDeviceGroups, - TokenSecurityAttributes, - TokenIsRestricted, - MaxTokenInfoClass - } - - public IntPtr hToken = IntPtr.Zero; - - [DllImport("kernel32.dll")] - private static extern IntPtr GetCurrentProcess(); - - [DllImport("advapi32.dll", SetLastError = true)] - private static extern bool OpenProcessToken( - IntPtr ProcessHandle, - TokenAccessLevels DesiredAccess, - out IntPtr TokenHandle); - - [DllImport("advapi32.dll", SetLastError = true)] - private static extern bool GetTokenInformation( - IntPtr TokenHandle, - TOKEN_INFORMATION_CLASS TokenInformationClass, - IntPtr TokenInformation, - UInt32 TokenInformationLength, - out UInt32 ReturnLength); - - public AccessToken(TokenAccessLevels tokenAccessLevels) - { - IntPtr currentProcess = GetCurrentProcess(); - if (!OpenProcessToken(currentProcess, tokenAccessLevels, out hToken)) - throw new Win32Exception("OpenProcessToken() for current process failed"); - } - - public IntPtr GetTokenInformation<T>(out T tokenInformation, TOKEN_INFORMATION_CLASS tokenClass) - { - UInt32 tokenLength = 0; - GetTokenInformation(hToken, tokenClass, IntPtr.Zero, 0, out tokenLength); - - IntPtr infoPtr = Marshal.AllocHGlobal((int)tokenLength); - - if (!GetTokenInformation(hToken, tokenClass, infoPtr, tokenLength, out tokenLength)) - throw new Win32Exception(String.Format("GetTokenInformation() data for {0} failed", tokenClass.ToString())); - - tokenInformation = (T)Marshal.PtrToStructure(infoPtr, typeof(T)); - return infoPtr; - } - - public void Dispose() - { - GC.SuppressFinalize(this); - } - - ~AccessToken() { Dispose(); } - } - - public class LsaHandle : IDisposable - { - [Flags] - public enum DesiredAccess : uint - { - POLICY_VIEW_LOCAL_INFORMATION = 0x00000001, - POLICY_VIEW_AUDIT_INFORMATION = 0x00000002, - POLICY_GET_PRIVATE_INFORMATION = 0x00000004, - POLICY_TRUST_ADMIN = 0x00000008, - POLICY_CREATE_ACCOUNT = 0x00000010, - POLICY_CREATE_SECRET = 0x00000020, - POLICY_CREATE_PRIVILEGE = 0x00000040, - POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080, - POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100, - POLICY_AUDIT_LOG_ADMIN = 0x00000200, - POLICY_SERVER_ADMIN = 0x00000400, - POLICY_LOOKUP_NAMES = 0x00000800, - POLICY_NOTIFICATION = 0x00001000 - } - - public IntPtr handle = IntPtr.Zero; - - [DllImport("advapi32.dll", SetLastError = true)] - private static extern uint LsaOpenPolicy( - LSA_UNICODE_STRING[] SystemName, - ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, - DesiredAccess AccessMask, - out IntPtr PolicyHandle); - - [DllImport("advapi32.dll", SetLastError = true)] - private static extern uint LsaClose( - IntPtr ObjectHandle); - - [DllImport("advapi32.dll", SetLastError = false)] - private static extern int LsaNtStatusToWinError( - uint Status); - - [StructLayout(LayoutKind.Sequential)] - public struct LSA_OBJECT_ATTRIBUTES - { - public int Length; - public IntPtr RootDirectory; - public IntPtr ObjectName; - public int Attributes; - public IntPtr SecurityDescriptor; - public IntPtr SecurityQualityOfService; - } - - public LsaHandle(DesiredAccess desiredAccess) - { - LSA_OBJECT_ATTRIBUTES lsaAttr; - lsaAttr.RootDirectory = IntPtr.Zero; - lsaAttr.ObjectName = IntPtr.Zero; - lsaAttr.Attributes = 0; - lsaAttr.SecurityDescriptor = IntPtr.Zero; - lsaAttr.SecurityQualityOfService = IntPtr.Zero; - lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES)); - LSA_UNICODE_STRING[] system = new LSA_UNICODE_STRING[1]; - system[0].buffer = IntPtr.Zero; - - uint res = LsaOpenPolicy(system, ref lsaAttr, desiredAccess, out handle); - if (res != 0) - throw new Win32Exception(LsaNtStatusToWinError(res), "LsaOpenPolicy() failed"); - } - - public void Dispose() - { - if (handle != IntPtr.Zero) - { - LsaClose(handle); - handle = IntPtr.Zero; - } - GC.SuppressFinalize(this); - } - - ~LsaHandle() { Dispose(); } - } - - public class Sid - { - public string SidString { get; internal set; } - public string DomainName { get; internal set; } - public string AccountName { get; internal set; } - public SID_NAME_USE SidType { get; internal set; } - - public enum SID_NAME_USE - { - SidTypeUser = 1, - SidTypeGroup, - SidTypeDomain, - SidTypeAlias, - SidTypeWellKnownGroup, - SidTypeDeletedAccount, - SidTypeInvalid, - SidTypeUnknown, - SidTypeComputer, - SidTypeLabel, - SidTypeLogon, - } - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool LookupAccountSid( - string lpSystemName, - [MarshalAs(UnmanagedType.LPArray)] - byte[] Sid, - StringBuilder lpName, - ref UInt32 cchName, - StringBuilder ReferencedDomainName, - ref UInt32 cchReferencedDomainName, - out SID_NAME_USE peUse); - - public Sid(IntPtr sidPtr) - { - SecurityIdentifier sid; - try - { - sid = new SecurityIdentifier(sidPtr); - } - catch (Exception e) - { - throw new ArgumentException(String.Format("Failed to cast IntPtr to SecurityIdentifier: {0}", e)); - } - - SetSidInfo(sid); - } - - public Sid(SecurityIdentifier sid) - { - SetSidInfo(sid); - } - - public override string ToString() - { - return SidString; - } - - private void SetSidInfo(SecurityIdentifier sid) - { - byte[] sidBytes = new byte[sid.BinaryLength]; - sid.GetBinaryForm(sidBytes, 0); - - StringBuilder lpName = new StringBuilder(); - UInt32 cchName = 0; - StringBuilder referencedDomainName = new StringBuilder(); - UInt32 cchReferencedDomainName = 0; - SID_NAME_USE peUse; - LookupAccountSid(null, sidBytes, lpName, ref cchName, referencedDomainName, ref cchReferencedDomainName, out peUse); - - lpName.EnsureCapacity((int)cchName); - referencedDomainName.EnsureCapacity((int)cchReferencedDomainName); - - SidString = sid.ToString(); - if (!LookupAccountSid(null, sidBytes, lpName, ref cchName, referencedDomainName, ref cchReferencedDomainName, out peUse)) - { - int lastError = Marshal.GetLastWin32Error(); - - if (lastError != 1332 && lastError != 1789) // Fails to lookup Logon Sid - { - throw new Win32Exception(lastError, String.Format("LookupAccountSid() failed for SID: {0} {1}", sid.ToString(), lastError)); - } - else if (SidString.StartsWith("S-1-5-5-")) - { - AccountName = String.Format("LogonSessionId_{0}", SidString.Substring(8)); - DomainName = "NT AUTHORITY"; - SidType = SID_NAME_USE.SidTypeLogon; - } - else - { - AccountName = null; - DomainName = null; - SidType = SID_NAME_USE.SidTypeUnknown; - } - } - else - { - AccountName = lpName.ToString(); - DomainName = referencedDomainName.ToString(); - SidType = peUse; - } - } - } - - public class SessionUtil - { - [DllImport("secur32.dll", SetLastError = false)] - private static extern uint LsaFreeReturnBuffer( - IntPtr Buffer); - - [DllImport("secur32.dll", SetLastError = false)] - private static extern uint LsaEnumerateLogonSessions( - out UInt64 LogonSessionCount, - out IntPtr LogonSessionList); - - [DllImport("secur32.dll", SetLastError = false)] - private static extern uint LsaGetLogonSessionData( - IntPtr LogonId, - out IntPtr ppLogonSessionData); - - [DllImport("advapi32.dll", SetLastError = false)] - private static extern int LsaNtStatusToWinError( - uint Status); - - [DllImport("advapi32", SetLastError = true)] - private static extern uint LsaEnumerateAccountRights( - IntPtr PolicyHandle, - IntPtr AccountSid, - out IntPtr UserRights, - out UInt64 CountOfRights); - - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool LookupPrivilegeName( - string lpSystemName, - ref LUID lpLuid, - StringBuilder lpName, - ref UInt32 cchName); - - private const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001; - private const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002; - private const UInt32 STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034; - private const UInt32 STATUS_ACCESS_DENIED = 0xC0000022; - - public static SessionInfo GetSessionInfo() - { - AccessToken accessToken = new AccessToken(TokenAccessLevels.Query); - - // Get Privileges - Hashtable privilegeInfo = new Hashtable(); - TOKEN_PRIVILEGES privileges; - IntPtr privilegesPtr = accessToken.GetTokenInformation(out privileges, AccessToken.TOKEN_INFORMATION_CLASS.TokenPrivileges); - LUID_AND_ATTRIBUTES[] luidAndAttributes = new LUID_AND_ATTRIBUTES[privileges.PrivilegeCount]; - try - { - PtrToStructureArray(luidAndAttributes, privilegesPtr.ToInt64() + Marshal.SizeOf(privileges.PrivilegeCount)); - } - finally - { - Marshal.FreeHGlobal(privilegesPtr); - } - foreach (LUID_AND_ATTRIBUTES luidAndAttribute in luidAndAttributes) - { - LUID privLuid = luidAndAttribute.Luid; - UInt32 privNameLen = 0; - StringBuilder privName = new StringBuilder(); - LookupPrivilegeName(null, ref privLuid, null, ref privNameLen); - privName.EnsureCapacity((int)(privNameLen + 1)); - if (!LookupPrivilegeName(null, ref privLuid, privName, ref privNameLen)) - throw new Win32Exception("LookupPrivilegeName() failed"); - - string state = "disabled"; - if ((luidAndAttribute.Attributes & SE_PRIVILEGE_ENABLED) == SE_PRIVILEGE_ENABLED) - state = "enabled"; - if ((luidAndAttribute.Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT) == SE_PRIVILEGE_ENABLED_BY_DEFAULT) - state = "enabled-by-default"; - privilegeInfo.Add(privName.ToString(), state); - } - - // Get Current Process LogonSID, User Rights and Groups - ArrayList userRights = new ArrayList(); - ArrayList userGroups = new ArrayList(); - TOKEN_GROUPS groups; - IntPtr groupsPtr = accessToken.GetTokenInformation(out groups, AccessToken.TOKEN_INFORMATION_CLASS.TokenGroups); - SID_AND_ATTRIBUTES[] sidAndAttributes = new SID_AND_ATTRIBUTES[groups.GroupCount]; - LsaHandle lsaHandle = null; - // We can only get rights if we are an admin - if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)) - lsaHandle = new LsaHandle(LsaHandle.DesiredAccess.POLICY_LOOKUP_NAMES); - try - { - PtrToStructureArray(sidAndAttributes, groupsPtr.ToInt64() + IntPtr.Size); - foreach (SID_AND_ATTRIBUTES sidAndAttribute in sidAndAttributes) - { - TokenGroupAttributes attributes = (TokenGroupAttributes)sidAndAttribute.Attributes; - if (attributes.HasFlag(TokenGroupAttributes.SE_GROUP_ENABLED) && lsaHandle != null) - { - ArrayList rights = GetAccountRights(lsaHandle.handle, sidAndAttribute.Sid); - foreach (string right in rights) - { - // Includes both Privileges and Account Rights, only add the ones with Logon in the name - // https://msdn.microsoft.com/en-us/library/windows/desktop/bb545671(v=vs.85).aspx - if (!userRights.Contains(right) && right.Contains("Logon")) - userRights.Add(right); - } - } - // Do not include the Logon SID in the groups category - if (!attributes.HasFlag(TokenGroupAttributes.SE_GROUP_LOGON_ID)) - { - Hashtable groupInfo = new Hashtable(); - Sid group = new Sid(sidAndAttribute.Sid); - ArrayList groupAttributes = new ArrayList(); - foreach (TokenGroupAttributes attribute in Enum.GetValues(typeof(TokenGroupAttributes))) - { - if (attributes.HasFlag(attribute)) - { - string attributeName = attribute.ToString().Substring(9); - attributeName = attributeName.Replace('_', ' '); - attributeName = attributeName.First().ToString().ToUpper() + attributeName.Substring(1).ToLower(); - groupAttributes.Add(attributeName); - } - } - // Using snake_case here as I can't generically convert all dict keys in PS (see Privileges) - groupInfo.Add("sid", group.SidString); - groupInfo.Add("domain_name", group.DomainName); - groupInfo.Add("account_name", group.AccountName); - groupInfo.Add("type", group.SidType); - groupInfo.Add("attributes", groupAttributes); - userGroups.Add(groupInfo); - } - } - } - finally - { - Marshal.FreeHGlobal(groupsPtr); - if (lsaHandle != null) - lsaHandle.Dispose(); - } - - // Get Integrity Level - Sid integritySid = null; - TOKEN_MANDATORY_LABEL mandatoryLabel; - IntPtr mandatoryLabelPtr = accessToken.GetTokenInformation(out mandatoryLabel, AccessToken.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel); - Marshal.FreeHGlobal(mandatoryLabelPtr); - integritySid = new Sid(mandatoryLabel.Label.Sid); - - // Get Token Statistics - TOKEN_STATISTICS tokenStats; - IntPtr tokenStatsPtr = accessToken.GetTokenInformation(out tokenStats, AccessToken.TOKEN_INFORMATION_CLASS.TokenStatistics); - Marshal.FreeHGlobal(tokenStatsPtr); - - SessionInfo sessionInfo = GetSessionDataForLogonSession(tokenStats.AuthenticationId); - sessionInfo.Groups = userGroups; - sessionInfo.Label = integritySid; - sessionInfo.ImpersonationLevel = tokenStats.ImpersonationLevel; - sessionInfo.TokenType = tokenStats.TokenType; - sessionInfo.Privileges = privilegeInfo; - sessionInfo.Rights = userRights; - return sessionInfo; - } - - private static ArrayList GetAccountRights(IntPtr lsaHandle, IntPtr sid) - { - UInt32 res; - ArrayList rights = new ArrayList(); - IntPtr userRightsPointer = IntPtr.Zero; - UInt64 countOfRights = 0; - - res = LsaEnumerateAccountRights(lsaHandle, sid, out userRightsPointer, out countOfRights); - if (res != 0 && res != STATUS_OBJECT_NAME_NOT_FOUND) - throw new Win32Exception(LsaNtStatusToWinError(res), "LsaEnumerateAccountRights() failed"); - else if (res != STATUS_OBJECT_NAME_NOT_FOUND) - { - LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[countOfRights]; - PtrToStructureArray(userRights, userRightsPointer.ToInt64()); - rights = new ArrayList(); - foreach (LSA_UNICODE_STRING right in userRights) - rights.Add(Marshal.PtrToStringUni(right.buffer)); - } - - return rights; - } - - private static SessionInfo GetSessionDataForLogonSession(LUID logonSession) - { - uint res; - UInt64 count = 0; - IntPtr luidPtr = IntPtr.Zero; - SessionInfo sessionInfo = null; - UInt64 processDataId = ConvertLuidToUint(logonSession); - - res = LsaEnumerateLogonSessions(out count, out luidPtr); - if (res != 0) - throw new Win32Exception(LsaNtStatusToWinError(res), "LsaEnumerateLogonSessions() failed"); - Int64 luidAddr = luidPtr.ToInt64(); - - try - { - for (UInt64 i = 0; i < count; i++) - { - IntPtr dataPointer = IntPtr.Zero; - res = LsaGetLogonSessionData(luidPtr, out dataPointer); - if (res == STATUS_ACCESS_DENIED) // Non admins won't be able to get info for session's that are not their own - { - luidPtr = new IntPtr(luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID))); - continue; - } - else if (res != 0) - throw new Win32Exception(LsaNtStatusToWinError(res), String.Format("LsaGetLogonSessionData() failed {0}", res)); - - SECURITY_LOGON_SESSION_DATA sessionData = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(dataPointer, typeof(SECURITY_LOGON_SESSION_DATA)); - UInt64 sessionDataid = ConvertLuidToUint(sessionData.LogonId); - - if (sessionDataid == processDataId) - { - ArrayList userFlags = new ArrayList(); - UserFlags flags = (UserFlags)sessionData.UserFlags; - foreach (UserFlags flag in Enum.GetValues(typeof(UserFlags))) - { - if (flags.HasFlag(flag)) - { - string flagName = flag.ToString().Substring(6); - flagName = flagName.Replace('_', ' '); - flagName = flagName.First().ToString().ToUpper() + flagName.Substring(1).ToLower(); - userFlags.Add(flagName); - } - } - - sessionInfo = new SessionInfo() - { - AuthenticationPackage = Marshal.PtrToStringUni(sessionData.AuthenticationPackage.buffer), - DnsDomainName = Marshal.PtrToStringUni(sessionData.DnsDomainName.buffer), - LoginDomain = Marshal.PtrToStringUni(sessionData.LoginDomain.buffer), - LoginTime = ConvertIntegerToDateString(sessionData.LoginTime), - LogonId = ConvertLuidToUint(sessionData.LogonId), - LogonServer = Marshal.PtrToStringUni(sessionData.LogonServer.buffer), - LogonType = sessionData.LogonType, - Upn = Marshal.PtrToStringUni(sessionData.Upn.buffer), - UserFlags = userFlags, - Account = new Sid(sessionData.Sid) - }; - break; - } - luidPtr = new IntPtr(luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID))); - } - } - finally - { - LsaFreeReturnBuffer(new IntPtr(luidAddr)); - } - - if (sessionInfo == null) - throw new Exception(String.Format("Could not find the data for logon session {0}", processDataId)); - return sessionInfo; - } - - private static string ConvertIntegerToDateString(UInt64 time) - { - if (time == 0) - return null; - if (time > (UInt64)DateTime.MaxValue.ToFileTime()) - return null; - - DateTime dateTime = DateTime.FromFileTime((long)time); - return dateTime.ToString("o"); - } - - private static UInt64 ConvertLuidToUint(LUID luid) - { - UInt32 low = luid.LowPart; - UInt64 high = (UInt64)luid.HighPart; - high = high << 32; - UInt64 uintValue = (high | (UInt64)low); - return uintValue; - } - - private static void PtrToStructureArray<T>(T[] array, Int64 pointerAddress) - { - Int64 pointerOffset = pointerAddress; - for (int i = 0; i < array.Length; i++, pointerOffset += Marshal.SizeOf(typeof(T))) - array[i] = (T)Marshal.PtrToStructure(new IntPtr(pointerOffset), typeof(T)); - } - - public static IEnumerable<T> GetValues<T>() - { - return Enum.GetValues(typeof(T)).Cast<T>(); - } - } -} -'@ - -$original_tmp = $env:TMP -$env:TMP = $_remote_tmp -Add-Type -TypeDefinition $session_util -$env:TMP = $original_tmp - -$session_info = [Ansible.SessionUtil]::GetSessionInfo() - -Function Convert-Value($value) { - $new_value = $value - if ($value -is [System.Collections.ArrayList]) { - $new_value = [System.Collections.ArrayList]@() - foreach ($list_value in $value) { - $new_list_value = Convert-Value -value $list_value - [void]$new_value.Add($new_list_value) - } - } elseif ($value -is [Hashtable]) { - $new_value = @{} - foreach ($entry in $value.GetEnumerator()) { - $entry_value = Convert-Value -value $entry.Value - # manually convert Sid type entry to remove the SidType prefix - if ($entry.Name -eq "type") { - $entry_value = $entry_value.Replace("SidType", "") - } - $new_value[$entry.Name] = $entry_value - } - } elseif ($value -is [Ansible.Sid]) { - $new_value = @{ - sid = $value.SidString - account_name = $value.AccountName - domain_name = $value.DomainName - type = $value.SidType.ToString().Replace("SidType", "") - } - } elseif ($value -is [Enum]) { - $new_value = $value.ToString() - } - - return ,$new_value -} - -$result = @{ - changed = $false -} - -$properties = [type][Ansible.SessionInfo] -foreach ($property in $properties.DeclaredProperties) { - $property_name = $property.Name - $property_value = $session_info.$property_name - $snake_name = Convert-StringToSnakeCase -string $property_name - - $result.$snake_name = Convert-Value -value $property_value -} - -Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_whoami.py b/lib/ansible/modules/windows/win_whoami.py deleted file mode 100644 index d647374b6c..0000000000 --- a/lib/ansible/modules/windows/win_whoami.py +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: win_whoami -version_added: "2.5" -short_description: Get information about the current user and process -description: -- Designed to return the same information as the C(whoami /all) command. -- Also includes information missing from C(whoami) such as logon metadata like - logon rights, id, type. -notes: -- If running this module with a non admin user, the logon rights will be an - empty list as Administrator rights are required to query LSA for the - information. -seealso: -- module: win_credential -- module: win_group_membership -- module: win_user_right -author: -- Jordan Borean (@jborean93) -''' - -EXAMPLES = r''' -- name: Get whoami information - win_whoami: -''' - -RETURN = r''' -authentication_package: - description: The name of the authentication package used to authenticate the - user in the session. - returned: success - type: str - sample: Negotiate -user_flags: - description: The user flags for the logon session, see UserFlags in - U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa380128). - returned: success - type: str - sample: Winlogon -upn: - description: The user principal name of the current user. - returned: success - type: str - sample: Administrator@DOMAIN.COM -logon_type: - description: The logon type that identifies the logon method, see - U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa380129.aspx). - returned: success - type: str - sample: Network -privileges: - description: A dictionary of privileges and their state on the logon token. - returned: success - type: dict - sample: { - "SeChangeNotifyPrivileges": "enabled-by-default", - "SeRemoteShutdownPrivilege": "disabled", - "SeDebugPrivilege": "enabled" - } -label: - description: The mandatory label set to the logon session. - returned: success - type: complex - contains: - domain_name: - description: The domain name of the label SID. - returned: success - type: str - sample: Mandatory Label - sid: - description: The SID in string form. - returned: success - type: str - sample: S-1-16-12288 - account_name: - description: The account name of the label SID. - returned: success - type: str - sample: High Mandatory Level - type: - description: The type of SID. - returned: success - type: str - sample: Label -impersonation_level: - description: The impersonation level of the token, only valid if - C(token_type) is C(TokenImpersonation), see - U(https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx). - returned: success - type: str - sample: SecurityAnonymous -login_time: - description: The logon time in ISO 8601 format - returned: success - type: str - sample: '2017-11-27T06:24:14.3321665+10:00' -groups: - description: A list of groups and attributes that the user is a member of. - returned: success - type: list - sample: [ - { - "account_name": "Domain Users", - "domain_name": "DOMAIN", - "attributes": [ - "Mandatory", - "Enabled by default", - "Enabled" - ], - "sid": "S-1-5-21-1654078763-769949647-2968445802-513", - "type": "Group" - }, - { - "account_name": "Administrators", - "domain_name": "BUILTIN", - "attributes": [ - "Mandatory", - "Enabled by default", - "Enabled", - "Owner" - ], - "sid": "S-1-5-32-544", - "type": "Alias" - } - ] -account: - description: The running account SID details. - returned: success - type: complex - contains: - domain_name: - description: The domain name of the account SID. - returned: success - type: str - sample: DOMAIN - sid: - description: The SID in string form. - returned: success - type: str - sample: S-1-5-21-1654078763-769949647-2968445802-500 - account_name: - description: The account name of the account SID. - returned: success - type: str - sample: Administrator - type: - description: The type of SID. - returned: success - type: str - sample: User -login_domain: - description: The name of the domain used to authenticate the owner of the - session. - returned: success - type: str - sample: DOMAIN -rights: - description: A list of logon rights assigned to the logon. - returned: success and running user is a member of the local Administrators group - type: list - sample: [ - "SeNetworkLogonRight", - "SeInteractiveLogonRight", - "SeBatchLogonRight", - "SeRemoteInteractiveLogonRight" - ] -logon_server: - description: The name of the server used to authenticate the owner of the - logon session. - returned: success - type: str - sample: DC01 -logon_id: - description: The unique identifier of the logon session. - returned: success - type: int - sample: 20470143 -dns_domain_name: - description: The DNS name of the logon session, this is an empty string if - this is not set. - returned: success - type: str - sample: DOMAIN.COM -token_type: - description: The token type to indicate whether it is a primary or - impersonation token. - returned: success - type: str - sample: TokenPrimary -''' diff --git a/lib/ansible/plugins/action/win_copy.py b/lib/ansible/plugins/action/win_copy.py deleted file mode 100644 index adb918be29..0000000000 --- a/lib/ansible/plugins/action/win_copy.py +++ /dev/null @@ -1,522 +0,0 @@ -# This file is part of Ansible - -# Copyright (c) 2017 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import base64 -import json -import os -import os.path -import shutil -import tempfile -import traceback -import zipfile - -from ansible import constants as C -from ansible.errors import AnsibleError, AnsibleFileNotFound -from ansible.module_utils._text import to_bytes, to_native, to_text -from ansible.module_utils.parsing.convert_bool import boolean -from ansible.plugins.action import ActionBase -from ansible.utils.hashing import checksum - - -def _walk_dirs(topdir, loader, decrypt=True, base_path=None, local_follow=False, trailing_slash_detector=None, checksum_check=False): - """ - Walk a filesystem tree returning enough information to copy the files. - This is similar to the _walk_dirs function in ``copy.py`` but returns - a dict instead of a tuple for each entry and includes the checksum of - a local file if wanted. - - :arg topdir: The directory that the filesystem tree is rooted at - :arg loader: The self._loader object from ActionBase - :kwarg decrypt: Whether to decrypt a file encrypted with ansible-vault - :kwarg base_path: The initial directory structure to strip off of the - files for the destination directory. If this is None (the default), - the base_path is set to ``top_dir``. - :kwarg local_follow: Whether to follow symlinks on the source. When set - to False, no symlinks are dereferenced. When set to True (the - default), the code will dereference most symlinks. However, symlinks - can still be present if needed to break a circular link. - :kwarg trailing_slash_detector: Function to determine if a path has - a trailing directory separator. Only needed when dealing with paths on - a remote machine (in which case, pass in a function that is aware of the - directory separator conventions on the remote machine). - :kawrg whether to get the checksum of the local file and add to the dict - :returns: dictionary of dictionaries. All of the path elements in the structure are text string. - This separates all the files, directories, and symlinks along with - import information about each:: - - { - 'files'; [{ - src: '/absolute/path/to/copy/from', - dest: 'relative/path/to/copy/to', - checksum: 'b54ba7f5621240d403f06815f7246006ef8c7d43' - }, ...], - 'directories'; [{ - src: '/absolute/path/to/copy/from', - dest: 'relative/path/to/copy/to' - }, ...], - 'symlinks'; [{ - src: '/symlink/target/path', - dest: 'relative/path/to/copy/to' - }, ...], - - } - - The ``symlinks`` field is only populated if ``local_follow`` is set to False - *or* a circular symlink cannot be dereferenced. The ``checksum`` entry is set - to None if checksum_check=False. - - """ - # Convert the path segments into byte strings - - r_files = {'files': [], 'directories': [], 'symlinks': []} - - def _recurse(topdir, rel_offset, parent_dirs, rel_base=u'', checksum_check=False): - """ - This is a closure (function utilizing variables from it's parent - function's scope) so that we only need one copy of all the containers. - Note that this function uses side effects (See the Variables used from - outer scope). - - :arg topdir: The directory we are walking for files - :arg rel_offset: Integer defining how many characters to strip off of - the beginning of a path - :arg parent_dirs: Directories that we're copying that this directory is in. - :kwarg rel_base: String to prepend to the path after ``rel_offset`` is - applied to form the relative path. - - Variables used from the outer scope - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :r_files: Dictionary of files in the hierarchy. See the return value - for :func:`walk` for the structure of this dictionary. - :local_follow: Read-only inside of :func:`_recurse`. Whether to follow symlinks - """ - for base_path, sub_folders, files in os.walk(topdir): - for filename in files: - filepath = os.path.join(base_path, filename) - dest_filepath = os.path.join(rel_base, filepath[rel_offset:]) - - if os.path.islink(filepath): - # Dereference the symlnk - real_file = loader.get_real_file(os.path.realpath(filepath), decrypt=decrypt) - if local_follow and os.path.isfile(real_file): - # Add the file pointed to by the symlink - r_files['files'].append( - { - "src": real_file, - "dest": dest_filepath, - "checksum": _get_local_checksum(checksum_check, real_file) - } - ) - else: - # Mark this file as a symlink to copy - r_files['symlinks'].append({"src": os.readlink(filepath), "dest": dest_filepath}) - else: - # Just a normal file - real_file = loader.get_real_file(filepath, decrypt=decrypt) - r_files['files'].append( - { - "src": real_file, - "dest": dest_filepath, - "checksum": _get_local_checksum(checksum_check, real_file) - } - ) - - for dirname in sub_folders: - dirpath = os.path.join(base_path, dirname) - dest_dirpath = os.path.join(rel_base, dirpath[rel_offset:]) - real_dir = os.path.realpath(dirpath) - dir_stats = os.stat(real_dir) - - if os.path.islink(dirpath): - if local_follow: - if (dir_stats.st_dev, dir_stats.st_ino) in parent_dirs: - # Just insert the symlink if the target directory - # exists inside of the copy already - r_files['symlinks'].append({"src": os.readlink(dirpath), "dest": dest_dirpath}) - else: - # Walk the dirpath to find all parent directories. - new_parents = set() - parent_dir_list = os.path.dirname(dirpath).split(os.path.sep) - for parent in range(len(parent_dir_list), 0, -1): - parent_stat = os.stat(u'/'.join(parent_dir_list[:parent])) - if (parent_stat.st_dev, parent_stat.st_ino) in parent_dirs: - # Reached the point at which the directory - # tree is already known. Don't add any - # more or we might go to an ancestor that - # isn't being copied. - break - new_parents.add((parent_stat.st_dev, parent_stat.st_ino)) - - if (dir_stats.st_dev, dir_stats.st_ino) in new_parents: - # This was a a circular symlink. So add it as - # a symlink - r_files['symlinks'].append({"src": os.readlink(dirpath), "dest": dest_dirpath}) - else: - # Walk the directory pointed to by the symlink - r_files['directories'].append({"src": real_dir, "dest": dest_dirpath}) - offset = len(real_dir) + 1 - _recurse(real_dir, offset, parent_dirs.union(new_parents), - rel_base=dest_dirpath, - checksum_check=checksum_check) - else: - # Add the symlink to the destination - r_files['symlinks'].append({"src": os.readlink(dirpath), "dest": dest_dirpath}) - else: - # Just a normal directory - r_files['directories'].append({"src": dirpath, "dest": dest_dirpath}) - - # Check if the source ends with a "/" so that we know which directory - # level to work at (similar to rsync) - source_trailing_slash = False - if trailing_slash_detector: - source_trailing_slash = trailing_slash_detector(topdir) - else: - source_trailing_slash = topdir.endswith(os.path.sep) - - # Calculate the offset needed to strip the base_path to make relative - # paths - if base_path is None: - base_path = topdir - if not source_trailing_slash: - base_path = os.path.dirname(base_path) - if topdir.startswith(base_path): - offset = len(base_path) - - # Make sure we're making the new paths relative - if trailing_slash_detector and not trailing_slash_detector(base_path): - offset += 1 - elif not base_path.endswith(os.path.sep): - offset += 1 - - if os.path.islink(topdir) and not local_follow: - r_files['symlinks'] = {"src": os.readlink(topdir), "dest": os.path.basename(topdir)} - return r_files - - dir_stats = os.stat(topdir) - parents = frozenset(((dir_stats.st_dev, dir_stats.st_ino),)) - # Actually walk the directory hierarchy - _recurse(topdir, offset, parents, checksum_check=checksum_check) - - return r_files - - -def _get_local_checksum(get_checksum, local_path): - if get_checksum: - return checksum(local_path) - else: - return None - - -class ActionModule(ActionBase): - - WIN_PATH_SEPARATOR = "\\" - - def _create_content_tempfile(self, content): - ''' Create a tempfile containing defined content ''' - fd, content_tempfile = tempfile.mkstemp(dir=C.DEFAULT_LOCAL_TMP) - f = os.fdopen(fd, 'wb') - content = to_bytes(content) - try: - f.write(content) - except Exception as err: - os.remove(content_tempfile) - raise Exception(err) - finally: - f.close() - return content_tempfile - - def _create_zip_tempfile(self, files, directories): - tmpdir = tempfile.mkdtemp(dir=C.DEFAULT_LOCAL_TMP) - zip_file_path = os.path.join(tmpdir, "win_copy.zip") - zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_STORED, True) - - # encoding the file/dir name with base64 so Windows can unzip a unicode - # filename and get the right name, Windows doesn't handle unicode names - # very well - for directory in directories: - directory_path = to_bytes(directory['src'], errors='surrogate_or_strict') - archive_path = to_bytes(directory['dest'], errors='surrogate_or_strict') - - encoded_path = to_text(base64.b64encode(archive_path), errors='surrogate_or_strict') - zip_file.write(directory_path, encoded_path, zipfile.ZIP_DEFLATED) - - for file in files: - file_path = to_bytes(file['src'], errors='surrogate_or_strict') - archive_path = to_bytes(file['dest'], errors='surrogate_or_strict') - - encoded_path = to_text(base64.b64encode(archive_path), errors='surrogate_or_strict') - zip_file.write(file_path, encoded_path, zipfile.ZIP_DEFLATED) - - return zip_file_path - - def _remove_tempfile_if_content_defined(self, content, content_tempfile): - if content is not None: - os.remove(content_tempfile) - - def _copy_single_file(self, local_file, dest, source_rel, task_vars, tmp, backup): - if self._play_context.check_mode: - module_return = dict(changed=True) - return module_return - - # copy the file across to the server - tmp_src = self._connection._shell.join_path(tmp, 'source') - self._transfer_file(local_file, tmp_src) - - copy_args = self._task.args.copy() - copy_args.update( - dict( - dest=dest, - src=tmp_src, - _original_basename=source_rel, - _copy_mode="single", - backup=backup, - ) - ) - copy_args.pop('content', None) - - copy_result = self._execute_module(module_name="copy", - module_args=copy_args, - task_vars=task_vars) - - return copy_result - - def _copy_zip_file(self, dest, files, directories, task_vars, tmp, backup): - # create local zip file containing all the files and directories that - # need to be copied to the server - if self._play_context.check_mode: - module_return = dict(changed=True) - return module_return - - try: - zip_file = self._create_zip_tempfile(files, directories) - except Exception as e: - module_return = dict( - changed=False, - failed=True, - msg="failed to create tmp zip file: %s" % to_text(e), - exception=traceback.format_exc() - ) - return module_return - - zip_path = self._loader.get_real_file(zip_file) - - # send zip file to remote, file must end in .zip so - # Com Shell.Application works - tmp_src = self._connection._shell.join_path(tmp, 'source.zip') - self._transfer_file(zip_path, tmp_src) - - # run the explode operation of win_copy on remote - copy_args = self._task.args.copy() - copy_args.update( - dict( - src=tmp_src, - dest=dest, - _copy_mode="explode", - backup=backup, - ) - ) - copy_args.pop('content', None) - module_return = self._execute_module(module_name='copy', - module_args=copy_args, - task_vars=task_vars) - shutil.rmtree(os.path.dirname(zip_path)) - return module_return - - def run(self, tmp=None, task_vars=None): - ''' handler for file transfer operations ''' - if task_vars is None: - task_vars = dict() - - result = super(ActionModule, self).run(tmp, task_vars) - del tmp # tmp no longer has any effect - - source = self._task.args.get('src', None) - content = self._task.args.get('content', None) - dest = self._task.args.get('dest', None) - remote_src = boolean(self._task.args.get('remote_src', False), strict=False) - local_follow = boolean(self._task.args.get('local_follow', False), strict=False) - force = boolean(self._task.args.get('force', True), strict=False) - decrypt = boolean(self._task.args.get('decrypt', True), strict=False) - backup = boolean(self._task.args.get('backup', False), strict=False) - - result['src'] = source - result['dest'] = dest - - result['failed'] = True - if (source is None and content is None) or dest is None: - result['msg'] = "src (or content) and dest are required" - elif source is not None and content is not None: - result['msg'] = "src and content are mutually exclusive" - elif content is not None and dest is not None and ( - dest.endswith(os.path.sep) or dest.endswith(self.WIN_PATH_SEPARATOR)): - result['msg'] = "dest must be a file if content is defined" - else: - del result['failed'] - - if result.get('failed'): - return result - - # If content is defined make a temp file and write the content into it - content_tempfile = None - if content is not None: - try: - # if content comes to us as a dict it should be decoded json. - # We need to encode it back into a string and write it out - if isinstance(content, dict) or isinstance(content, list): - content_tempfile = self._create_content_tempfile(json.dumps(content)) - else: - content_tempfile = self._create_content_tempfile(content) - source = content_tempfile - except Exception as err: - result['failed'] = True - result['msg'] = "could not write content tmp file: %s" % to_native(err) - return result - # all actions should occur on the remote server, run win_copy module - elif remote_src: - new_module_args = self._task.args.copy() - new_module_args.update( - dict( - _copy_mode="remote", - dest=dest, - src=source, - force=force, - backup=backup, - ) - ) - new_module_args.pop('content', None) - result.update(self._execute_module(module_args=new_module_args, task_vars=task_vars)) - return result - # find_needle returns a path that may not have a trailing slash on a - # directory so we need to find that out first and append at the end - else: - trailing_slash = source.endswith(os.path.sep) - try: - # find in expected paths - source = self._find_needle('files', source) - except AnsibleError as e: - result['failed'] = True - result['msg'] = to_text(e) - result['exception'] = traceback.format_exc() - return result - - if trailing_slash != source.endswith(os.path.sep): - if source[-1] == os.path.sep: - source = source[:-1] - else: - source = source + os.path.sep - - # A list of source file tuples (full_path, relative_path) which will try to copy to the destination - source_files = {'files': [], 'directories': [], 'symlinks': []} - - # If source is a directory populate our list else source is a file and translate it to a tuple. - if os.path.isdir(to_bytes(source, errors='surrogate_or_strict')): - result['operation'] = 'folder_copy' - - # Get a list of the files we want to replicate on the remote side - source_files = _walk_dirs(source, self._loader, decrypt=decrypt, local_follow=local_follow, - trailing_slash_detector=self._connection._shell.path_has_trailing_slash, - checksum_check=force) - - # If it's recursive copy, destination is always a dir, - # explicitly mark it so (note - win_copy module relies on this). - if not self._connection._shell.path_has_trailing_slash(dest): - dest = "%s%s" % (dest, self.WIN_PATH_SEPARATOR) - - check_dest = dest - # Source is a file, add details to source_files dict - else: - result['operation'] = 'file_copy' - - # If the local file does not exist, get_real_file() raises AnsibleFileNotFound - try: - source_full = self._loader.get_real_file(source, decrypt=decrypt) - except AnsibleFileNotFound as e: - result['failed'] = True - result['msg'] = "could not find src=%s, %s" % (source_full, to_text(e)) - return result - - original_basename = os.path.basename(source) - result['original_basename'] = original_basename - - # check if dest ends with / or \ and append source filename to dest - if self._connection._shell.path_has_trailing_slash(dest): - check_dest = dest - filename = original_basename - result['dest'] = self._connection._shell.join_path(dest, filename) - else: - # replace \\ with / so we can use os.path to get the filename or dirname - unix_path = dest.replace(self.WIN_PATH_SEPARATOR, os.path.sep) - filename = os.path.basename(unix_path) - check_dest = os.path.dirname(unix_path) - - file_checksum = _get_local_checksum(force, source_full) - source_files['files'].append( - dict( - src=source_full, - dest=filename, - checksum=file_checksum - ) - ) - result['checksum'] = file_checksum - result['size'] = os.path.getsize(to_bytes(source_full, errors='surrogate_or_strict')) - - # find out the files/directories/symlinks that we need to copy to the server - query_args = self._task.args.copy() - query_args.update( - dict( - _copy_mode="query", - dest=check_dest, - force=force, - files=source_files['files'], - directories=source_files['directories'], - symlinks=source_files['symlinks'], - ) - ) - # src is not required for query, will fail path validation is src has unix allowed chars - query_args.pop('src', None) - - query_args.pop('content', None) - query_return = self._execute_module(module_args=query_args, - task_vars=task_vars) - - if query_return.get('failed') is True: - result.update(query_return) - return result - - if len(query_return['files']) > 0 or len(query_return['directories']) > 0 and self._connection._shell.tmpdir is None: - self._connection._shell.tmpdir = self._make_tmp_path() - - if len(query_return['files']) == 1 and len(query_return['directories']) == 0: - # we only need to copy 1 file, don't mess around with zips - file_src = query_return['files'][0]['src'] - file_dest = query_return['files'][0]['dest'] - result.update(self._copy_single_file(file_src, dest, file_dest, - task_vars, self._connection._shell.tmpdir, backup)) - if result.get('failed') is True: - result['msg'] = "failed to copy file %s: %s" % (file_src, result['msg']) - result['changed'] = True - - elif len(query_return['files']) > 0 or len(query_return['directories']) > 0: - # either multiple files or directories need to be copied, compress - # to a zip and 'explode' the zip on the server - # TODO: handle symlinks - result.update(self._copy_zip_file(dest, source_files['files'], - source_files['directories'], - task_vars, self._connection._shell.tmpdir, backup)) - result['changed'] = True - else: - # no operations need to occur - result['failed'] = False - result['changed'] = False - - # remove the content tmp file and remote tmp file if it was created - self._remove_tempfile_if_content_defined(content, content_tempfile) - self._remove_tmp_path(self._connection._shell.tmpdir) - return result diff --git a/lib/ansible/plugins/action/win_reboot.py b/lib/ansible/plugins/action/win_reboot.py deleted file mode 100644 index c408f4f30e..0000000000 --- a/lib/ansible/plugins/action/win_reboot.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright: (c) 2018, Matt Davis <mdavis@ansible.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from datetime import datetime - -from ansible.errors import AnsibleError -from ansible.module_utils._text import to_native -from ansible.plugins.action import ActionBase -from ansible.plugins.action.reboot import ActionModule as RebootActionModule -from ansible.utils.display import Display - -display = Display() - - -class TimedOutException(Exception): - pass - - -class ActionModule(RebootActionModule, ActionBase): - TRANSFERS_FILES = False - _VALID_ARGS = frozenset(( - 'connect_timeout', 'connect_timeout_sec', 'msg', 'post_reboot_delay', 'post_reboot_delay_sec', 'pre_reboot_delay', 'pre_reboot_delay_sec', - 'reboot_timeout', 'reboot_timeout_sec', 'shutdown_timeout', 'shutdown_timeout_sec', 'test_command', - )) - - DEFAULT_BOOT_TIME_COMMAND = "(Get-WmiObject -ClassName Win32_OperatingSystem).LastBootUpTime" - DEFAULT_CONNECT_TIMEOUT = 5 - DEFAULT_PRE_REBOOT_DELAY = 2 - DEFAULT_SUDOABLE = False - DEFAULT_SHUTDOWN_COMMAND_ARGS = '/r /t {delay_sec} /c "{message}"' - - DEPRECATED_ARGS = { - 'shutdown_timeout': '2.5', - 'shutdown_timeout_sec': '2.5', - } - - def __init__(self, *args, **kwargs): - super(ActionModule, self).__init__(*args, **kwargs) - - def get_distribution(self, task_vars): - return {'name': 'windows', 'version': '', 'family': ''} - - def get_shutdown_command(self, task_vars, distribution): - return self.DEFAULT_SHUTDOWN_COMMAND - - def run_test_command(self, distribution, **kwargs): - # Need to wrap the test_command in our PowerShell encoded wrapper. This is done to align the command input to a - # common shell and to allow the psrp connection plugin to report the correct exit code without manually setting - # $LASTEXITCODE for just that plugin. - test_command = self._task.args.get('test_command', self.DEFAULT_TEST_COMMAND) - kwargs['test_command'] = self._connection._shell._encode_script(test_command) - super(ActionModule, self).run_test_command(distribution, **kwargs) - - def perform_reboot(self, task_vars, distribution): - shutdown_command = self.get_shutdown_command(task_vars, distribution) - shutdown_command_args = self.get_shutdown_command_args(distribution) - reboot_command = self._connection._shell._encode_script('{0} {1}'.format(shutdown_command, shutdown_command_args)) - - display.vvv("{action}: rebooting server...".format(action=self._task.action)) - display.debug("{action}: distribution: {dist}".format(action=self._task.action, dist=distribution)) - display.debug("{action}: rebooting server with command '{command}'".format(action=self._task.action, command=reboot_command)) - - result = {} - reboot_result = self._low_level_execute_command(reboot_command, sudoable=self.DEFAULT_SUDOABLE) - result['start'] = datetime.utcnow() - - # Test for "A system shutdown has already been scheduled. (1190)" and handle it gracefully - stdout = reboot_result['stdout'] - stderr = reboot_result['stderr'] - if reboot_result['rc'] == 1190 or (reboot_result['rc'] != 0 and "(1190)" in reboot_result['stderr']): - display.warning('A scheduled reboot was pre-empted by Ansible.') - - # Try to abort (this may fail if it was already aborted) - result1 = self._low_level_execute_command(self._connection._shell._encode_script('shutdown /a'), - sudoable=self.DEFAULT_SUDOABLE) - - # Initiate reboot again - result2 = self._low_level_execute_command(reboot_command, sudoable=self.DEFAULT_SUDOABLE) - - reboot_result['rc'] = result2['rc'] - stdout += result1['stdout'] + result2['stdout'] - stderr += result1['stderr'] + result2['stderr'] - - if reboot_result['rc'] != 0: - result['failed'] = True - result['rebooted'] = False - result['msg'] = "Reboot command failed, error was: {stdout} {stderr}".format( - stdout=to_native(stdout.strip()), - stderr=to_native(stderr.strip())) - return result - - result['failed'] = False - return result diff --git a/lib/ansible/plugins/action/win_template.py b/lib/ansible/plugins/action/win_template.py deleted file mode 100644 index 20494b93e7..0000000000 --- a/lib/ansible/plugins/action/win_template.py +++ /dev/null @@ -1,29 +0,0 @@ -# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible.plugins.action import ActionBase -from ansible.plugins.action.template import ActionModule as TemplateActionModule - - -# Even though TemplateActionModule inherits from ActionBase, we still need to -# directly inherit from ActionBase to appease the plugin loader. -class ActionModule(TemplateActionModule, ActionBase): - DEFAULT_NEWLINE_SEQUENCE = '\r\n' diff --git a/lib/ansible/plugins/action/win_updates.py b/lib/ansible/plugins/action/win_updates.py deleted file mode 100644 index 7e0187a503..0000000000 --- a/lib/ansible/plugins/action/win_updates.py +++ /dev/null @@ -1,247 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json - -from ansible.errors import AnsibleError -from ansible.module_utils._text import to_text -from ansible.module_utils.parsing.convert_bool import boolean -from ansible.parsing.yaml.objects import AnsibleUnicode -from ansible.plugins.action import ActionBase -from ansible.plugins.loader import become_loader -from ansible.utils.display import Display - -display = Display() - - -class ActionModule(ActionBase): - - DEFAULT_REBOOT_TIMEOUT = 1200 - - def _run_win_updates(self, module_args, task_vars, use_task): - display.vvv("win_updates: running win_updates module") - wrap_async = self._task.async_val - result = self._execute_module_with_become(module_name='win_updates', - module_args=module_args, - task_vars=task_vars, - wrap_async=wrap_async, - use_task=use_task) - return result - - def _reboot_server(self, task_vars, reboot_timeout, use_task): - display.vvv("win_updates: rebooting remote host after update install") - reboot_args = { - 'reboot_timeout': reboot_timeout - } - reboot_result = self._run_action_plugin('win_reboot', task_vars, - module_args=reboot_args) - if reboot_result.get('failed', False): - raise AnsibleError(reboot_result['msg']) - - # only run this if the user has specified we can only use scheduled - # tasks, the win_shell command requires become and will be skipped if - # become isn't available to use - if use_task: - display.vvv("win_updates: skipping WUA is not busy check as " - "use_scheduled_task=True is set") - else: - display.vvv("win_updates: checking WUA is not busy with win_shell " - "command") - # While this always returns False after a reboot it doesn't return - # a value until Windows is actually ready and finished installing - # updates. This needs to run with become as WUA doesn't work over - # WinRM, ignore connection errors as another reboot can happen - command = "(New-Object -ComObject Microsoft.Update.Session)." \ - "CreateUpdateInstaller().IsBusy" - shell_module_args = { - '_raw_params': command - } - - try: - shell_result = self._execute_module_with_become( - module_name='win_shell', module_args=shell_module_args, - task_vars=task_vars, wrap_async=False, use_task=use_task - ) - display.vvv("win_updates: shell wait results: %s" - % json.dumps(shell_result)) - except Exception as exc: - display.debug("win_updates: Fatal error when running shell " - "command, attempting to recover: %s" % to_text(exc)) - - display.vvv("win_updates: ensure the connection is up and running") - # in case Windows needs to reboot again after the updates, we wait for - # the connection to be stable again - wait_for_result = self._run_action_plugin('wait_for_connection', - task_vars) - if wait_for_result.get('failed', False): - raise AnsibleError(wait_for_result['msg']) - - def _run_action_plugin(self, plugin_name, task_vars, module_args=None): - # Create new task object and reset the args - new_task = self._task.copy() - new_task.args = {} - - if module_args is not None: - for key, value in module_args.items(): - new_task.args[key] = value - - # run the action plugin and return the results - action = self._shared_loader_obj.action_loader.get( - plugin_name, - task=new_task, - connection=self._connection, - play_context=self._play_context, - loader=self._loader, - templar=self._templar, - shared_loader_obj=self._shared_loader_obj - ) - return action.run(task_vars=task_vars) - - def _merge_dict(self, original, new): - dict_var = original.copy() - dict_var.update(new) - return dict_var - - def _execute_module_with_become(self, module_name, module_args, task_vars, - wrap_async, use_task): - orig_become = self._connection.become - try: - if not use_task and orig_become is None: - become = become_loader.get('runas') - become.set_options(direct={'become_user': 'SYSTEM', 'become_pass': None}) - self._connection.set_become_plugin(become) - - module_res = self._execute_module(module_name=module_name, - module_args=module_args, - task_vars=task_vars, - wrap_async=wrap_async) - finally: - self._connection.set_become_plugin(orig_become) - - return module_res - - def run(self, tmp=None, task_vars=None): - self._supports_check_mode = True - self._supports_async = True - - result = super(ActionModule, self).run(tmp, task_vars) - del tmp # tmp no longer has any effect - - state = self._task.args.get('state', 'installed') - reboot = self._task.args.get('reboot', False) - reboot_timeout = self._task.args.get('reboot_timeout', - self.DEFAULT_REBOOT_TIMEOUT) - use_task = boolean(self._task.args.get('use_scheduled_task', False), - strict=False) - - if state not in ['installed', 'searched', 'downloaded']: - result['failed'] = True - result['msg'] = "state must be either installed, searched or downloaded" - return result - - try: - reboot = boolean(reboot) - except TypeError as exc: - result['failed'] = True - result['msg'] = "cannot parse reboot as a boolean: %s" % to_text(exc) - return result - - if not isinstance(reboot_timeout, int): - result['failed'] = True - result['msg'] = "reboot_timeout must be an integer" - return result - - if reboot and self._task.async_val > 0: - result['failed'] = True - result['msg'] = "async is not supported for this task when " \ - "reboot=yes" - return result - - # Run the module - new_module_args = self._task.args.copy() - new_module_args.pop('reboot', None) - new_module_args.pop('reboot_timeout', None) - result = self._run_win_updates(new_module_args, task_vars, use_task) - - # if the module failed to run at all then changed won't be populated - # so we just return the result as is - # https://github.com/ansible/ansible/issues/38232 - failed = result.get('failed', False) - if ("updates" not in result.keys() and self._task.async_val == 0) or failed: - result['failed'] = True - return result - - changed = result.get('changed', False) - updates = result.get('updates', dict()) - filtered_updates = result.get('filtered_updates', dict()) - found_update_count = result.get('found_update_count', 0) - installed_update_count = result.get('installed_update_count', 0) - - # Handle automatic reboots if the reboot flag is set - if reboot and state == 'installed' and not \ - self._play_context.check_mode: - previously_errored = False - while result['installed_update_count'] > 0 or \ - result['found_update_count'] > 0 or \ - result['reboot_required'] is True: - display.vvv("win_updates: check win_updates results for " - "automatic reboot: %s" % json.dumps(result)) - - # check if the module failed, break from the loop if it - # previously failed and return error to the user - if result.get('failed', False): - if previously_errored: - break - previously_errored = True - else: - previously_errored = False - - reboot_error = None - # check if a reboot was required before installing the updates - if result.get('msg', '') == "A reboot is required before " \ - "more updates can be installed": - reboot_error = "reboot was required before more updates " \ - "can be installed" - - if result.get('reboot_required', False): - if reboot_error is None: - reboot_error = "reboot was required to finalise " \ - "update install" - try: - changed = True - self._reboot_server(task_vars, reboot_timeout, - use_task) - except AnsibleError as exc: - result['failed'] = True - result['msg'] = "Failed to reboot remote host when " \ - "%s: %s" \ - % (reboot_error, to_text(exc)) - break - - result.pop('msg', None) - # rerun the win_updates module after the reboot is complete - result = self._run_win_updates(new_module_args, task_vars, - use_task) - if result.get('failed', False): - return result - - result_updates = result.get('updates', dict()) - result_filtered_updates = result.get('filtered_updates', dict()) - updates = self._merge_dict(updates, result_updates) - filtered_updates = self._merge_dict(filtered_updates, - result_filtered_updates) - found_update_count += result.get('found_update_count', 0) - installed_update_count += result.get('installed_update_count', 0) - if result['changed']: - changed = True - - # finally create the return dict based on the aggregated execution - # values if we are not in async - if self._task.async_val == 0: - result['changed'] = changed - result['updates'] = updates - result['filtered_updates'] = filtered_updates - result['found_update_count'] = found_update_count - result['installed_update_count'] = installed_update_count - - return result diff --git a/lib/ansible/plugins/doc_fragments/url_windows.py b/lib/ansible/plugins/doc_fragments/url_windows.py deleted file mode 100644 index 29a5be311f..0000000000 --- a/lib/ansible/plugins/doc_fragments/url_windows.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2019 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - - -class ModuleDocFragment(object): - - # Standard files documentation fragment - DOCUMENTATION = r''' -options: - method: - description: - - The HTTP Method of the request. - type: str - follow_redirects: - description: - - Whether or the module should follow redirects. - - C(all) will follow all redirect. - - C(none) will not follow any redirect. - - C(safe) will follow only "safe" redirects, where "safe" means that the - client is only doing a C(GET) or C(HEAD) on the URI to which it is being - redirected. - choices: - - all - - none - - safe - default: safe - type: str - headers: - description: - - Extra headers to set on the request. - - This should be a dictionary where the key is the header name and the - value is the value for that header. - type: dict - http_agent: - description: - - Header to identify as, generally appears in web server logs. - - This is set to the C(User-Agent) header on a HTTP request. - default: ansible-httpget - type: str - version_added: "2.9" - maximum_redirection: - description: - - Specify how many times the module will redirect a connection to an - alternative URI before the connection fails. - - If set to C(0) or I(follow_redirects) is set to C(none), or C(safe) when - not doing a C(GET) or C(HEAD) it prevents all redirection. - default: 50 - type: int - timeout: - description: - - Specifies how long the request can be pending before it times out (in - seconds). - - Set to C(0) to specify an infinite timeout. - default: 30 - type: int - version_added: "2.4" - validate_certs: - description: - - If C(no), SSL certificates will not be validated. - - This should only be used on personally controlled sites using self-signed - certificates. - default: yes - type: bool - version_added: "2.4" - client_cert: - description: - - The path to the client certificate (.pfx) that is used for X509 - authentication. This path can either be the path to the C(pfx) on the - filesystem or the PowerShell certificate path - C(Cert:\CurrentUser\My\<thumbprint>). - - The WinRM connection must be authenticated with C(CredSSP) or C(become) - is used on the task if the certificate file is not password protected. - - Other authentication types can set I(client_cert_password) when the cert - is password protected. - type: str - client_cert_password: - description: - - The password for I(client_cert) if the cert is password protected. - type: str - force_basic_auth: - description: - - By default the authentication header is only sent when a webservice - responses to an initial request with a 401 status. Since some basic auth - services do not properly send a 401, logins will fail. - - This option forces the sending of the Basic authentication header upon - the original request. - default: no - type: bool - version_added: "2.5" - url_username: - description: - - The username to use for authentication. - type: str - url_password: - description: - - The password for I(url_username). - type: str - use_default_credential: - description: - - Uses the current user's credentials when authenticating with a server - protected with C(NTLM), C(Kerberos), or C(Negotiate) authentication. - - Sites that use C(Basic) auth will still require explicit credentials - through the I(url_username) and I(url_password) options. - - The module will only have access to the user's credentials if using - C(become) with a password, you are connecting with SSH using a password, - or connecting with WinRM using C(CredSSP) or C(Kerberos with delegation). - - If not using C(become) or a different auth method to the ones stated - above, there will be no default credentials available and no - authentication will occur. - default: no - type: bool - version_added: "2.9" - use_proxy: - description: - - If C(no), it will not use the proxy defined in IE for the current user. - default: yes - type: bool - proxy_url: - description: - - An explicit proxy to use for the request. - - By default, the request will use the IE defined proxy unless I(use_proxy) - is set to C(no). - type: str - proxy_username: - description: - - The username to use for proxy authentication. - type: str - proxy_password: - description: - - The password for I(proxy_username). - type: str - proxy_use_default_credential: - description: - - Uses the current user's credentials when authenticating with a proxy host - protected with C(NTLM), C(Kerberos), or C(Negotiate) authentication. - - Proxies that use C(Basic) auth will still require explicit credentials - through the I(proxy_username) and I(proxy_password) options. - - The module will only have access to the user's credentials if using - C(become) with a password, you are connecting with SSH using a password, - or connecting with WinRM using C(CredSSP) or C(Kerberos with delegation). - - If not using C(become) or a different auth method to the ones stated - above, there will be no default credentials available and no proxy - authentication will occur. - default: no - type: bool - version_added: "2.9" -seealso: -- module: win_inet_proxy -''' diff --git a/test/integration/targets/win_acl/aliases b/test/integration/targets/win_acl/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_acl/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_acl/defaults/main.yml b/test/integration/targets/win_acl/defaults/main.yml deleted file mode 100644 index 9999acd1ba..0000000000 --- a/test/integration/targets/win_acl/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -test_acl_path: '{{ win_output_dir }}\win_acl .ÅÑŚÌβŁÈ [$!@^&test(;)]' -test_acl_network_path: \\localhost\{{ test_acl_path[0:1] }}$\{{ test_acl_path[3:] }} -# Use HKU as that path is not automatically loaded in the PSProvider making our test more complex -test_acl_reg_path: HKU:\.DEFAULT\Ansible Test .ÅÑŚÌβŁÈ [$!@^&test(;)] diff --git a/test/integration/targets/win_acl/tasks/main.yml b/test/integration/targets/win_acl/tasks/main.yml deleted file mode 100644 index d322fb893a..0000000000 --- a/test/integration/targets/win_acl/tasks/main.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -- name: ensure we start with a clean dir - win_file: - path: '{{ test_acl_path }}' - state: '{{ item }}' - with_items: - - absent - - directory - -- name: ensure we start with a clean reg path - win_regedit: - path: '{{ test_acl_reg_path }}' - delete_key: yes - state: '{{ item }}' - with_items: - - absent - - present - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: cleanup testing dir - win_file: - path: '{{ test_acl_path }}' - state: absent - - - name: cleanup testing reg path - win_regedit: - path: '{{ test_acl_reg_path }}' - delete_key: yes - state: absent diff --git a/test/integration/targets/win_acl/tasks/tests.yml b/test/integration/targets/win_acl/tasks/tests.yml deleted file mode 100644 index 56f5273373..0000000000 --- a/test/integration/targets/win_acl/tasks/tests.yml +++ /dev/null @@ -1,362 +0,0 @@ -# these are very basic tests, they should be expanded greatly as this is a core module ---- -- name: get register cmd that will get ace info - set_fact: - test_ace_cmd: | - # Overcome bug in Set-Acl/Get-Acl for registry paths and -LiteralPath - New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS > $null - Push-Location -LiteralPath (Split-Path -Path $path -Qualifier) - $rights_key = if ((Get-Item -LiteralPath $path -Force).PSProvider.Name -eq "Registry") { - "RegistryRights" - } else { - "FileSystemRights" - } - $ace_list = (Get-Acl -LiteralPath $path).Access | Where-Object { $_.IsInherited -eq $false } | ForEach-Object { - @{ - rights = $_."$rights_key".ToString() - type = $_.AccessControlType.ToString() - identity = $_.IdentityReference.Value.ToString() - inheritance_flags = $_.InheritanceFlags.ToString() - propagation_flags = $_.PropagationFlags.ToString() - } - } - Pop-Location - ConvertTo-Json -InputObject @($ace_list) - -- name: add write rights to Guest - win_acl: - path: '{{ test_acl_path }}' - type: allow - user: Guests - rights: Write - register: allow_right - -- name: get result of add write rights to Guest - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: allow_right_actual - -- name: assert add write rights to Guest - assert: - that: - - allow_right is changed - - (allow_right_actual.stdout|from_json)|count == 1 - - (allow_right_actual.stdout|from_json)[0].identity == 'BUILTIN\Guests' - - (allow_right_actual.stdout|from_json)[0].inheritance_flags == 'ContainerInherit, ObjectInherit' - - (allow_right_actual.stdout|from_json)[0].propagation_flags == 'None' - - (allow_right_actual.stdout|from_json)[0].rights == 'Write, Synchronize' - - (allow_right_actual.stdout|from_json)[0].type == 'Allow' - -- name: add write rights to Guest (idempotent) - win_acl: - path: '{{ test_acl_path }}' - type: allow - user: Guests - rights: Write - register: allow_right_again - -- name: assert add write rights to Guest (idempotent) - assert: - that: - - not allow_right_again is changed - -- name: remove write rights from Guest - win_acl: - path: '{{ test_acl_path }}' - type: allow - user: Guests - rights: Write - state: absent - register: remove_right - -- name: get result of remove write rights from Guest - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: remove_right_actual - -- name: assert remove write rights from Guest - assert: - that: - - remove_right is changed - - remove_right_actual.stdout_lines == ["[", "", "]"] - -- name: remove write rights from Guest (idempotent) - win_acl: - path: '{{ test_acl_path }}' - type: allow - user: Guests - rights: Write - state: absent - register: remove_right_again - -- name: assert remote write rights from Guest (idempotent) - assert: - that: - - not remove_right_again is changed - -- name: add deny write rights to Guest - win_acl: - path: '{{ test_acl_path }}' - type: deny - user: Guests - rights: Write - inherit: ContainerInherit - propagation: NoPropagateInherit - state: present - register: add_deny_right - -- name: get result of add deny write rights to Guest - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: add_deny_right_actual - -- name: assert add deny write rights to Guest - assert: - that: - - add_deny_right is changed - - (add_deny_right_actual.stdout|from_json)|count == 1 - - (add_deny_right_actual.stdout|from_json)[0].identity == 'BUILTIN\Guests' - - (add_deny_right_actual.stdout|from_json)[0].inheritance_flags == 'ContainerInherit' - - (add_deny_right_actual.stdout|from_json)[0].propagation_flags == 'NoPropagateInherit' - - (add_deny_right_actual.stdout|from_json)[0].rights == 'Write' - - (add_deny_right_actual.stdout|from_json)[0].type == 'Deny' - -- name: add deny write rights to Guest (idempotent) - win_acl: - path: '{{ test_acl_path }}' - type: deny - user: Guests - rights: Write - inherit: ContainerInherit - propagation: NoPropagateInherit - state: present - register: add_deny_right_again - -- name: assert add deny write rights to Guest (idempotent) - assert: - that: - - not add_deny_right_again is changed - -- name: remove deny write rights from Guest - win_acl: - path: '{{ test_acl_path }}' - type: deny - user: Guests - rights: Write - inherit: ContainerInherit - propagation: NoPropagateInherit - state: absent - register: remove_deny_right - -- name: get result of remove deny write rights from Guest - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: remove_deny_right_actual - -- name: assert remove deny write rights from Guest - assert: - that: - - remove_deny_right is changed - - remove_deny_right_actual.stdout_lines == ["[", "", "]"] - -- name: remove deny write rights from Guest (idempotent) - win_acl: - path: '{{ test_acl_path }}' - type: deny - user: Guests - rights: Write - inherit: ContainerInherit - propagation: NoPropagateInherit - state: absent - register: remove_deny_right_again - -- name: assert remove deny write rights from Guest (idempotent) - assert: - that: - - not remove_deny_right_again is changed - -- name: add write rights to Guest - network - win_acl: - path: '{{ test_acl_network_path }}' - type: allow - user: Guests - rights: Write - register: allow_right - -- name: get result of add write rights to Guest - network - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: allow_right_actual - -- name: assert add write rights to Guest - network - assert: - that: - - allow_right is changed - - (allow_right_actual.stdout|from_json)|count == 1 - - (allow_right_actual.stdout|from_json)[0].identity == 'BUILTIN\Guests' - - (allow_right_actual.stdout|from_json)[0].inheritance_flags == 'ContainerInherit, ObjectInherit' - - (allow_right_actual.stdout|from_json)[0].propagation_flags == 'None' - - (allow_right_actual.stdout|from_json)[0].rights == 'Write, Synchronize' - - (allow_right_actual.stdout|from_json)[0].type == 'Allow' - -- name: remove write rights from Guest - network - win_acl: - path: '{{ test_acl_network_path }}' - type: allow - user: Guests - rights: Write - state: absent - register: remove_right - -- name: get result of remove write rights from Guest - network - win_shell: '$path = ''{{ test_acl_path }}''; {{ test_ace_cmd }}' - register: remove_right_actual - -- name: assert remove write rights from Guest - assert: - that: - - remove_right is changed - - remove_right_actual.stdout_lines == ["[", "", "]"] - -- name: add write rights to Guest - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: allow - user: Guests - rights: WriteKey - register: allow_right_reg - -- name: get result of add write rights to Guest - registry - win_shell: '$path = ''{{ test_acl_reg_path }}''; {{ test_ace_cmd }}' - register: allow_right_reg_actual - -- name: assert add write rights to Guest - registry - assert: - that: - - allow_right_reg is changed - - (allow_right_reg_actual.stdout|from_json)|count == 1 - - (allow_right_reg_actual.stdout|from_json)[0].identity == 'BUILTIN\Guests' - - (allow_right_reg_actual.stdout|from_json)[0].inheritance_flags == 'ContainerInherit, ObjectInherit' - - (allow_right_reg_actual.stdout|from_json)[0].propagation_flags == 'None' - - (allow_right_reg_actual.stdout|from_json)[0].rights == 'WriteKey' - - (allow_right_reg_actual.stdout|from_json)[0].type == 'Allow' - -- name: add write rights to Guest (idempotent) - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: allow - user: Guests - rights: WriteKey - register: allow_right_reg_again - -- name: assert add write rights to Guest (idempotent) - registry - assert: - that: - - not allow_right_reg_again is changed - -- name: remove write rights from Guest - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: allow - user: Guests - rights: WriteKey - state: absent - register: remove_right_reg - -- name: get result of remove write rights from Guest - registry - win_shell: '$path = ''{{ test_acl_reg_path }}''; {{ test_ace_cmd }}' - register: remove_right_reg_actual - -- name: assert remove write rights from Guest - registry - assert: - that: - - remove_right_reg is changed - - remove_right_reg_actual.stdout_lines == ["[", "", "]"] - -- name: remove write rights from Guest (idempotent) - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: allow - user: Guests - rights: WriteKey - state: absent - register: remove_right_reg_again - -- name: assert remote write rights from Guest (idempotent) - registry - assert: - that: - - not remove_right_reg_again is changed - -- name: add deny write rights to Guest - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: deny - user: Guests - rights: WriteKey - inherit: ContainerInherit - propagation: NoPropagateInherit - state: present - register: add_deny_right_reg - -- name: get result of add deny write rights to Guest - registry - win_shell: '$path = ''{{ test_acl_reg_path }}''; {{ test_ace_cmd }}' - register: add_deny_right_reg_actual - -- name: assert add deny write rights to Guest - registry - assert: - that: - - add_deny_right_reg is changed - - (add_deny_right_reg_actual.stdout|from_json)|count == 1 - - (add_deny_right_reg_actual.stdout|from_json)[0].identity == 'BUILTIN\Guests' - - (add_deny_right_reg_actual.stdout|from_json)[0].inheritance_flags == 'ContainerInherit' - - (add_deny_right_reg_actual.stdout|from_json)[0].propagation_flags == 'NoPropagateInherit' - - (add_deny_right_reg_actual.stdout|from_json)[0].rights == 'WriteKey' - - (add_deny_right_reg_actual.stdout|from_json)[0].type == 'Deny' - -- name: add deny write rights to Guest (idempotent) - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: deny - user: Guests - rights: WriteKey - inherit: ContainerInherit - propagation: NoPropagateInherit - state: present - register: add_deny_right_reg_again - -- name: assert add deny write rights to Guest (idempotent) - registry - assert: - that: - - not add_deny_right_reg_again is changed - -- name: remove deny write rights from Guest - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: deny - user: Guests - rights: WriteKey - inherit: ContainerInherit - propagation: NoPropagateInherit - state: absent - register: remove_deny_right_reg - -- name: get result of remove deny write rights from Guest - registry - win_shell: '$path = ''{{ test_acl_reg_path }}''; {{ test_ace_cmd }}' - register: remove_deny_right_reg_actual - -- name: assert remove deny write rights from Guest - registry - assert: - that: - - remove_deny_right_reg is changed - - remove_deny_right_reg_actual.stdout_lines == ["[", "", "]"] - -- name: remove deny write rights from Guest (idempotent) - registry - win_acl: - path: '{{ test_acl_reg_path }}' - type: deny - user: Guests - rights: WriteKey - inherit: ContainerInherit - propagation: NoPropagateInherit - state: absent - register: remove_deny_right_reg_again - -- name: assert remove deny write rights from Guest (idempotent) - registry - assert: - that: - - not remove_deny_right_reg_again is changed diff --git a/test/integration/targets/win_acl_inheritance/aliases b/test/integration/targets/win_acl_inheritance/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_acl_inheritance/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_acl_inheritance/defaults/main.yml b/test/integration/targets/win_acl_inheritance/defaults/main.yml deleted file mode 100644 index 138063f4fe..0000000000 --- a/test/integration/targets/win_acl_inheritance/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_win_acl_inheritance_path: C:\ansible\win_acl_inheritance .ÅÑŚÌβŁÈ [$!@^&test(;)] diff --git a/test/integration/targets/win_acl_inheritance/library/test_get_acl.ps1 b/test/integration/targets/win_acl_inheritance/library/test_get_acl.ps1 deleted file mode 100644 index c75d33ead8..0000000000 --- a/test/integration/targets/win_acl_inheritance/library/test_get_acl.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -#!powershell - -# WANT_JSON -# POWERSHELL_COMMON - -$ErrorActionPreference = 'Stop' -Set-StrictMode -Version 2.0 - -$params = Parse-Args $args -supports_check_mode $false -$path = Get-AnsibleParam -obj $params "path" -type "path" -failifempty $true - -$result = @{ - changed = $false -} - -$acl = Get-Acl -LiteralPath $path - -$result.inherited = $acl.AreAccessRulesProtected -eq $false - -$user_details = @{} -$acl.Access | ForEach-Object { - $user = $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value - if ($user_details.ContainsKey($user)) { - $details = $user_details.$user - } else { - $details = @{ - isinherited = $false - } - } - $details.isinherited = $_.IsInherited - $user_details.$user = $details -} - -$result.user_details = $user_details - -Exit-Json $result diff --git a/test/integration/targets/win_acl_inheritance/tasks/main.yml b/test/integration/targets/win_acl_inheritance/tasks/main.yml deleted file mode 100644 index 9b613276a3..0000000000 --- a/test/integration/targets/win_acl_inheritance/tasks/main.yml +++ /dev/null @@ -1,174 +0,0 @@ ---- -# Test setup -# Use single task to save in CI runtime -- name: create test folders - win_shell: | - $ErrorActionPreference = 'Stop' - - $tmp_dir = '{{ test_win_acl_inheritance_path }}' - if (Test-Path -LiteralPath $tmp_dir) { - Remove-Item -LiteralPath $tmp_dir -Force -Recurse - } - New-Item -Path $tmp_dir -ItemType Directory > $null - - Add-Type -AssemblyName System.DirectoryServices.AccountManagement - $current_sid = ([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).Sid - $system_sid = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList @([System.Security.Principal.WellKnownSidType]::LocalSystemSid, $null) - $everyone_sid = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList @([System.Security.Principal.WellKnownSidType]::WorldSid, $null) - - $sd = New-Object -TypeName System.Security.AccessControl.DirectorySecurity - $sd.SetAccessRuleProtection($true, $false) - $sd.AddAccessRule( - (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList @( - $system_sid, - [System.Security.AccessControl.FileSystemRights]::FullControl, - [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit", - [System.Security.AccessControl.PropagationFlags]::None, - [System.Security.AccessControl.AccessControlType]::Allow - )) - ) - $sd.AddAccessRule( - (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList @( - $current_sid, - [System.Security.AccessControl.FileSystemRights]::FullControl, - [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit", - [System.Security.AccessControl.PropagationFlags]::None, - [System.Security.AccessControl.AccessControlType]::Allow - )) - ) - $sd.AddAccessRule( - (New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList @( - $everyone_sid, - [System.Security.AccessControl.FileSystemRights]::Read, - [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit", - [System.Security.AccessControl.PropagationFlags]::None, - [System.Security.AccessControl.AccessControlType]::Allow - )) - ) - - Set-Acl -LiteralPath $tmp_dir -AclObject $sd - - New-Item -Path "$tmp_dir\folder" -ItemType Directory > $null - Set-Content -LiteralPath "$tmp_dir\folder\file.txt" -Value 'a' - - $system_sid.Value - $current_sid.Value - $everyone_sid.Value - register: test_sids # register the output SID values used for comparison tests below - -# Run tests -- name: remove inheritance check - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: absent - register: remove_check - check_mode: True - -- name: get actual remove inheritance check - test_get_acl: - path: '{{ test_win_acl_inheritance_path }}\folder' - register: actual_remove_check - -- name: assert remove inheritance check - assert: - that: - - remove_check is changed - - actual_remove_check.inherited == True - - actual_remove_check.user_details[test_sids.stdout_lines[0]].isinherited == True - - actual_remove_check.user_details[test_sids.stdout_lines[1]].isinherited == True - - actual_remove_check.user_details[test_sids.stdout_lines[2]].isinherited == True - -- name: remove inheritance - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: absent - register: remove - -- name: get actual remove inheritance - test_get_acl: - path: '{{ test_win_acl_inheritance_path }}\folder' - register: actual_remove - -- name: assert remove inheritance - assert: - that: - - remove is changed - - actual_remove.inherited == False - - actual_remove.user_details[test_sids.stdout_lines[0]].isinherited == False - - actual_remove.user_details[test_sids.stdout_lines[1]].isinherited == False - - actual_remove.user_details[test_sids.stdout_lines[2]].isinherited == False - -- name: remove inheritance again - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: absent - register: remove_again - -- name: assert remove inheritance again - assert: - that: - - remove_again is not changed - -- name: add inheritance check - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: present - register: add_check - check_mode: True - -- name: get actual add inheritance check - test_get_acl: - path: '{{ test_win_acl_inheritance_path }}\folder' - register: actual_add_check - -- name: assert add inheritance check - assert: - that: - - add_check is changed - - actual_add_check.inherited == False - - actual_add_check.user_details[test_sids.stdout_lines[0]].isinherited == False - - actual_add_check.user_details[test_sids.stdout_lines[1]].isinherited == False - - actual_add_check.user_details[test_sids.stdout_lines[2]].isinherited == False - -- name: add inheritance - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: present - register: add - -- name: get actual add inheritance - test_get_acl: - path: '{{ test_win_acl_inheritance_path }}\folder' - register: actual_add - -- name: assert add inheritance - assert: - that: - - add is changed - - actual_add.inherited == True - - actual_add.user_details[test_sids.stdout_lines[0]].isinherited == True - - actual_add.user_details[test_sids.stdout_lines[1]].isinherited == True - - actual_add.user_details[test_sids.stdout_lines[2]].isinherited == True - -- name: add inheritance again - win_acl_inheritance: - path: '{{ test_win_acl_inheritance_path }}\folder' - reorganize: True - state: present - register: add_again - -- name: assert add inheritance again - assert: - that: - - add_again is not changed - -# Test cleanup -- name: remove test folder - win_file: - path: '{{ test_win_acl_inheritance_path }}' - state: absent diff --git a/test/integration/targets/win_certificate_store/aliases b/test/integration/targets/win_certificate_store/aliases deleted file mode 100644 index c46e6e61f4..0000000000 --- a/test/integration/targets/win_certificate_store/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group7 -skip/windows/2016 # Host takes a while to run and module isn't OS dependent diff --git a/test/integration/targets/win_certificate_store/defaults/main.yml b/test/integration/targets/win_certificate_store/defaults/main.yml deleted file mode 100644 index 19ab156654..0000000000 --- a/test/integration/targets/win_certificate_store/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -win_cert_dir: '{{win_output_dir}}\win_certificate .ÅÑŚÌβŁÈ [$!@^&test(;)]' -key_password: password -subj_thumbprint: 'BD7AF104CF1872BDB518D95C9534EA941665FD27' -root_thumbprint: 'BC05633694E675449136679A658281F17A191087' diff --git a/test/integration/targets/win_certificate_store/files/root-cert.pem b/test/integration/targets/win_certificate_store/files/root-cert.pem deleted file mode 100644 index edbe6b8684..0000000000 --- a/test/integration/targets/win_certificate_store/files/root-cert.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDKDCCAhCgAwIBAgIJAP1vIdGgMJv/MA0GCSqGSIb3DQEBCwUAMCgxGTAXBgNV -BAMMEHJvb3QuYW5zaWJsZS5jb20xCzAJBgNVBAYTAlVTMCAXDTE3MTIxNTA4Mzkz -MloYDzIwODYwMTAyMDgzOTMyWjAoMRkwFwYDVQQDDBByb290LmFuc2libGUuY29t -MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmq -YT8eZY6rFQKnmScUGnnUH1tLQ+3WQpfKiWygCUSb1CNqO3J1u3pGMEqYM58LK4Kr -Mpskv7K1tCV/EMZqGTqXAIfSLy9umlb/9C3AhL9thBPn5I9dam/EmrIZktI9/w5Y -wBXn4toe+OopA3QkMQh9BUjUCPb9fdOI+ir7OGFZMmxXmiM64+BEeywM2oSGsdZ9 -5hU378UBu2IX4+OAV8Fbr2l6VW+Fxg/tKIOo6Bs46Pa4EZgtemOqs3kxYBOltBTb -vFcLsLa4KYVu5Ge5YfB0Axfaem7PoP8IlMs8gxyojZ/r0o5hzxUcYlL/h8GeeoLW -PFFdiAS+UgxWINOqNXMCAwEAAaNTMFEwHQYDVR0OBBYEFLp9k4LmOnAR4ROrqhb+ -CFdbk2+oMB8GA1UdIwQYMBaAFLp9k4LmOnAR4ROrqhb+CFdbk2+oMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGksycHsjGbXfWfuhQh+CvXk/A2v -MoNgiHtNMTGliVNgoVp1B1rj4x9xyZ8YrO8GAmv8jaCwCShd0B5Ul4aZVk1wglVv -lFAwb4IAZN9jv9+fw5BRzQ2tLhkVWIEwx6pZkhGhhjBvMaplLN5JwBtsdZorFbm7 -wuKiUKcFAM28acoOhCmOhgyNNBZpZn5wXaQDY43AthJOhitAV7vph4MPUkwIJnOh -MA5GJXEqS58TE9z9pkhQnn9598G8tmOXyA2erAoM9JAXM3EYHxVpoHBb9QRj6WAw -XVBo6qRXkwjNEM5CbnD4hVIBsdkOGsDrgd4Q5izQZ3x+jFNkdL/zPsXjJFw= ------END CERTIFICATE----- - diff --git a/test/integration/targets/win_certificate_store/files/root-key.pem b/test/integration/targets/win_certificate_store/files/root-key.pem deleted file mode 100644 index c2d641d449..0000000000 --- a/test/integration/targets/win_certificate_store/files/root-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAyaphPx5ljqsVAqeZJxQaedQfW0tD7dZCl8qJbKAJRJvUI2o7 -cnW7ekYwSpgznwsrgqsymyS/srW0JX8QxmoZOpcAh9IvL26aVv/0LcCEv22EE+fk -j11qb8SashmS0j3/DljAFefi2h746ikDdCQxCH0FSNQI9v1904j6Kvs4YVkybFea -Izrj4ER7LAzahIax1n3mFTfvxQG7Yhfj44BXwVuvaXpVb4XGD+0og6joGzjo9rgR -mC16Y6qzeTFgE6W0FNu8VwuwtrgphW7kZ7lh8HQDF9p6bs+g/wiUyzyDHKiNn+vS -jmHPFRxiUv+HwZ56gtY8UV2IBL5SDFYg06o1cwIDAQABAoIBAFRpZNsutgPJyLmb -vZeF6q8kAxwLnRtom+c9d9hoBHkbYOiSBuAaN6cuyffvTWw9GLFRR5V5BGSheg5X -6YWj03uayTYQ3H9WJHRWHrcn5mjaRnaukhUQXQT7nmT+H16xZJl0vLJupZ33aOla -0X9DxuJusk+RsU7xPEHXDCABl8/m7v3cFttUBughGBG5oDuzKlFbhXPwA8/yeJ1v -qdXKxENi9HO4X5fH1l0vFNIhEqvUVKjw/AzapYtr+bv1wssoNAzvhT7CFa2GjPQ0 -Ibcq3+RxyAN4iQVITy86Yl4LW1jLx63wbg9q1WG/ca9K/OEAuT7ebJNeMYmM+kf7 -sf6A8wECgYEA+nnLJ4QtANtAs6nmDC106DTx1cOf3Yq9JOAvmGLomF/8SrUzZbXM -F+JcZcttXuuFIFcZD0K7fFP9sx2ITH//BS5V0B0x7Z2olWexVjR6/5pOVFPu19ow -tyDCNi5BlTPbvSr/fAxjmO9SgVTb8oG66i4mi0Xn5bp1E441KdvNsHECgYEAzhz/ -+SjFJlJcGNvMmgfAbfv6McUv7TKrPIvVkA++Gi5QdqJjkuzL1uTfgWIY/9iDByMd -W36rFTkYrw6LTMF2dkMjul72Kkco3UExSzOmF4lFmCt3DZW6a6CExKpwk4kF2RnX -GRD0FoZZown3RbPHi9rsWxjyVy/yKGwnvXYndiMCgYEA6rnIUDfllK/jansFQtQ2 -goVbPGAfKJYjurL852mJX4JUBA7bI63CnX9b52lEDXfZQf1dVpfK6zAqx/gdCtPI -QSqy8FzrtSnSGnEaFxcHTRFl5lDhuxaWIIdqeSvP+eqnOhdZZP6XN3LPdrP3isNY -Tq0BIfNY5khd/v19hMSfdYECgYBQ8h6tMY/LrwiwUpIV4/l0uELYDQL3erC5RImI -3EXiblH3ZWsJpqmfKZ+FZos+3z8GLIo5BpQV76h8B5A5grkNVOzRIr42eF/aFOJR -EGWoVKbaTiehVC40WoQJ4I35wxRi4L0TAQ97USQe3akY3LP/fujYFgIGr7PAoEkz -JRX2VQKBgQDir8/a3FZVo6nYI8zIhBz8xqZJIgvlYQqiQFFwADu5eNPMvNIaVy+6 -7HKibGM2jPkuS2KHdc8WUp8IrRRMui04qE7kRxVu41QXEBfPiDvrvAQf8SfJe631 -XvYeZr7HKY4NI5J0ENcb54d7DLQ8a1/wL/GeLVrfUWG35Ra5MW57Og== ------END RSA PRIVATE KEY----- - diff --git a/test/integration/targets/win_certificate_store/files/subj-cert.pem b/test/integration/targets/win_certificate_store/files/subj-cert.pem deleted file mode 100644 index 6d9ec39c73..0000000000 --- a/test/integration/targets/win_certificate_store/files/subj-cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC0TCCAbkCCQC/MtOBa1UDpzANBgkqhkiG9w0BAQsFADAoMRkwFwYDVQQDDBBy -b290LmFuc2libGUuY29tMQswCQYDVQQGEwJVUzAgFw0xNzEyMTUwODU2MzBaGA8y -MDg2MDEwMjA4NTYzMFowKzEcMBoGA1UEAwwTc3ViamVjdC5hbnNpYmxlLmNvbTEL -MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDszqdF -So3GlVP1xUnN4bSPrFRFiOl/Mqup0Zn5UJJUR9wLnRD+OLcq7kKin6hYqozSu7cC -+BnWQoq7vGSSNVqv7BqFMwzGJt9IBUQv0UqIQkA/duUdKdAiMn2PQRsNDnkWEbTj -4xsitItVNv84cDG0lkZBYyTgfyZlZLZWplkpUQkrZhoFCekZRJ+ODrqNW3W560rr -OUIh+HiQeBqocat6OdxgICBqpUh8EVo1iha3DXjGN08q5utg6gmbIl2VBaVJjfyd -wnUSqHylJwh6WCIEh+HXsn4ndfNWSN/fDqvi5I10V1j6Zos7yqQf8qAezUAm6eSq -hLgZz0odq9DsO4HHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFK5mVIJ2D+kI0kk -sxnW4ibWFjzlYFYPYrZg+2JFIVTbKBg1YzyhuIKm0uztqRxQq5iLn/C/uponHoqF -7KDQI37KAJIQdgSva+mEuO9bZAXg/eegail2hN6np7HjOKlPu23s40dAbFrbcOWP -VbsBEPDP0HLv6OgbQWzNlE9HO1b7pX6ozk3q4ULO7IR85P6OHYsBBThL+qsOTzg/ -gVknuB9+n9hgNqZcAcXBLDetOM9aEmYJCGk0enYP5UGLYpseE+rTXFbRuHTPr1o6 -e8BetiSWS/wcrV4ZF5qr9NiYt5eD6JzTB5Rn5awxxj0FwMtrBu003lLQUWxsuTzz -35/RLY4= ------END CERTIFICATE----- - diff --git a/test/integration/targets/win_certificate_store/files/subj-key.pem b/test/integration/targets/win_certificate_store/files/subj-key.pem deleted file mode 100644 index 51a150afe6..0000000000 --- a/test/integration/targets/win_certificate_store/files/subj-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA7M6nRUqNxpVT9cVJzeG0j6xURYjpfzKrqdGZ+VCSVEfcC50Q -/ji3Ku5Cop+oWKqM0ru3AvgZ1kKKu7xkkjVar+wahTMMxibfSAVEL9FKiEJAP3bl -HSnQIjJ9j0EbDQ55FhG04+MbIrSLVTb/OHAxtJZGQWMk4H8mZWS2VqZZKVEJK2Ya -BQnpGUSfjg66jVt1uetK6zlCIfh4kHgaqHGrejncYCAgaqVIfBFaNYoWtw14xjdP -KubrYOoJmyJdlQWlSY38ncJ1Eqh8pScIelgiBIfh17J+J3XzVkjf3w6r4uSNdFdY -+maLO8qkH/KgHs1AJunkqoS4Gc9KHavQ7DuBxwIDAQABAoIBAQDfjqBfS+jYZrUi -uqPYV5IMaNYN5xj4Wi+xXA0OT0A1jLlxxU/7kDNrtg72U9+sBSZ483nstag+nAc5 -ALu5Q+FfX3gR84XFs4DrDv22XtEMHe9leqsFgynYfu4GRaJyCw3JBeJNmWNOuj8n -rYn4EAL8xzmAFUcFIURwSEnTN6vI0cS09nQukz+9CIBuGr7TPMET8YlATDJcH+Ua -EGZ9MAFXdKF6adC2nrCVBDNr8mUEpK1XdQcPH2bvcTuZ3Jj5AF2rOrcHq4FZUm97 -8PaMH6Sarxhwl+ycwrKbU5aEzUYTk67k0V6m9lyvH9z3O3Y84Tr3cZZ5WxdnG6Ri -72MFlfgRAoGBAP8wA+KWJ/ttmEXAoSX4J2fPl7X1RhR+1zPNdLY7iX0uNstL8IFH -vUN9JHi1Tr7llav+2bUTOu2EMDVmDWZH0s/qKOn+GmqIQLp0441fVAiamTcgwGKE -Wwsu4dg10IJ9akHIIbrILT0CvRcIRf67EYLBj3ZwfR+wF1ncefbsxWA9AoGBAO2P -qGMn+yrIi5DZF23x6iD2Y7bIdlUmqIqwb99XhW+3YJmRuh1EuN6XP2bIveRa9xvm -Q7bbcQM0Yv2c7eTyxpzz2I4bmnccVbs6M1VhtkyQEy5+X5yOl9wnitaaUrbWFy/w -kDPuISjLl3xDlxd6dbjf70fkG5oogx5c5toEyWZTAoGAK1CHGErMdozfr9dGgx9f -8Or3oVcEki4FcTGKgfQRHkJd4pv9MrRul6oCKsr7lsN5aDxVz7p34iDx3d54n8fJ -LKleUHllGngOJJf6l+B6bwtuvkC85vv4SCmpA/3+amfHRWsm7oFTzGtOlT4+Q0KV -clBQfZYSZvKIxCP8P8ForzECgYEAjDOad1qjOy68X7Ifx71cJjQDyV4pqDt2gNN8 -Ut1+XN5m3ntI0fk6+fNdcbXLjDe7WvXcxNBhtDh4q6CwLcyyNvMavVPBJ8bLOgIx -RZSzWCA3kdr3ZpgpO78Ci4DsjAdyC9L36A4D9+Wf87CYPT0CuSdAOrd/Ks36BDNj -8wucKQ0CgYAaRwQ18nkemrpQ/+EQgEWnWfqgB+6T4ygZ4ZTym0FAtG7CdLxvCi8V -toyn+zi+yFTRFXHDmvg9HLIIMK/hRQjgc8Ns5nDwgQlGwCZTvjVbD4anCr1IWuky -owvxKWsHseNilKrnAk2maQxrrrpSk8QWrp2CFw04LsWGTxtFvstBmg== ------END RSA PRIVATE KEY----- - diff --git a/test/integration/targets/win_certificate_store/meta/main.yml b/test/integration/targets/win_certificate_store/meta/main.yml deleted file mode 100644 index bdea853d75..0000000000 --- a/test/integration/targets/win_certificate_store/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- prepare_win_tests diff --git a/test/integration/targets/win_certificate_store/tasks/main.yml b/test/integration/targets/win_certificate_store/tasks/main.yml deleted file mode 100644 index 86bf3baedd..0000000000 --- a/test/integration/targets/win_certificate_store/tasks/main.yml +++ /dev/null @@ -1,121 +0,0 @@ -### keys in files/ have been generated with -# generate root private key -# openssl genrsa -aes256 -out enckey.pem 2048 -# openssl rsa -in envkey.pem -out root-key.pem -# -# generate root certificate -# openssl req -x509 -key root-key.pem -days 24855 -out root-vert.pem -subj "/CN=root.ansible.com/C=US" -# -# generate subject private key -# openssl genrsa -aes256 -out enckey.pem 2048 -# openssl rsa -in enckey.pem -out subj-key.pem -# -# generate subject certificate -# openssl req -new -key subj-key.pem -out cert.csr -subj "/CN=subject.ansible.com/C=US" -# openssl x509 -req -in cert.csr -CA root-cert.pem -CAkey root-key.pem -CAcreateserial -out subj-cert.pem -days 24855 -### ---- -- name: ensure test dir is present - win_file: - path: '{{win_cert_dir}}\exported' - state: directory - -- name: ensure certificates are removed from store before test - win_certificate_store: - thumbprint: '{{item}}' - state: absent - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - -- name: ensure certificates are removed from custom store before test - win_certificate_store: - thumbprint: '{{item}}' - state: absent - store_name: TrustedPeople - store_location: CurrentUser - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - -# these files are created on the fly so we don't store binary in the git repo -- name: create PKCS12 without password - command: 'openssl pkcs12 -export -out subj-cert-without-pass.pfx -inkey subj-key.pem -in subj-cert.pem -passout pass:' - args: - chdir: '{{role_path}}/files' - delegate_to: localhost - run_once: yes - -- name: create PKCS12 with password - command: 'openssl pkcs12 -export -out subj-cert-with-pass.pfx -inkey subj-key.pem -in subj-cert.pem -passout pass:{{key_password}}' - args: - chdir: '{{role_path}}/files' - delegate_to: localhost - run_once: yes - -- name: create DER encoded cert - command: openssl x509 -outform der -in subj-cert.pem -out subj-cert.cer - args: - chdir: '{{role_path}}/files' - delegate_to: localhost - run_once: yes - -- name: create PEM encoded PKCS7 file - command: openssl crl2pkcs7 -nocrl -certfile subj-cert.pem -certfile root-cert.pem -out chain.pem - args: - chdir: '{{role_path}}/files' - delegate_to: localhost - run_once: yes - -- name: create DER encoded PKCS7 file - command: openssl crl2pkcs7 -nocrl -certfile subj-cert.pem -certfile root-cert.pem -out chain.p7b -outform der - args: - chdir: '{{role_path}}/files' - delegate_to: localhost - run_once: yes - -- name: copy across test cert files - win_copy: - src: files/ - dest: '{{win_cert_dir}}' - -- block: - - name: run tests - include_tasks: test.yml - - always: - - name: ensure generated keys are deleted - file: - path: '{{role_path}}/files/{{item}}' - state: absent - delegate_to: localhost - run_once: yes - with_items: - - subj-cert-with-pass.pfx - - subj-cert-without-pass.pfx - - subj-cert.cer - - chain.pem - - chain.p7b - - - name: ensure certificates are removed from store after test - win_certificate_store: - thumbprint: '{{item}}' - state: absent - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - - - name: ensure certificates are removed from custom store after test - win_certificate_store: - thumbprint: '{{item}}' - state: absent - store_name: TrustedPeople - store_location: CurrentUser - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - - - name: ensure test dir is deleted - win_file: - path: '{{win_cert_dir}}' - state: absent diff --git a/test/integration/targets/win_certificate_store/tasks/test.yml b/test/integration/targets/win_certificate_store/tasks/test.yml deleted file mode 100644 index 05e6717162..0000000000 --- a/test/integration/targets/win_certificate_store/tasks/test.yml +++ /dev/null @@ -1,801 +0,0 @@ ---- -- name: fail with invalid store location - win_certificate_store: - state: present - path: '{{win_cert_dir}}\subj-cert.pem' - store_location: FakeLocation - register: fail_fake_location - failed_when: "fail_fake_location.msg != 'value of store_location must be one of: CurrentUser, LocalMachine. Got no match for: FakeLocation'" - -- name: fail with invalid store name - win_certificate_store: - state: present - path: '{{win_cert_dir}}\subj-cert.pem' - store_name: FakeName - register: fail_fake_name - failed_when: "fail_fake_name.msg != 'value of store_name must be one of: AddressBook, AuthRoot, CertificateAuthority, Disallowed, My, Root, TrustedPeople, TrustedPublisher. Got no match for: FakeName'" - -- name: fail when state=present and no path is set - win_certificate_store: - state: present - register: fail_present_no_path - failed_when: "fail_present_no_path.msg != 'state is present but all of the following are missing: path'" - -- name: fail when state=exported and no path is set - win_certificate_store: - state: exported - thumbprint: ABC - register: fail_export_no_path - failed_when: "fail_export_no_path.msg != 'state is exported but all of the following are missing: path'" - -- name: fail when state=exported and no thumbprint is set - win_certificate_store: - state: exported - path: '{{win_cert_dir}}' - register: fail_export_no_thumbprint - failed_when: "fail_export_no_thumbprint.msg != 'state is exported but all of the following are missing: thumbprint'" - -- name: fail to export thumbprint when path is a dir - win_certificate_store: - state: exported - thumbprint: '{{subj_thumbprint}}' - path: '{{win_cert_dir}}' - register: fail_export_path_is_dir - failed_when: fail_export_path_is_dir.msg != "Cannot export cert to path '" + win_cert_dir + "' as it is a directory" - -- name: fail when state=absent and not path or thumbprint is set - win_certificate_store: - state: absent - register: fail_absent_no_path_or_thumbprint - failed_when: "fail_absent_no_path_or_thumbprint.msg != 'state is absent but any of the following are missing: path, thumbprint'" - -- name: import pem certificate (check) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.pem' - state: present - register: import_pem_check - check_mode: yes - -- name: get result of import pem certificate (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pem_result_check - -- name: assert results of import pem certificate (check) - assert: - that: - - import_pem_check is changed - - import_pem_check.thumbprints == [subj_thumbprint] - - import_pem_result_check.stdout_lines[0] == "False" - -- name: import pem certificate - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.pem' - state: present - register: import_pem - -- name: get result of import pem certificate - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pem_result - -- name: assert results of import pem certificate - assert: - that: - - import_pem is changed - - import_pem.thumbprints == [subj_thumbprint] - - import_pem_result.stdout_lines[0] == "True" - -- name: import pem certificate (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.pem' - state: present - register: import_pem_again - -- name: assert results of import pem certificate (idempotent) - assert: - that: - - not import_pem_again is changed - -- name: remove certificate based on thumbprint (check) - win_certificate_store: - thumbprint: '{{subj_thumbprint}}' - state: absent - register: remove_thumbprint_check - check_mode: yes - -- name: get result of remove certificate based on thumbprint (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: remove_thumbprint_result_check - -- name: assert results of remove certificate based on thumbprint (check) - assert: - that: - - remove_thumbprint_check is changed - - remove_thumbprint_check.thumbprints == [subj_thumbprint] - - remove_thumbprint_result_check.stdout_lines[0] == "True" - -- name: remove certificate based on thumbprint - win_certificate_store: - thumbprint: '{{subj_thumbprint}}' - state: absent - register: remove_thumbprint - -- name: get result of remove certificate based on thumbprint - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: remove_thumbprint_result - -- name: assert results of remove certificate based on thumbprint - assert: - that: - - remove_thumbprint is changed - - remove_thumbprint.thumbprints == [subj_thumbprint] - - remove_thumbprint_result.stdout_lines[0] == "False" - -- name: remove certificate based on thumbprint (idempotent) - win_certificate_store: - thumbprint: '{{subj_thumbprint}}' - state: absent - register: remove_thumbprint_again - -- name: assert results of remove certificate based on thumbprint (idempotent) - assert: - that: - - not remove_thumbprint_again is changed - -- name: import der certificate (check) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: present - register: import_der_check - check_mode: yes - -- name: get result of import der certificate (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_der_result_check - -- name: assert results of import der certificate (check) - assert: - that: - - import_der_check is changed - - import_der_check.thumbprints == [subj_thumbprint] - - import_der_result_check.stdout_lines[0] == "False" - -- name: import der certificate - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: present - register: import_der - -- name: get result of import der certificate - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_der_result - -- name: assert results of import der certificate - assert: - that: - - import_der is changed - - import_der.thumbprints == [subj_thumbprint] - - import_der_result.stdout_lines[0] == "True" - -- name: import der certificate (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: present - register: import_der_again - -- name: assert results of import der certificate (idempotent) - assert: - that: - - not import_der_again is changed - -- name: remove certificate based on path (check) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: absent - register: remove_path_check - check_mode: yes - -- name: get result of remove certificate based on path (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: remove_path_result_check - -- name: assert results of remove certificate based on path (check) - assert: - that: - - remove_path_check is changed - - remove_path_check.thumbprints == [subj_thumbprint] - - remove_path_result_check.stdout_lines[0] == "True" - -- name: remove certificate based on path - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: absent - register: remove_path - -- name: get result of remove certificate based on path - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: remove_path_result - -- name: assert results of remove certificate based on path - assert: - that: - - remove_path is changed - - remove_path.thumbprints == [subj_thumbprint] - - remove_path_result.stdout_lines[0] == "False" - -- name: remove certificate based on path (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert.cer' - state: absent - register: remove_path_again - -- name: assert results of remove certificate based on path (idempotent) - assert: - that: - - not remove_path_again is changed - -- name: import PEM encoded p7b chain (check) - win_certificate_store: - path: '{{win_cert_dir}}\chain.pem' - state: present - register: import_pem_p7b_check - check_mode: yes - -- name: get result of subj in p7b chain (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pem_p7b_subj_result_check - -- name: get result of root in p7b chain (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false } - register: import_pem_p7b_root_result_check - -- name: assert results of import PEM encoded p7b chain (check) - assert: - that: - - import_pem_p7b_check is changed - - import_pem_p7b_check.thumbprints|count == 2 - - subj_thumbprint in import_pem_p7b_check.thumbprints - - root_thumbprint in import_pem_p7b_check.thumbprints - - import_pem_p7b_subj_result_check.stdout_lines[0] == "False" - - import_pem_p7b_root_result_check.stdout_lines[0] == "False" - -- name: import PEM encoded p7b chain - win_certificate_store: - path: '{{win_cert_dir}}\chain.pem' - state: present - register: import_pem_p7b - -- name: get result of subj in p7b chain - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pem_p7b_subj_result - -- name: get result of root in p7b chain - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false } - register: import_pem_p7b_root_result - -- name: assert results of import PEM encoded p7b chain - assert: - that: - - import_pem_p7b is changed - - import_pem_p7b.thumbprints|count == 2 - - subj_thumbprint in import_pem_p7b.thumbprints - - root_thumbprint in import_pem_p7b.thumbprints - - import_pem_p7b_subj_result.stdout_lines[0] == "True" - - import_pem_p7b_root_result.stdout_lines[0] == "True" - -- name: import PEM encoded p7b chain (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\chain.pem' - state: present - register: import_pem_p7b_again - -- name: assert results of import PEM encoded p7b chain (idempotent) - assert: - that: - - not import_pem_p7b_again is changed - -- name: remove p7b chain certs - win_certificate_store: - thumbprint: '{{item}}' - state: absent - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - -- name: import DER encoded p7b chain into custom store (check) - win_certificate_store: - path: '{{win_cert_dir}}\chain.p7b' - state: present - store_name: TrustedPeople - store_location: CurrentUser - register: import_der_p7b_check - check_mode: yes - -- name: get result of subj in p7b chain in custom store (check) - win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_der_p7b_subj_result_check - -- name: get result of root in p7b chain in custom store (check) - win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false } - register: import_der_p7b_root_result_check - -- name: assert results of import DER encoded p7b chain into custom store (check) - assert: - that: - - import_der_p7b_check is changed - - import_der_p7b_check.thumbprints|count == 2 - - subj_thumbprint in import_der_p7b_check.thumbprints - - root_thumbprint in import_der_p7b_check.thumbprints - - import_der_p7b_subj_result_check.stdout_lines[0] == "False" - - import_der_p7b_root_result_check.stdout_lines[0] == "False" - -- name: import DER encoded p7b chain into custom store - win_certificate_store: - path: '{{win_cert_dir}}\chain.p7b' - state: present - store_name: TrustedPeople - store_location: CurrentUser - register: import_der_p7b - -- name: get result of subj in p7b chain in custom store - win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_der_p7b_subj_result - -- name: get result of root in p7b chain in custom store - win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false } - register: import_der_p7b_root_result - -- name: assert results of import DER encoded p7b chain into custom store - assert: - that: - - import_der_p7b is changed - - import_der_p7b.thumbprints|count == 2 - - subj_thumbprint in import_der_p7b.thumbprints - - root_thumbprint in import_der_p7b.thumbprints - - import_der_p7b_root_result.stdout_lines[0] == "True" - - import_der_p7b_root_result.stdout_lines[0] == "True" - -- name: import DER encoded p7b chain into custom store (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\chain.p7b' - state: present - store_name: TrustedPeople - store_location: CurrentUser - register: import_der_p7b_again - -- name: assert results of import DER encoded p7b chain into custom store (idempotent) - assert: - that: - - not import_der_p7b_again is changed - -- name: remove p7b chain certs from custom store - win_certificate_store: - thumbprint: '{{item}}' - state: absent - store_name: TrustedPeople - store_location: CurrentUser - with_items: - - '{{subj_thumbprint}}' - - '{{root_thumbprint}}' - -- name: import pfx without password and non exportable (check) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-without-pass.pfx' - state: present - key_exportable: no - vars: &become_vars - ansible_become: yes - ansible_become_method: runas - ansible_become_user: '{{ansible_user}}' - ansible_become_pass: '{{ansible_password}}' - register: import_pfx_without_pass_check - check_mode: yes - -- name: get results of import pfx without password and non exportable (check) - win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pfx_without_pass_result_check - -- name: assert results of import pfx without password and non exportable (check) - assert: - that: - - import_pfx_without_pass_check is changed - - import_pfx_without_pass_check.thumbprints == [subj_thumbprint] - - import_pfx_without_pass_result_check.stdout_lines[0] == "False" - -- name: import pfx without password and non exportable - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-without-pass.pfx' - state: present - key_exportable: no - vars: *become_vars - register: import_pfx_without_pass - -- name: get results of import pfx without password and non exportable - win_shell: (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }).PrivateKey.CspKeyContainerInfo.Exportable - vars: *become_vars - register: import_pfx_without_pass_result - -- name: assert results of import pfx without password and non exportable - assert: - that: - - import_pfx_without_pass is changed - - import_pfx_without_pass.thumbprints == [subj_thumbprint] - - import_pfx_without_pass_result.stdout_lines[0] == "False" - -- name: import pfx without password and non exportable (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-without-pass.pfx' - state: present - key_exportable: no - vars: *become_vars - register: import_pfx_without_pass_again - -- name: assert results of import pfx without password and non exportable (idempotent) - assert: - that: - - not import_pfx_without_pass_again is changed - -- name: fail import pfx with password and none set - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-with-pass.pfx' - state: present - store_location: CurrentUser - store_name: TrustedPeople - register: fail_import_pfx_with_password - failed_when: "'Failed to load cert from file' not in fail_import_pfx_with_password.msg and 'The specified network password is not correct' not in fail_import_pfx_with_password.msg" - -- name: import pfx with password (check) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-with-pass.pfx' - state: present - password: '{{key_password}}' - store_location: CurrentUser - store_name: TrustedPeople - register: import_pfx_with_pass_check - vars: *become_vars - check_mode: yes - -- name: get results of import pfx with password (check) - win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false } - register: import_pfx_with_pass_result_check - -- name: assert results of import pfx with password (check) - assert: - that: - - import_pfx_with_pass_check is changed - - import_pfx_with_pass_check.thumbprints == [subj_thumbprint] - - import_pfx_with_pass_result_check.stdout_lines[0] == "False" - -- name: import pfx with password - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-with-pass.pfx' - state: present - password: '{{key_password}}' - store_location: CurrentUser - store_name: TrustedPeople - vars: *become_vars - register: import_pfx_with_pass - -- name: get results of import pfx with password - win_shell: (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }).PrivateKey.CspKeyContainerInfo.Exportable - vars: *become_vars - register: import_pfx_with_pass_result - -- name: assert results of import pfx with password - assert: - that: - - import_pfx_with_pass is changed - - import_pfx_with_pass.thumbprints == [subj_thumbprint] - - import_pfx_with_pass_result.stdout_lines[0] == "True" - -- name: import pfx with password (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\subj-cert-with-pass.pfx' - state: present - password: '{{key_password}}' - store_location: CurrentUser - store_name: TrustedPeople - vars: *become_vars - register: import_pfx_with_pass_again - -- name: assert results of import pfx with password (idempotent) - assert: - that: - - not import_pfx_with_pass_again is changed - -- name: import root cert for export tests - win_certificate_store: - path: '{{win_cert_dir}}\root-cert.pem' - state: present - -- name: export cert as pem (check) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.pem' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pem - register: export_pem_check - check_mode: yes - -- name: get result of export cert as pem (check) - win_stat: - path: '{{win_cert_dir}}\exported\cert.pem' - register: export_pem_result_check - -- name: assert results of export cert as pem (check) - assert: - that: - - export_pem_check is changed - - export_pem_check.thumbprints == [subj_thumbprint] - - export_pem_result_check.stat.exists == False - -- name: export cert as pem - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.pem' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pem - register: export_pem - -- name: get result of export cert as pem - win_stat: - path: '{{win_cert_dir}}\exported\cert.pem' - register: export_pem_result - -- name: assert results of export cert as pem - assert: - that: - - export_pem is changed - - export_pem.thumbprints == [subj_thumbprint] - - export_pem_result.stat.checksum == '1ebf5467d18230e9f611940a74d12f1d0bc819b7' - -- name: export cert as pem (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.pem' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pem - register: export_pem_again - -- name: assert results of export cert as pem - assert: - that: - - not export_pem_again is changed - -- name: export cert as der (check) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.cer' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: der - register: export_der_check - check_mode: yes - -- name: get result of export cert as der (check) - win_stat: - path: '{{win_cert_dir}}\exported\cert.cer' - register: export_der_result_check - -- name: assert results of export cert as der (check) - assert: - that: - - export_der_check is changed - - export_der_check.thumbprints == [subj_thumbprint] - - export_der_result_check.stat.exists == False - -- name: export cert as der - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.cer' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: der - register: export_der - -- name: get result of export cert as der - win_stat: - path: '{{win_cert_dir}}\exported\cert.cer' - register: export_der_result - -- name: assert results of export cert as der - assert: - that: - - export_der is changed - - export_der.thumbprints == [subj_thumbprint] - - export_der_result.stat.checksum == 'bd7af104cf1872bdb518d95c9534ea941665fd27' - -- name: export cert as der (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.cer' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: der - register: export_der_again - -- name: assert results of export cert as der - assert: - that: - - not export_der_again is changed - -- name: export cert as der replacing pem - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.pem' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: der - register: export_der_over_pem - -- name: get result of export cert as der replacing pem - win_stat: - path: '{{win_cert_dir}}\exported\cert.pem' - register: export_der_over_pem_result - -- name: assert results of export cert as der replacing pem - assert: - that: - - export_der_over_pem is changed - - export_der_over_pem.thumbprints == [subj_thumbprint] - - export_der_over_pem_result.stat.checksum == 'bd7af104cf1872bdb518d95c9534ea941665fd27' - -- name: export cert as pem replacing der - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert.cer' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pem - register: export_pem_over_der - -- name: get result of export cert as pem replacing der - win_stat: - path: '{{win_cert_dir}}\exported\cert.cer' - register: export_pem_over_der_result - -- name: assert results of export cert as pem replacing der - assert: - that: - - export_pem_over_der is changed - - export_pem_over_der.thumbprints == [subj_thumbprint] - - export_pem_over_der_result.stat.checksum == '1ebf5467d18230e9f611940a74d12f1d0bc819b7' - -- name: export cert with key and password as pfx (check) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - password: '{{key_password}}' - register: export_pfx_with_pass_check - vars: *become_vars - check_mode: yes - -- name: get result of export cert with key and password as pfx (check) - win_stat: - path: '{{win_cert_dir}}\exported\cert-pass.pfx' - register: export_pfx_with_pass_result_check - -- name: assert results of export cert with key and password as pfx (check) - assert: - that: - - export_pfx_with_pass_check is changed - - export_pfx_with_pass_check.thumbprints == [subj_thumbprint] - - export_pfx_with_pass_result_check.stat.exists == False - -- name: export cert with key and password as pfx - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - password: '{{key_password}}' - vars: *become_vars - register: export_pfx_with_pass - -- name: get result of export cert with key and password as pfx - win_shell: | - $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 - $cert.Import("{{win_cert_dir}}\exported\cert-pass.pfx", "{{key_password}}", 0) - $cert.HasPrivateKey - vars: *become_vars - register: export_pfx_with_pass_result - -- name: assert results of export cert with key and password as pfx - assert: - that: - - export_pfx_with_pass is changed - - export_pfx_with_pass.thumbprints == [subj_thumbprint] - - export_pfx_with_pass_result.stdout_lines[0] == "True" - -- name: export cert with key and password as pfx (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - password: '{{key_password}}' - vars: *become_vars - register: export_pfx_with_pass_again - -- name: assert results of export cert with key and password as pfx (idempotent) - assert: - that: - - not export_pfx_with_pass_again is changed - -- name: export cert with key without password as pfx (check) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-without-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - vars: *become_vars - register: export_pfx_without_pass_check - check_mode: yes - -- name: get result of export cert with key without password as pfx (check) - win_stat: - path: '{{win_cert_dir}}\exported\cert-without-pass.pfx' - register: export_pfx_without_pass_result_check - -- name: assert results of export cert with key without password as pfx (check) - assert: - that: - - export_pfx_without_pass_check is changed - - export_pfx_without_pass_check.thumbprints == [subj_thumbprint] - - export_pfx_without_pass_result_check.stat.exists == False - -- name: export cert with key without password as pfx - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-without-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - vars: *become_vars - register: export_pfx_without_pass - -- name: get result of export cert with key without password as pfx - win_shell: | - $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 - $cert.Import("{{win_cert_dir}}\exported\cert-without-pass.pfx", $null, 0) - $cert.HasPrivateKey - vars: *become_vars - register: export_pfx_without_pass_result - -- name: assert results of export cert with key without password as pfx - assert: - that: - - export_pfx_without_pass is changed - - export_pfx_without_pass.thumbprints == [subj_thumbprint] - - export_pfx_without_pass_result.stdout_lines[0] == "True" - -- name: export cert with key without password as pfx (idempotent) - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-without-pass.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - store_location: CurrentUser - store_name: TrustedPeople - vars: *become_vars - register: export_pfx_without_pass_again - -- name: assert results of export cert with key without password as pfx (idempotent) - assert: - that: - - not export_pfx_without_pass_again is changed - -- name: fail to export cert with key as pfx when not marked as exportable - win_certificate_store: - path: '{{win_cert_dir}}\exported\cert-fail.pfx' - thumbprint: '{{subj_thumbprint}}' - state: exported - file_type: pkcs12 - vars: *become_vars - register: fail_export_non_exportable - failed_when: fail_export_non_exportable.msg != 'Cannot export cert with key as PKCS12 when the key is not marked as exportable or not accessible by the current user' diff --git a/test/integration/targets/win_command/aliases b/test/integration/targets/win_command/aliases deleted file mode 100644 index 4cd27b3cb2..0000000000 --- a/test/integration/targets/win_command/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_command/files/crt_setmode.c b/test/integration/targets/win_command/files/crt_setmode.c deleted file mode 100644 index 4067e71778..0000000000 --- a/test/integration/targets/win_command/files/crt_setmode.c +++ /dev/null @@ -1,15 +0,0 @@ -// crt_setmode.c -// This program uses _setmode to change -// stdout from text mode to binary mode. -// Used to test output_encoding_override for win_command. - -#include <stdio.h> -#include <fcntl.h> -#include <io.h> - -int main(void) -{ - _setmode(_fileno(stdout), _O_BINARY); - // Translates to 日本 in shift_jis - printf("\x93\xFa\x96\x7B - Japan"); -} diff --git a/test/integration/targets/win_command/tasks/main.yml b/test/integration/targets/win_command/tasks/main.yml deleted file mode 100644 index bf72ffe21f..0000000000 --- a/test/integration/targets/win_command/tasks/main.yml +++ /dev/null @@ -1,255 +0,0 @@ -- name: execute a command - win_command: whoami /groups - register: cmdout - -- name: validate result - assert: - that: - - cmdout is successful - - cmdout is changed - - cmdout.cmd == 'whoami /groups' - - cmdout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.rc == 0 - - cmdout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.stderr == "" - - cmdout.stdout is search('GROUP INFORMATION') - - '"GROUP INFORMATION" in cmdout.stdout_lines' - -- name: execute something nonexistent - win_command: bogus_command1234 - register: cmdout - ignore_errors: true - -- name: validate result - assert: - that: - - cmdout is failed - - cmdout is not changed - - cmdout.cmd == 'bogus_command1234' - - cmdout.rc == 2 - - "\"Could not find file 'bogus_command1234.exe'.\" in cmdout.msg" - -- name: execute something with error output - win_command: cmd /c "echo some output & echo some error 1>&2" - register: cmdout - -- name: validate result - assert: - that: - - cmdout is successful - - cmdout is changed - - cmdout.cmd == 'cmd /c "echo some output & echo some error 1>&2"' - - cmdout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.rc == 0 - - cmdout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - cmdout.stderr is search('some error') - - cmdout.stdout == "some output \r\n" - - cmdout.stdout_lines == ["some output "] - -- name: ensure test file is absent - win_file: - path: c:\testfile.txt - state: absent - -- name: run with creates, should create - win_command: cmd /c "echo $null >> c:\testfile.txt" - args: - creates: c:\testfile.txt - register: cmdout - -- name: validate result - assert: - that: - - cmdout is successful - - cmdout is changed - -- name: run again with creates, should skip - win_command: cmd /c "echo $null >> c:\testfile.txt" - args: - creates: c:\testfile.txt - register: cmdout - -- name: validate result - assert: - that: - - cmdout is skipped - - cmdout.msg is search('exists') - -- name: get path of pagefile - win_shell: | - $pagefile = $null - $cs = Get-CimInstance -ClassName Win32_ComputerSystem - if ($cs.AutomaticManagedPagefile) { - $pagefile = "$($env:SystemRoot.Substring(0, 1)):\pagefile.sys" - } else { - $pf = Get-CimInstance -ClassName Win32_PageFileSetting - if ($pf -ne $null) { - $pagefile = $pf[0].Name - } - } - $pagefile - register: pagefile_path - -- name: test creates with hidden system file, should skip - win_command: echo no - args: - creates: '{{pagefile_path.stdout_lines[0]}}' - register: cmdout - when: pagefile_path.stdout_lines|count != 0 - -- name: validate result - assert: - that: - - cmdout is skipped - - cmdout.msg is search('exists') - when: pagefile_path.stdout_lines|count != 0 - -- name: ensure testfile is still present - win_stat: - path: c:\testfile.txt - register: statout - -- name: validate result - assert: - that: - - statout.stat.exists == true - -- name: run with removes, should remove - win_command: cmd /c "del c:\testfile.txt" - args: - removes: c:\testfile.txt - register: cmdout - -- name: validate result - assert: - that: - - cmdout is successful - - cmdout is changed - -- name: run again with removes, should skip - win_command: cmd /c "del c:\testfile.txt" - args: - removes: c:\testfile.txt - register: cmdout - -- name: validate result - assert: - that: - - cmdout is skipped - - cmdout.msg is search('does not exist') - -- name: run something with known nonzero exit code - win_command: cmd /c "exit 254" - register: cmdout - ignore_errors: true - -- name: validate result - assert: - that: - - cmdout is failed - - cmdout.failed == True # check the failure key explicitly, since failed does magic with RC - - cmdout.rc == 254 - -- name: interleave large writes between stdout/stderr (check for buffer consumption deadlock) - win_command: powershell /c "$ba = New-Object byte[] 4096; (New-Object System.Random 32).NextBytes($ba); $text = [Convert]::ToBase64String($ba); Write-Output startout; Write-Error starterror; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Output doneout Write-Error doneerror" - register: cmdout - -- name: ensure that the entirety of both streams were read - assert: - that: - - cmdout.stdout is search("startout") - - cmdout.stdout is search("doneout") - - cmdout.stderr is search("starterror") - - cmdout.stderr is search("doneerror") - -- name: create testing folder for argv binary - win_file: - path: C:\ansible testing - state: directory - -- name: download binary the outputs argv to stdout - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_module_utils/PrintArgv.exe - dest: C:\ansible testing\PrintArgv.exe - -- name: call argv binary with absolute path - win_command: '"C:\ansible testing\PrintArgv.exe" arg1 "arg 2" C:\path\arg "\"quoted arg\""' - register: cmdout - -- name: assert call to argv binary with absolute path - assert: - that: - - cmdout is changed - - cmdout.rc == 0 - - cmdout.stdout_lines[0] == 'arg1' - - cmdout.stdout_lines[1] == 'arg 2' - - cmdout.stdout_lines[2] == 'C:\\path\\arg' - - cmdout.stdout_lines[3] == '"quoted arg"' - -- name: call argv binary with relative path - win_command: 'PrintArgv.exe C:\path\end\slash\ ADDLOCAL="msi,example" two\\slashes' - args: - chdir: C:\ansible testing - register: cmdout - -- name: assert call to argv binary with relative path - assert: - that: - - cmdout is changed - - cmdout.rc == 0 - - cmdout.stdout_lines[0] == 'C:\\path\\end\\slash\\' - - cmdout.stdout_lines[1] == 'ADDLOCAL=msi,example' - - cmdout.stdout_lines[2] == 'two\\\\slashes' - -- name: download binary that output shift_jis chars to console - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_command/OutputEncodingOverride.exe - dest: C:\ansible testing\OutputEncodingOverride.exe - -- name: call binary with shift_jis output encoding override - win_command: '"C:\ansible testing\OutputEncodingOverride.exe"' - args: - output_encoding_override: shift_jis - register: cmdout - -- name: assert call to binary with shift_jis output - assert: - that: - - cmdout is changed - - cmdout.rc == 0 - - cmdout.stdout_lines[0] == '日本 - Japan' - -- name: remove testing folder - win_file: - path: C:\ansible testing - state: absent - -- name: run stdin test - win_command: powershell.exe - - args: - stdin: Write-Host "some input" - register: cmdout - -- name: assert run stdin test - assert: - that: - - cmdout is changed - - cmdout.rc == 0 - - cmdout.stdout_lines|count == 1 - - cmdout.stdout_lines[0] == "some input" - - cmdout.stderr == "" - -- name: echo some non ascii characters - win_command: cmd.exe /c echo über den Fußgängerübergang gehen - register: nonascii_output - -- name: assert echo some non ascii characters - assert: - that: - - nonascii_output is changed - - nonascii_output.rc == 0 - - nonascii_output.stdout_lines|count == 1 - - nonascii_output.stdout_lines[0] == 'über den Fußgängerübergang gehen' - - nonascii_output.stderr == '' diff --git a/test/integration/targets/win_copy/aliases b/test/integration/targets/win_copy/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_copy/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_copy/defaults/main.yml b/test/integration/targets/win_copy/defaults/main.yml deleted file mode 100644 index 5d8a1d2351..0000000000 --- a/test/integration/targets/win_copy/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_win_copy_path: C:\ansible\win_copy .ÅÑŚÌβŁÈ [$!@^&test(;)] diff --git a/test/integration/targets/win_copy/files-different/vault/folder/nested-vault-file b/test/integration/targets/win_copy/files-different/vault/folder/nested-vault-file deleted file mode 100644 index d8d1549874..0000000000 --- a/test/integration/targets/win_copy/files-different/vault/folder/nested-vault-file +++ /dev/null @@ -1,6 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -65653164323866373138353632323531393664393563633665373635623763353561386431373366 -3232353263363034313136663062623336663463373966320a333763323032646463386432626161 -36386330356637666362396661653935653064623038333031653335626164376465353235303636 -3335616231663838620a303632343938326538656233393562303162343261383465623261646664 -33613932343461626339333832363930303962633364303736376634396364643861 diff --git a/test/integration/targets/win_copy/files-different/vault/readme.txt b/test/integration/targets/win_copy/files-different/vault/readme.txt deleted file mode 100644 index dae883b5ee..0000000000 --- a/test/integration/targets/win_copy/files-different/vault/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -This directory contains some files that have been encrypted with ansible-vault. - -This is to test out the decrypt parameter in win_copy. - -The password is: password diff --git a/test/integration/targets/win_copy/files-different/vault/vault-file b/test/integration/targets/win_copy/files-different/vault/vault-file deleted file mode 100644 index 2fff7619a7..0000000000 --- a/test/integration/targets/win_copy/files-different/vault/vault-file +++ /dev/null @@ -1,6 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -30353665333635633433356261616636356130386330363962386533303566313463383734373532 -3933643234323638623939613462346361313431363939370a303532656338353035346661353965 -34656231633238396361393131623834316262306533663838336362366137306562646561383766 -6363373965633337640a373666336461613337346131353564383134326139616561393664663563 -3431 diff --git a/test/integration/targets/win_copy/files/empty.txt b/test/integration/targets/win_copy/files/empty.txt deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/integration/targets/win_copy/files/empty.txt +++ /dev/null diff --git a/test/integration/targets/win_copy/files/foo.txt b/test/integration/targets/win_copy/files/foo.txt deleted file mode 100644 index 7c6ded14ec..0000000000 --- a/test/integration/targets/win_copy/files/foo.txt +++ /dev/null @@ -1 +0,0 @@ -foo.txt diff --git a/test/integration/targets/win_copy/files/subdir/bar.txt b/test/integration/targets/win_copy/files/subdir/bar.txt deleted file mode 100644 index 76018072e0..0000000000 --- a/test/integration/targets/win_copy/files/subdir/bar.txt +++ /dev/null @@ -1 +0,0 @@ -baz diff --git a/test/integration/targets/win_copy/files/subdir/subdir2/baz.txt b/test/integration/targets/win_copy/files/subdir/subdir2/baz.txt deleted file mode 100644 index 76018072e0..0000000000 --- a/test/integration/targets/win_copy/files/subdir/subdir2/baz.txt +++ /dev/null @@ -1 +0,0 @@ -baz diff --git a/test/integration/targets/win_copy/files/subdir/subdir2/subdir3/subdir4/qux.txt b/test/integration/targets/win_copy/files/subdir/subdir2/subdir3/subdir4/qux.txt deleted file mode 100644 index 78df5b06bd..0000000000 --- a/test/integration/targets/win_copy/files/subdir/subdir2/subdir3/subdir4/qux.txt +++ /dev/null @@ -1 +0,0 @@ -qux
\ No newline at end of file diff --git a/test/integration/targets/win_copy/tasks/main.yml b/test/integration/targets/win_copy/tasks/main.yml deleted file mode 100644 index b2ee103fd0..0000000000 --- a/test/integration/targets/win_copy/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: create empty folder - file: - path: '{{role_path}}/files/subdir/empty' - state: directory - delegate_to: localhost - -# removes the cached zip module from the previous task so we can replicate -# the below issue where win_copy would delete DEFAULT_LOCAL_TMP if it -# had permission to -# https://github.com/ansible/ansible/issues/35613 -- name: clear the local ansiballz cache - file: - path: "{{lookup('config', 'DEFAULT_LOCAL_TMP')}}/ansiballz_cache" - state: absent - delegate_to: localhost - -- name: create test folder - win_file: - path: '{{test_win_copy_path}}' - state: directory - -- block: - - name: run tests for local to remote - include_tasks: tests.yml - - - name: run tests for remote to remote - include_tasks: remote_tests.yml - - always: - - name: remove test folder - win_file: - path: '{{test_win_copy_path}}' - state: absent diff --git a/test/integration/targets/win_copy/tasks/remote_tests.yml b/test/integration/targets/win_copy/tasks/remote_tests.yml deleted file mode 100644 index 5abb50200b..0000000000 --- a/test/integration/targets/win_copy/tasks/remote_tests.yml +++ /dev/null @@ -1,471 +0,0 @@ ---- -- name: fail when source does not exist remote - win_copy: - src: fakesource - dest: fakedest - remote_src: yes - register: fail_remote_invalid_source - failed_when: "'it does not exist' not in fail_remote_invalid_source.msg" - -- name: setup source folder for remote tests - win_copy: - src: files/ - dest: '{{test_win_copy_path}}\source\' - -- name: setup remote failure tests - win_file: - path: '{{item.path}}' - state: '{{item.state}}' - with_items: - - { 'path': '{{test_win_copy_path}}\target\folder', 'state': 'directory' } - - { 'path': '{{test_win_copy_path}}\target\file', 'state': 'touch' } - - { 'path': '{{test_win_copy_path}}\target\subdir', 'state': 'touch' } - -- name: fail source is a file but dest is a folder - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\folder' - remote_src: yes - register: fail_remote_file_to_folder - failed_when: "'dest is already a folder' not in fail_remote_file_to_folder.msg" - -- name: fail source is a file but dest is a folder - win_copy: - src: '{{test_win_copy_path}}\source\' - dest: '{{test_win_copy_path}}\target\' - remote_src: yes - register: fail_remote_folder_to_file - failed_when: "'dest is already a file' not in fail_remote_folder_to_file.msg" - -- name: fail source is a file dest parent dir is also a file - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\file\foo.txt' - remote_src: yes - register: fail_remote_file_parent_dir_file - failed_when: "'is currently a file' not in fail_remote_file_parent_dir_file.msg" - -- name: fail source is a folder dest parent dir is also a file - win_copy: - src: '{{test_win_copy_path}}\source\subdir' - dest: '{{test_win_copy_path}}\target\file' - remote_src: yes - register: fail_remote_folder_parent_dir_file - failed_when: "'object at dest parent dir is not a folder' not in fail_remote_folder_parent_dir_file.msg" - -- name: fail to copy a remote file with parent dir that doesn't exist and filename is set - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\missing-dir\foo.txt' - remote_src: yes - register: fail_remote_missing_parent_dir - failed_when: "'does not exist' not in fail_remote_missing_parent_dir.msg" - -- name: remove target after remote failure tests - win_file: - path: '{{test_win_copy_path}}\target' - state: absent - -- name: create remote target after cleaning - win_file: - path: '{{test_win_copy_path}}\target' - state: directory - -- name: copy single file remote (check mode) - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\foo-target.txt' - remote_src: yes - register: remote_copy_file_check - check_mode: yes - -- name: get result of copy single file remote (check mode) - win_stat: - path: '{{test_win_copy_path}}\target\foo-target.txt' - register: remote_copy_file_actual_check - -- name: assert copy single file remote (check mode) - assert: - that: - - remote_copy_file_check is changed - - remote_copy_file_actual_check.stat.exists == False - -- name: copy single file remote - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\foo-target.txt' - remote_src: yes - register: remote_copy_file - -- name: get result of copy single file remote - win_stat: - path: '{{test_win_copy_path}}\target\foo-target.txt' - register: remote_copy_file_actual - -- name: assert copy single file remote - assert: - that: - - remote_copy_file is changed - - remote_copy_file.operation == 'file_copy' - - remote_copy_file.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - remote_copy_file.size == 8 - - remote_copy_file.original_basename == 'foo.txt' - - remote_copy_file_actual.stat.exists == True - - remote_copy_file_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: copy single file remote (idempotent) - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\foo-target.txt' - remote_src: yes - register: remote_copy_file_again - -- name: assert copy single file remote (idempotent) - assert: - that: - - remote_copy_file_again is not changed - -- name: copy single file into folder remote (check mode) - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\' - remote_src: yes - register: remote_copy_file_to_folder_check - check_mode: yes - -- name: get result of copy single file into folder remote (check mode) - win_stat: - path: '{{test_win_copy_path}}\target\foo.txt' - register: remote_copy_file_to_folder_actual_check - -- name: assert copy single file into folder remote (check mode) - assert: - that: - - remote_copy_file_to_folder_check is changed - - remote_copy_file_to_folder_actual_check.stat.exists == False - -- name: copy single file into folder remote - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\' - remote_src: yes - register: remote_copy_file_to_folder - -- name: get result of copy single file into folder remote - win_stat: - path: '{{test_win_copy_path}}\target\foo.txt' - register: remote_copy_file_to_folder_actual - -- name: assert copy single file into folder remote - assert: - that: - - remote_copy_file_to_folder is changed - - remote_copy_file_to_folder.operation == 'file_copy' - - remote_copy_file_to_folder.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - remote_copy_file_to_folder.size == 8 - - remote_copy_file_to_folder.original_basename == 'foo.txt' - - remote_copy_file_to_folder_actual.stat.exists == True - - remote_copy_file_to_folder_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: copy single file into folder remote (idempotent) - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\' - remote_src: yes - register: remote_copy_file_to_folder_again - -- name: assert copy single file into folder remote - assert: - that: - - remote_copy_file_to_folder_again is not changed - -- name: copy single file to missing folder (check mode) - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\missing\' - remote_src: yes - register: remote_copy_file_to_missing_folder_check - check_mode: yes - -- name: get result of copy single file to missing folder remote (check mode) - win_stat: - path: '{{test_win_copy_path}}\target\missing\foo.txt' - register: remote_copy_file_to_missing_folder_actual_check - -- name: assert copy single file to missing folder remote (check mode) - assert: - that: - - remote_copy_file_to_missing_folder_check is changed - - remote_copy_file_to_missing_folder_check.operation == 'file_copy' - - remote_copy_file_to_missing_folder_actual_check.stat.exists == False - -- name: copy single file to missing folder remote - win_copy: - src: '{{test_win_copy_path}}\source\foo.txt' - dest: '{{test_win_copy_path}}\target\missing\' - remote_src: yes - register: remote_copy_file_to_missing_folder - -- name: get result of copy single file to missing folder remote - win_stat: - path: '{{test_win_copy_path}}\target\missing\foo.txt' - register: remote_copy_file_to_missing_folder_actual - -- name: assert copy single file to missing folder remote - assert: - that: - - remote_copy_file_to_missing_folder is changed - - remote_copy_file_to_missing_folder.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - remote_copy_file_to_missing_folder.operation == 'file_copy' - - remote_copy_file_to_missing_folder.size == 8 - - remote_copy_file_to_missing_folder_actual.stat.exists == True - - remote_copy_file_to_missing_folder_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: clear target for folder to folder test - win_file: - path: '{{test_win_copy_path}}\target' - state: absent - -- name: copy folder to folder remote (check mode) - win_copy: - src: '{{test_win_copy_path}}\source' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_to_folder_check - check_mode: yes - -- name: get result of copy folder to folder remote (check mode) - win_stat: - path: '{{test_win_copy_path}}\target' - register: remote_copy_folder_to_folder_actual_check - -- name: assert copy folder to folder remote (check mode) - assert: - that: - - remote_copy_folder_to_folder_check is changed - - remote_copy_folder_to_folder_check.operation == 'folder_copy' - - remote_copy_folder_to_folder_actual_check.stat.exists == False - -- name: copy folder to folder remote - win_copy: - src: '{{test_win_copy_path}}\source' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_to_folder - -- name: get result of copy folder to folder remote - win_find: - paths: '{{test_win_copy_path}}\target' - recurse: yes - file_type: directory - register: remote_copy_folder_to_folder_actual - -- name: assert copy folder to folder remote - assert: - that: - - remote_copy_folder_to_folder is changed - - remote_copy_folder_to_folder.operation == 'folder_copy' - - remote_copy_folder_to_folder_actual.examined == 11 - - remote_copy_folder_to_folder_actual.matched == 6 - - remote_copy_folder_to_folder_actual.files[0].filename == 'source' - - remote_copy_folder_to_folder_actual.files[1].filename == 'subdir' - - remote_copy_folder_to_folder_actual.files[2].filename == 'empty' - - remote_copy_folder_to_folder_actual.files[3].filename == 'subdir2' - - remote_copy_folder_to_folder_actual.files[4].filename == 'subdir3' - - remote_copy_folder_to_folder_actual.files[5].filename == 'subdir4' - -- name: copy folder to folder remote (idempotent) - win_copy: - src: '{{test_win_copy_path}}\source' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_to_folder_again - -- name: assert copy folder to folder remote (idempotent) - assert: - that: - - remote_copy_folder_to_folder_again is not changed - -- name: change remote file after folder to folder test - win_copy: - content: bar.txt - dest: '{{test_win_copy_path}}\target\source\foo.txt' - -- name: remote remote folder after folder to folder test - win_file: - path: '{{test_win_copy_path}}\target\source\subdir\subdir2\subdir3\subdir4' - state: absent - -- name: copy folder to folder remote after change - win_copy: - src: '{{test_win_copy_path}}\source' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_to_folder_after_change - -- name: get result of copy folder to folder remote after change - win_find: - paths: '{{test_win_copy_path}}\target\source' - recurse: yes - patterns: ['foo.txt', 'qux.txt'] - register: remote_copy_folder_to_folder_after_change_actual - -- name: assert copy folder after changes - assert: - that: - - remote_copy_folder_to_folder_after_change is changed - - remote_copy_folder_to_folder_after_change_actual.matched == 2 - - remote_copy_folder_to_folder_after_change_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - remote_copy_folder_to_folder_after_change_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - -- name: clear target folder before folder contents to remote test - win_file: - path: '{{test_win_copy_path}}\target' - state: absent - -- name: copy folder contents to folder remote with backslash (check mode) - win_copy: - src: '{{test_win_copy_path}}\source\' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_content_backslash_check - check_mode: yes - -- name: get result of copy folder contents to folder remote with backslash (check mode) - win_stat: - path: '{{test_win_copy_path}}\target' - register: remote_copy_folder_content_backslash_actual_check - -- name: assert copy folder content to folder remote with backslash (check mode) - assert: - that: - - remote_copy_folder_content_backslash_check is changed - - remote_copy_folder_content_backslash_actual_check.stat.exists == False - -- name: copy folder contents to folder remote with backslash - win_copy: - src: '{{test_win_copy_path}}\source\' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_content_backslash - -- name: get result of copy folder contents to folder remote with backslash - win_find: - paths: '{{test_win_copy_path}}\target' - recurse: yes - file_type: directory - register: remote_copy_folder_content_backslash_actual - -- name: assert copy folder content to folder remote with backslash - assert: - that: - - remote_copy_folder_content_backslash is changed - - remote_copy_folder_content_backslash.operation == 'folder_copy' - - remote_copy_folder_content_backslash_actual.examined == 10 - - remote_copy_folder_content_backslash_actual.matched == 5 - - remote_copy_folder_content_backslash_actual.files[0].filename == 'subdir' - - remote_copy_folder_content_backslash_actual.files[1].filename == 'empty' - - remote_copy_folder_content_backslash_actual.files[2].filename == 'subdir2' - - remote_copy_folder_content_backslash_actual.files[3].filename == 'subdir3' - - remote_copy_folder_content_backslash_actual.files[4].filename == 'subdir4' - -- name: copy folder contents to folder remote with backslash (idempotent) - win_copy: - src: '{{test_win_copy_path}}\source\' - dest: '{{test_win_copy_path}}\target' - remote_src: yes - register: remote_copy_folder_content_backslash_again - -- name: assert copy folder content to folder remote with backslash (idempotent) - assert: - that: - - remote_copy_folder_content_backslash_again is not changed - -- name: change remote file after folder content to folder test - win_copy: - content: bar.txt - dest: '{{test_win_copy_path}}\target\foo.txt' - -- name: remote remote folder after folder content to folder test - win_file: - path: '{{test_win_copy_path}}\target\subdir\subdir2\subdir3\subdir4' - state: absent - -- name: copy folder content to folder remote after change - win_copy: - src: '{{test_win_copy_path}}/source/' - dest: '{{test_win_copy_path}}/target/' - remote_src: yes - register: remote_copy_folder_content_to_folder_after_change - -- name: get result of copy folder content to folder remote after change - win_find: - paths: '{{test_win_copy_path}}\target' - recurse: yes - patterns: ['foo.txt', 'qux.txt'] - register: remote_copy_folder_content_to_folder_after_change_actual - -- name: assert copy folder content to folder after changes - assert: - that: - - remote_copy_folder_content_to_folder_after_change is changed - - remote_copy_folder_content_to_folder_after_change_actual.matched == 2 - - remote_copy_folder_content_to_folder_after_change_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - remote_copy_folder_content_to_folder_after_change_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - -# https://github.com/ansible/ansible/issues/50077 -- name: create empty nested directory - win_file: - path: '{{ test_win_copy_path }}\source\empty-nested\nested-dir' - state: directory - -- name: copy empty nested directory (check mode) - win_copy: - src: '{{ test_win_copy_path }}\source\empty-nested' - dest: '{{ test_win_copy_path }}\target' - remote_src: True - check_mode: True - register: copy_empty_dir_check - -- name: get result of copy empty nested directory (check mode) - win_stat: - path: '{{ test_win_copy_path }}\target\empty-nested' - register: copy_empty_dir_actual_check - -- name: assert copy empty nested directory (check mode) - assert: - that: - - copy_empty_dir_check is changed - - copy_empty_dir_check.operation == "folder_copy" - - not copy_empty_dir_actual_check.stat.exists - -- name: copy empty nested directory - win_copy: - src: '{{ test_win_copy_path }}\source\empty-nested' - dest: '{{ test_win_copy_path }}\target' - remote_src: True - register: copy_empty_dir - -- name: get result of copy empty nested directory - win_stat: - path: '{{ test_win_copy_path }}\target\empty-nested\nested-dir' - register: copy_empty_dir_actual - -- name: assert copy empty nested directory - assert: - that: - - copy_empty_dir is changed - - copy_empty_dir.operation == "folder_copy" - - copy_empty_dir_actual.stat.exists - -- name: copy empty nested directory (idempotent) - win_copy: - src: '{{ test_win_copy_path }}\source\empty-nested' - dest: '{{ test_win_copy_path }}\target' - remote_src: True - register: copy_empty_dir_again - -- name: assert copy empty nested directory (idempotent) - assert: - that: - - not copy_empty_dir_again is changed diff --git a/test/integration/targets/win_copy/tasks/tests.yml b/test/integration/targets/win_copy/tasks/tests.yml deleted file mode 100644 index d15e71f65c..0000000000 --- a/test/integration/targets/win_copy/tasks/tests.yml +++ /dev/null @@ -1,535 +0,0 @@ ---- -- name: fail no source or content - win_copy: - dest: dest - register: fail_no_source_content - failed_when: fail_no_source_content.msg != 'src (or content) and dest are required' - -- name: fail content but dest isn't a file, unix ending - win_copy: - content: a - dest: a/ - register: fail_dest_not_file_unix - failed_when: fail_dest_not_file_unix.msg != 'dest must be a file if content is defined' - -- name: fail content but dest isn't a file, windows ending - win_copy: - content: a - dest: a\ - register: fail_dest_not_file_windows - failed_when: fail_dest_not_file_windows.msg != 'dest must be a file if content is defined' - -- name: fail to copy a file with parent dir that doesn't exist and filename is set - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\missing-dir\foo.txt' - register: fail_missing_parent_dir - failed_when: "'does not exist' not in fail_missing_parent_dir.msg" - -- name: fail to copy an encrypted file without the password set - win_copy: - src: '{{role_path}}/files-different/vault/vault-file' - dest: '{{test_win_copy_path}}\file' - register: fail_copy_encrypted_file - ignore_errors: yes # weird failed_when doesn't work in this case - -- name: assert failure message when copying an encrypted file without the password set - assert: - that: - - fail_copy_encrypted_file is failed - - fail_copy_encrypted_file.msg == 'A vault password or secret must be specified to decrypt {{role_path}}/files-different/vault/vault-file' - -- name: fail to copy a directory with an encrypted file without the password - win_copy: - src: '{{role_path}}/files-different/vault' - dest: '{{test_win_copy_path}}' - register: fail_copy_directory_with_enc_file - ignore_errors: yes - -- name: assert failure message when copying a directory that contains an encrypted file without the password set - assert: - that: - - fail_copy_directory_with_enc_file is failed - - fail_copy_directory_with_enc_file.msg == 'A vault password or secret must be specified to decrypt {{role_path}}/files-different/vault/vault-file' - -- name: copy with content (check mode) - win_copy: - content: a - dest: '{{test_win_copy_path}}\file' - register: copy_content_check - check_mode: yes - -- name: get result of copy with content (check mode) - win_stat: - path: '{{test_win_copy_path}}\file' - register: copy_content_actual_check - -- name: assert copy with content (check mode) - assert: - that: - - copy_content_check is changed - - copy_content_check.checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8' - - copy_content_check.operation == 'file_copy' - - copy_content_check.size == 1 - - copy_content_actual_check.stat.exists == False - -- name: copy with content - win_copy: - content: a - dest: '{{test_win_copy_path}}\file' - register: copy_content - -- name: get result of copy with content - win_stat: - path: '{{test_win_copy_path}}\file' - register: copy_content_actual - -- name: assert copy with content - assert: - that: - - copy_content is changed - - copy_content.checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8' - - copy_content.operation == 'file_copy' - - copy_content.size == 1 - - copy_content_actual.stat.exists == True - - copy_content_actual.stat.checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8' - -- name: copy with content (idempotent) - win_copy: - content: a - dest: '{{test_win_copy_path}}\file' - register: copy_content_again - -- name: assert copy with content (idempotent) - assert: - that: - - copy_content_again is not changed - -- name: copy with content change when missing - win_copy: - content: b - dest: '{{test_win_copy_path}}\file' - force: no - register: copy_content_when_missing - -- name: assert copy with content change when missing - assert: - that: - - copy_content_when_missing is not changed - -- name: copy single file (check mode) - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\foo-target.txt' - register: copy_file_check - check_mode: yes - -- name: get result of copy single file (check mode) - win_stat: - path: '{{test_win_copy_path}}\foo-target.txt' - register: copy_file_actual_check - -- name: assert copy single file (check mode) - assert: - that: - - copy_file_check is changed - - copy_file_check.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file_check.dest == test_win_copy_path + '\\foo-target.txt' - - copy_file_check.operation == 'file_copy' - - copy_file_check.size == 8 - - copy_file_actual_check.stat.exists == False - -- name: copy single file - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\foo-target.txt' - register: copy_file - -- name: get result of copy single file - win_stat: - path: '{{test_win_copy_path}}\foo-target.txt' - register: copy_file_actual - -- name: assert copy single file - assert: - that: - - copy_file is changed - - copy_file.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file.dest == test_win_copy_path + '\\foo-target.txt' - - copy_file.operation == 'file_copy' - - copy_file.size == 8 - - copy_file_actual.stat.exists == True - - copy_file_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: copy single file (idempotent) - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\foo-target.txt' - register: copy_file_again - -- name: assert copy single file (idempotent) - assert: - that: - - copy_file_again is not changed - -- name: copy single file (backup) - win_copy: - content: "{{ lookup('file', 'foo.txt') }}\nfoo bar" - dest: '{{test_win_copy_path}}\foo-target.txt' - backup: yes - register: copy_file_backup - -- name: check backup_file - win_stat: - path: '{{ copy_file_backup.backup_file }}' - register: backup_file - -- name: assert copy single file (backup) - assert: - that: - - copy_file_backup is changed - - backup_file.stat.exists == true - -- name: copy single file to folder (check mode) - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\' - register: copy_file_to_folder_check - check_mode: yes - -- name: get result of copy single file to folder (check mode) - win_stat: - path: '{{test_win_copy_path}}\foo.txt' - register: copy_file_to_folder_actual_check - -- name: assert copy single file to folder (check mode) - assert: - that: - - copy_file_to_folder_check is changed - - copy_file_to_folder_check.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file_to_folder_check.dest == test_win_copy_path + '\\foo.txt' - - copy_file_to_folder_check.operation == 'file_copy' - - copy_file_to_folder_check.size == 8 - - copy_file_to_folder_actual_check.stat.exists == False - -- name: copy single file to folder - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\' - register: copy_file_to_folder - -- name: get result of copy single file to folder - win_stat: - path: '{{test_win_copy_path}}\foo.txt' - register: copy_file_to_folder_actual - -- name: assert copy single file to folder - assert: - that: - - copy_file_to_folder is changed - - copy_file_to_folder.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file_to_folder.dest == test_win_copy_path + '\\foo.txt' - - copy_file_to_folder.operation == 'file_copy' - - copy_file_to_folder.size == 8 - - copy_file_to_folder_actual.stat.exists == True - - copy_file_to_folder_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: copy single file to folder (idempotent) - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\' - register: copy_file_to_folder_again - -- name: assert copy single file to folder (idempotent) - assert: - that: - - copy_file_to_folder_again is not changed - -- name: copy single file to missing folder (check mode) - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\missing\' - register: copy_file_to_missing_folder_check - check_mode: yes - -- name: get result of copy single file to missing folder (check mode) - win_stat: - path: '{{test_win_copy_path}}\missing\foo.txt' - register: copy_file_to_missing_folder_actual_check - -- name: assert copy single file to missing folder (check mode) - assert: - that: - - copy_file_to_missing_folder_check is changed - - copy_file_to_missing_folder_check.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file_to_missing_folder_check.operation == 'file_copy' - - copy_file_to_missing_folder_check.size == 8 - - copy_file_to_missing_folder_actual_check.stat.exists == False - -- name: copy single file to missing folder - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\missing\' - register: copy_file_to_missing_folder - -- name: get result of copy single file to missing folder - win_stat: - path: '{{test_win_copy_path}}\missing\foo.txt' - register: copy_file_to_missing_folder_actual - -- name: assert copy single file to missing folder - assert: - that: - - copy_file_to_missing_folder is changed - - copy_file_to_missing_folder.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_file_to_missing_folder.operation == 'file_copy' - - copy_file_to_missing_folder.size == 8 - - copy_file_to_missing_folder_actual.stat.exists == True - - copy_file_to_missing_folder_actual.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - -- name: copy folder (check mode) - win_copy: - src: files - dest: '{{test_win_copy_path}}\recursive\folder' - register: copy_folder_check - check_mode: yes - -- name: get result of copy folder (check mode) - win_stat: - path: '{{test_win_copy_path}}\recursive\folder' - register: copy_folder_actual_check - -- name: assert copy folder (check mode) - assert: - that: - - copy_folder_check is changed - - copy_folder_check.operation == 'folder_copy' - - copy_folder_actual_check.stat.exists == False - -- name: copy folder - win_copy: - src: files - dest: '{{test_win_copy_path}}\recursive\folder' - register: copy_folder - -- name: get result of copy folder - win_find: - paths: '{{test_win_copy_path}}\recursive\folder' - recurse: yes - file_type: directory - register: copy_folder_actual - -- name: assert copy folder - assert: - that: - - copy_folder is changed - - copy_folder.operation == 'folder_copy' - - copy_folder_actual.examined == 11 # includes files and folders, the below is the nested order - - copy_folder_actual.matched == 6 - - copy_folder_actual.files[0].filename == 'files' - - copy_folder_actual.files[1].filename == 'subdir' - - copy_folder_actual.files[2].filename == 'empty' - - copy_folder_actual.files[3].filename == 'subdir2' - - copy_folder_actual.files[4].filename == 'subdir3' - - copy_folder_actual.files[5].filename == 'subdir4' - -- name: copy folder (idempotent) - win_copy: - src: files - dest: '{{test_win_copy_path}}\recursive\folder' - register: copy_folder_again - -- name: assert copy folder (idempotent) - assert: - that: - - copy_folder_again is not changed - -- name: change the text of a file in the remote source - win_copy: - content: bar.txt - dest: '{{test_win_copy_path}}\recursive\folder\files\foo.txt' - -- name: remove folder for test of recursive copy - win_file: - path: '{{test_win_copy_path}}\recursive\folder\files\subdir\subdir2\subdir3\subdir4' - state: absent - -- name: copy folder after changes - win_copy: - src: files - dest: '{{test_win_copy_path}}\recursive\folder' - register: copy_folder_after_change - -- name: get result of copy folder after changes - win_find: - paths: '{{test_win_copy_path}}\recursive\folder\files' - recurse: yes - patterns: ['foo.txt', 'qux.txt'] - register: copy_folder_after_changes_actual - -- name: assert copy folder after changes - assert: - that: - - copy_folder_after_change is changed - - copy_folder_after_changes_actual.matched == 2 - - copy_folder_after_changes_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' - - copy_folder_after_changes_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - -- name: copy folder's contents (check mode) - win_copy: - src: files/ - dest: '{{test_win_copy_path}}\recursive-contents\' - register: copy_folder_contents_check - check_mode: yes - -- name: get result of copy folder'scontents (check mode) - win_stat: - path: '{{test_win_copy_path}}\recursive-contents' - register: copy_folder_contents_actual_check - -- name: assert copy folder's contents (check mode) - assert: - that: - - copy_folder_contents_check is changed - - copy_folder_contents_check.operation == 'folder_copy' - - copy_folder_contents_actual_check.stat.exists == False - -- name: copy folder's contents - win_copy: - src: files/ - dest: '{{test_win_copy_path}}\recursive-contents\' - register: copy_folder_contents - -- name: get result of copy folder - win_find: - paths: '{{test_win_copy_path}}\recursive-contents' - recurse: yes - file_type: directory - register: copy_folder_contents_actual - -- name: assert copy folder - assert: - that: - - copy_folder_contents is changed - - copy_folder_contents.operation == 'folder_copy' - - copy_folder_contents_actual.examined == 10 # includes files and folders, the below is the nested order - - copy_folder_contents_actual.matched == 5 - - copy_folder_contents_actual.files[0].filename == 'subdir' - - copy_folder_contents_actual.files[1].filename == 'empty' - - copy_folder_contents_actual.files[2].filename == 'subdir2' - - copy_folder_contents_actual.files[3].filename == 'subdir3' - - copy_folder_contents_actual.files[4].filename == 'subdir4' - -- name: fail to copy file to a folder - win_copy: - src: foo.txt - dest: '{{test_win_copy_path}}\recursive-contents' - register: fail_file_to_folder - failed_when: "'object at path is already a directory' not in fail_file_to_folder.msg" - -- name: fail to copy folder to a file - win_copy: - src: subdir/ - dest: '{{test_win_copy_path}}\recursive-contents\foo.txt' - register: fail_folder_to_file - failed_when: "'object at parent directory path is already a file' not in fail_folder_to_file.msg" - -# https://github.com/ansible/ansible/issues/31336 -- name: create file with colon in the name - copy: - dest: '{{role_path}}/files-different/colon:file' - content: test - delegate_to: localhost - -- name: copy a file with colon as a source - win_copy: - src: '{{role_path}}/files-different/colon:file' - dest: '{{test_win_copy_path}}\colon.file' - register: copy_file_with_colon - -- name: get result of file with colon as a source - win_stat: - path: '{{test_win_copy_path}}\colon.file' - register: copy_file_with_colon_result - -- name: assert results of copy a file with colon as a source - assert: - that: - - copy_file_with_colon is changed - - copy_file_with_colon_result.stat.exists == True - - copy_file_with_colon_result.stat.checksum == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" - -- name: remove file with colon in the name - file: - path: '{{role_path}}/files-different/colon:file' - state: absent - delegate_to: localhost - -- name: copy an encrypted file without decrypting - win_copy: - src: '{{role_path}}/files-different/vault/vault-file' - dest: '{{test_win_copy_path}}\vault-file' - decrypt: no - register: copy_encrypted_file - -- name: get stat of copied encrypted file without decrypting - win_stat: - path: '{{test_win_copy_path}}\vault-file' - register: copy_encrypted_file_result - -- name: assert result of copy an encrypted file without decrypting - assert: - that: - - copy_encrypted_file is changed - - copy_encrypted_file_result.stat.checksum == "74a89620002d253f38834ee5b06cddd28956a43d" - -- name: copy an encrypted file without decrypting (idempotent) - win_copy: - src: '{{role_path}}/files-different/vault/vault-file' - dest: '{{test_win_copy_path}}\vault-file' - decrypt: no - register: copy_encrypted_file_again - -- name: assert result of copy an encrypted file without decrypting (idempotent) - assert: - that: - - copy_encrypted_file_again is not changed - -- name: copy folder with encrypted files without decrypting - win_copy: - src: '{{role_path}}/files-different/vault/' - dest: '{{test_win_copy_path}}\encrypted-test' - decrypt: no - register: copy_encrypted_file - -- name: get result of copy folder with encrypted files without decrypting - win_find: - paths: '{{test_win_copy_path}}\encrypted-test' - recurse: yes - patterns: '*vault*' - register: copy_encrypted_file_result - -- name: assert result of copy folder with encrypted files without decrypting - assert: - that: - - copy_encrypted_file is changed - - copy_encrypted_file_result.files|count == 2 - - copy_encrypted_file_result.files[0].checksum == "834563c94127730ecfa42dfc1e1821bbda2e51da" - - copy_encrypted_file_result.files[1].checksum == "74a89620002d253f38834ee5b06cddd28956a43d" - -- name: copy folder with encrypted files without decrypting (idempotent) - win_copy: - src: '{{role_path}}/files-different/vault/' - dest: '{{test_win_copy_path}}\encrypted-test' - decrypt: no - register: copy_encrypted_file_again - -- name: assert result of copy folder with encrypted files without decrypting (idempotent) - assert: - that: - - copy_encrypted_file_again is not changed - -- name: remove test folder after local to remote tests - win_file: - path: '{{test_win_copy_path}}' - state: absent diff --git a/test/integration/targets/win_dns_client/aliases b/test/integration/targets/win_dns_client/aliases deleted file mode 100644 index 423ce39108..0000000000 --- a/test/integration/targets/win_dns_client/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_dns_client/meta/main.yml b/test/integration/targets/win_dns_client/meta/main.yml deleted file mode 100644 index 012551418a..0000000000 --- a/test/integration/targets/win_dns_client/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_win_device diff --git a/test/integration/targets/win_dns_client/tasks/main.yml b/test/integration/targets/win_dns_client/tasks/main.yml deleted file mode 100644 index 0e8b011b17..0000000000 --- a/test/integration/targets/win_dns_client/tasks/main.yml +++ /dev/null @@ -1,217 +0,0 @@ ---- -- set_fact: - get_ip_script: | - $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ network_adapter_name }}'" - $config = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=$($adapter.DeviceID)" - $ips = $config.DNSServerSearchOrder - if ($ips) { - $config.DNSServerSearchOrder[0] - $config.DNSServerSearchOrder[1] - } - -- name: set a single IPv4 address (check mode) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: 192.168.34.5 - register: set_single_check - check_mode: yes - -- name: get result of set a single IPv4 address (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_single_actual_check - -- name: assert set a single IPv4 address (check mode) - assert: - that: - - set_single_check is changed - - set_single_actual_check.stdout_lines == [] - -- name: set a single IPv4 address - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: 192.168.34.5 - register: set_single - -- name: get result of set a single IPv4 address - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_single_actual - -- name: assert set a single IPv4 address - assert: - that: - - set_single is changed - - set_single_actual.stdout_lines == ["192.168.34.5"] - -- name: set a single IPv4 address (idempotent) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: 192.168.34.5 - register: set_single_again - -- name: assert set a single IPv4 address (idempotent) - assert: - that: - - not set_single_again is changed - -- name: change IPv4 address to another value (check mode) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: 192.168.34.6 - register: change_single_check - check_mode: yes - -- name: get result of change IPv4 address to another value (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: check_single_actual_check - -- name: assert change IPv4 address to another value (check mode) - assert: - that: - - change_single_check is changed - - check_single_actual_check.stdout_lines == ["192.168.34.5"] - -- name: change IPv4 address to another value - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: 192.168.34.6 - register: change_single - -- name: get result of change IPv4 address to another value - win_shell: '{{ get_ip_script }}' - changed_when: no - register: check_single_actual - -- name: assert change IPv4 address to another value - assert: - that: - - change_single is changed - - check_single_actual.stdout_lines == ["192.168.34.6"] - -- name: set multiple IPv4 addresses (check mode) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple_check - check_mode: yes - -- name: get result of set multiple IPv4 addresses (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_multiple_actual_check - -- name: assert set multiple IPv4 addresses (check mode) - assert: - that: - - set_multiple_check is changed - - set_multiple_actual_check.stdout_lines == ["192.168.34.6"] - -- name: set multiple IPv4 addresses - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple - -- name: get result of set multiple IPv4 addresses - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_multiple_actual - -- name: assert set multiple IPv4 addresses - assert: - that: - - set_multiple is changed - - set_multiple_actual.stdout_lines == ["192.168.34.7", "192.168.34.8"] - -- name: set multiple IPv4 addresses (idempotent) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple_again - -- name: assert set multiple IPv4 addresses (idempotent) - assert: - that: - - not set_multiple_again is changed - -- name: reset IPv4 DNS back to DHCP (check mode) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: [] - register: set_dhcp_check - check_mode: yes - -- name: get result of reset IPv4 DNS back to DHCP (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_dhcp_actual_check - -- name: assert reset IPv4 DNS back to DHCP (check mode) - assert: - that: - - set_dhcp_check is changed - - set_dhcp_actual_check.stdout_lines == ["192.168.34.7", "192.168.34.8"] - -- name: reset IPv4 DNS back to DHCP - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: [] - register: set_dhcp - -- name: get result of reset IPv4 DNS back to DHCP - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_dhcp_actual - -- name: assert reset IPv4 DNS back to DHCP - assert: - that: - - set_dhcp is changed - - set_dhcp_actual.stdout_lines == [] - -- name: reset IPv4 DNS back to DHCP (idempotent) - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - ipv4_addresses: [] - register: set_dhcp_again - -- name: assert reset IPv4 DNS back to DHCP (idempotent) - assert: - that: - - set_dhcp_again is not changed - -# Legacy WMI does not support setting IPv6 addresses so we can only test this on newer hosts that have the new cmdlets -- name: check if server supports IPv6 - win_shell: if (Get-Command -Name Get-NetAdapter -ErrorAction SilentlyContinue) { $true } else { $false } - changed_when: no - register: new_os - -- name: run IPv6 tests - when: new_os.stdout | trim | bool - block: - - name: set IPv6 DNS address - win_dns_client: - adapter_names: '{{ network_adapter_name }}' - dns_servers: - - 2001:db8::1 - - 2001:db8::2 - register: set_ipv6 - - - name: get result of set IPv6 DNS address - win_shell: (Get-DnsClientServerAddress -InterfaceAlias '{{ network_adapter_name }}' -AddressFAmily IPv6).ServerAddresses - changed_when: no - register: set_ipv6_actual - - - name: assert set IPv6 DNS address - assert: - that: - - set_ipv6 is changed - - set_ipv6_actual.stdout_lines == ['2001:db8::1', '2001:db8::2'] diff --git a/test/integration/targets/win_domain_membership/aliases b/test/integration/targets/win_domain_membership/aliases deleted file mode 100644 index 4c08975b17..0000000000 --- a/test/integration/targets/win_domain_membership/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_domain_membership/tasks/main.yml b/test/integration/targets/win_domain_membership/tasks/main.yml deleted file mode 100644 index c6294bd32a..0000000000 --- a/test/integration/targets/win_domain_membership/tasks/main.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: get current workgroup - win_shell: (Get-WmiObject Win32_ComputerSystem).Workgroup - register: workgroup - -- name: fail if workgroup result is empty (means test host is in a domain) - fail: - msg: Cannot run tests for win_domain_membership when host is a member of a domain - when: workgroup.stdout == "" - -- block: - - include_tasks: tests.yml - - always: - - name: revert workgroup back to original before tests - win_domain_membership: - workgroup_name: '{{workgroup.stdout_lines[0]}}' - state: workgroup - domain_admin_user: fake user - domain_admin_password: fake password diff --git a/test/integration/targets/win_domain_membership/tasks/tests.yml b/test/integration/targets/win_domain_membership/tasks/tests.yml deleted file mode 100644 index 85f688e1d6..0000000000 --- a/test/integration/targets/win_domain_membership/tasks/tests.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- -- name: change workgroup (check mode) - win_domain_membership: - workgroup_name: ANSIBLETEST - state: workgroup - domain_admin_user: fake user - domain_admin_password: fake password - register: change_workgroup_check - check_mode: yes - -- name: get result of change workgroup (check mode) - win_shell: (Get-WmiObject Win32_ComputerSystem).Workgroup - register: change_workgroup_result_check - -- name: assert result of change workgroup (check mode) - assert: - that: - - change_workgroup_check is changed - - change_workgroup_result_check.stdout == workgroup.stdout - -- name: change workgroup - win_domain_membership: - workgroup_name: ANSIBLETEST - state: workgroup - domain_admin_user: fake user - domain_admin_password: fake password - register: change_workgroup - -- name: get result of change workgroup - win_shell: (Get-WmiObject Win32_ComputerSystem).Workgroup - register: change_workgroup_result - -- name: assert result of change workgroup - assert: - that: - - change_workgroup is changed - - change_workgroup_result.stdout_lines[0] == "ANSIBLETEST" - -- name: change workgroup (idempotent) - win_domain_membership: - workgroup_name: ANSIBLETEST - state: workgroup - domain_admin_user: fake user - domain_admin_password: fake password - register: change_workgroup_again - -- name: assert result of change workgroup (idempotent) - assert: - that: - - change_workgroup_again is not changed - -- name: change workgroup fail invalid name - win_domain_membership: - workgroup_name: ANSIBLELONGNAMEFAILURE - state: workgroup - domain_admin_user: fake user - domain_admin_password: fake password - register: fail_change_workgroup - failed_when: "fail_change_workgroup.msg != 'failed to set workgroup through WMI, return value: 2695'" diff --git a/test/integration/targets/win_dsc/aliases b/test/integration/targets/win_dsc/aliases deleted file mode 100644 index 79af200d66..0000000000 --- a/test/integration/targets/win_dsc/aliases +++ /dev/null @@ -1,5 +0,0 @@ -shippable/windows/group4 -skip/windows/2008 -skip/windows/2008-R2 -skip/windows/2012 -skip/windows/2012-R2 diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 deleted file mode 100644 index dbf1ecf3ee..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 +++ /dev/null @@ -1,41 +0,0 @@ -#Requires -Version 5.0 -Modules CimCmdlets - -Function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([Hashtable])] - param( - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [String]$KeyParam - ) - return @{Value = [bool]$global:DSCMachineStatus} -} - -Function Set-TargetResource -{ - [CmdletBinding()] - param ( - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [String]$KeyParam, - [Bool]$Value = $true - ) - $global:DSCMachineStatus = [int]$Value -} - -Function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([Boolean])] - param ( - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [String]$KeyParam, - [Bool]$Value = $true - ) - $false -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof deleted file mode 100644 index 288b887722..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof +++ /dev/null @@ -1,7 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("xSetReboot")] -class ANSIBLE_xSetReboot : OMI_BaseResource -{ - [Key] String KeyParam; - [Write] Boolean Value; -}; - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 deleted file mode 100644 index 79f6496962..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 +++ /dev/null @@ -1,214 +0,0 @@ -#Requires -Version 5.0 -Modules CimCmdlets - -Function ConvertFrom-CimInstance { - param( - [Parameter(Mandatory=$true)][CimInstance]$Instance - ) - $hashtable = @{ - _cim_instance = $Instance.CimSystemProperties.ClassName - } - foreach ($prop in $Instance.CimInstanceProperties) { - $hashtable."$($prop.Name)" = ConvertTo-OutputValue -Value $prop.Value - } - return $hashtable -} - -Function ConvertTo-OutputValue { - param($Value) - - if ($Value -is [DateTime[]]) { - $Value = $Value | ForEach-Object { $_.ToString("o") } - } elseif ($Value -is [DateTime]) { - $Value = $Value.ToString("o") - } elseif ($Value -is [Double]) { - $Value = $Value.ToString() # To avoid Python 2 double parsing issues on test validation - } elseif ($Value -is [Double[]]) { - $Value = $Value | ForEach-Object { $_.ToString() } - } elseif ($Value -is [PSCredential]) { - $password = $null - $password_ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Value.Password) - try { - $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($password_ptr) - } finally { - [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($password_ptr) - } - $Value = @{ - username = $Value.Username - password = $password - } - } elseif ($Value -is [CimInstance[]]) { - $value_list = [System.Collections.Generic.List`1[Hashtable]]@() - foreach ($cim_instance in $Value) { - $value_list.Add((ConvertFrom-CimInstance -Instance $cim_instance)) - } - $Value = $value_list.ToArray() - } elseif ($Value -is [CimInstance]) { - $Value = ConvertFrom-CimInstance -Instance $Value - } - - return ,$Value -} - -Function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([Hashtable])] - param( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path - ) - return @{ - Ensure = $Ensure - Path = $Path - } -} - -Function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path, - - [String] $DefaultParam = "Default", - [String] $StringParam, - [String[]] $StringArrayParam, - [SByte] $Int8Param, - [SByte[]] $Int8ArrayParam, - [Byte] $UInt8Param, - [Byte[]] $UInt8ArrayParam, - [Int16] $Int16Param, - [Int16[]] $Int16ArrayParam, - [UInt16] $UInt16Param, - [UInt16[]] $UInt16ArrayParam, - [Int32] $Int32Param, - [Int32[]] $Int32ArrayParam, - [UInt32] $UInt32Param, - [UInt32[]] $UInt32ArrayParam, - [Int64] $Int64Param, - [Int64[]] $Int64ArrayParam, - [UInt64] $UInt64Param, - [UInt64[]] $UInt64ArrayParam, - [Bool] $BooleanParam, - [Bool[]] $BooleanArrayParam, - [Char] $CharParam, - [Char[]] $CharArrayParam, - [Single] $SingleParam, - [Single[]] $SingleArrayParam, - [Double] $DoubleParam, - [Double[]] $DoubleArrayParam, - [DateTime] $DateTimeParam, - [DateTime[]] $DateTimeArrayParam, - [PSCredential] $PSCredentialParam, - [CimInstance[]] $HashtableParam, - [CimInstance] $CimInstanceParam, - [CimInstance[]] $CimInstanceArrayParam, - [CimInstance] $NestedCimInstanceParam, - [CimInstance[]] $NestedCimInstanceArrayParam - ) - - $info = @{ - Version = "1.0.0" - Ensure = @{ - Type = $Ensure.GetType().FullName - Value = $Ensure - } - Path = @{ - Type = $Path.GetType().FullName - Value = $Path - } - DefaultParam = @{ - Type = $DefaultParam.GetType().FullName - Value = $DefaultParam - } - } - - foreach ($kvp in $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator()) { - $info."$($kvp.Key)" = @{ - Type = $kvp.Value.GetType().FullName - Value = (ConvertTo-OutputValue -Value $kvp.Value) - } - } - - if (Test-Path -Path $Path) { - Remove-Item -Path $Path -Force > $null - } - New-Item -Path $Path -ItemType File > $null - Set-Content -Path $Path -Value (ConvertTo-Json -InputObject $info -Depth 10) > $null - Write-Verbose -Message "set verbose" - Write-Warning -Message "set warning" -} - -Function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path, - - [String] $DefaultParam = "Default", - [String] $StringParam, - [String[]] $StringArrayParam, - [SByte] $Int8Param, - [SByte[]] $Int8ArrayParam, - [Byte] $UInt8Param, - [Byte[]] $UInt8ArrayParam, - [Int16] $Int16Param, - [Int16[]] $Int16ArrayParam, - [UInt16] $UInt16Param, - [UInt16[]] $UInt16ArrayParam, - [Int32] $Int32Param, - [Int32[]] $Int32ArrayParam, - [UInt32] $UInt32Param, - [UInt32[]] $UInt32ArrayParam, - [Int64] $Int64Param, - [Int64[]] $Int64ArrayParam, - [UInt64] $UInt64Param, - [UInt64[]] $UInt64ArrayParam, - [Bool] $BooleanParam, - [Bool[]] $BooleanArrayParam, - [Char] $CharParam, - [Char[]] $CharArrayParam, - [Single] $SingleParam, - [Single[]] $SingleArrayParam, - [Double] $DoubleParam, - [Double[]] $DoubleArrayParam, - [DateTime] $DateTimeParam, - [DateTime[]] $DateTimeArrayParam, - [PSCredential] $PSCredentialParam, - [CimInstance[]] $HashtableParam, - [CimInstance] $CimInstanceParam, - [CimInstance[]] $CimInstanceArrayParam, - [CimInstance] $NestedCimInstanceParam, - [CimInstance[]] $NestedCimInstanceArrayParam - ) - Write-Verbose -Message "test verbose" - Write-Warning -Message "test warning" - $exists = Test-Path -LiteralPath $Path -PathType Leaf - if ($Ensure -eq "Present") { - $exists - } else { - -not $exists - } -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof deleted file mode 100644 index c61b2b1e6a..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof +++ /dev/null @@ -1,60 +0,0 @@ -[ClassVersion("1.0.0")] -class ANSIBLE_xTestClass -{ - [Key] String Key; - [Write] String StringValue; - [Write] SInt32 IntValue; - [Write] String StringArrayValue[]; -}; - -[ClassVersion("1.0.0")] -class ANSIBLE_xNestedClass -{ - [Key] String KeyValue; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimValue; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashValue[]; - [Write] SInt16 IntValue; -}; - -[ClassVersion("1.0.0"), FriendlyName("xTestResource")] -class ANSIBLE_xTestResource : OMI_BaseResource -{ - [Key] String Path; - [Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; - [Read] String ReadParam; - [Write] String DefaultParam; - [Write] String StringParam; - [Write] String StringArrayParam[]; - [Write] SInt8 Int8Param; - [Write] SInt8 Int8ArrayParam[]; - [Write] UInt8 UInt8Param; - [Write] UInt8 UInt8ArrayParam[]; - [Write] SInt16 Int16Param; - [Write] SInt16 Int16ArrayParam[]; - [Write] UInt16 UInt16Param; - [Write] UInt16 UInt16ArrayParam[]; - [Write] SInt32 Int32Param; - [Write] SInt32 Int32ArrayParam[]; - [Write] UInt32 UInt32Param; - [Write] UInt32 UInt32ArrayParam[]; - [Write] SInt64 Int64Param; - [Write] SInt64 Int64ArrayParam[]; - [Write] UInt64 UInt64Param; - [Write] UInt64 UInt64ArrayParam[]; - [Write] Boolean BooleanParam; - [Write] Boolean BooleanArrayParam[]; - [Write] Char16 CharParam; - [Write] Char16 CharArrayParam[]; - [Write] Real32 SingleParam; - [Write] Real32 SingleArrayParam[]; - [Write] Real64 DoubleParam; - [Write] Real64 DoubleArrayParam[]; - [Write] DateTime DateTimeParam; - [Write] DateTime DateTimeArrayParam[]; - [Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashtableParam[]; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[]; - [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceParam; - [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceArrayParam[]; -}; - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 deleted file mode 100644 index 3d61611d70..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 +++ /dev/null @@ -1,13 +0,0 @@ -@{ - ModuleVersion = '1.0.0' - GUID = '80c895c4-de3f-4d6d-8fa4-c504c96b6f22' - Author = 'Ansible' - CompanyName = 'Ansible' - Copyright = '(c) 2019' - Description = 'Test DSC Resource for Ansible integration tests' - PowerShellVersion = '5.0' - CLRVersion = '4.0' - FunctionsToExport = '*' - CmdletsToExport = '*' -} - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 deleted file mode 100644 index d75256e1d9..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 +++ /dev/null @@ -1,214 +0,0 @@ -#Requires -Version 5.0 -Modules CimCmdlets - -Function ConvertFrom-CimInstance { - param( - [Parameter(Mandatory=$true)][CimInstance]$Instance - ) - $hashtable = @{ - _cim_instance = $Instance.CimSystemProperties.ClassName - } - foreach ($prop in $Instance.CimInstanceProperties) { - $hashtable."$($prop.Name)" = ConvertTo-OutputValue -Value $prop.Value - } - return $hashtable -} - -Function ConvertTo-OutputValue { - param($Value) - - if ($Value -is [DateTime[]]) { - $Value = $Value | ForEach-Object { $_.ToString("o") } - } elseif ($Value -is [DateTime]) { - $Value = $Value.ToString("o") - } elseif ($Value -is [Double]) { - $Value = $Value.ToString() # To avoid Python 2 double parsing issues on test validation - } elseif ($Value -is [Double[]]) { - $Value = $Value | ForEach-Object { $_.ToString() } - } elseif ($Value -is [PSCredential]) { - $password = $null - $password_ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Value.Password) - try { - $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($password_ptr) - } finally { - [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($password_ptr) - } - $Value = @{ - username = $Value.Username - password = $password - } - } elseif ($Value -is [CimInstance[]]) { - $value_list = [System.Collections.Generic.List`1[Hashtable]]@() - foreach ($cim_instance in $Value) { - $value_list.Add((ConvertFrom-CimInstance -Instance $cim_instance)) - } - $Value = $value_list.ToArray() - } elseif ($Value -is [CimInstance]) { - $Value = ConvertFrom-CimInstance -Instance $Value - } - - return ,$Value -} - -Function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([Hashtable])] - param( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path - ) - return @{ - Ensure = $Ensure - Path = $Path - } -} - -Function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path, - - [String] $DefaultParam = "Default", - [String] $StringParam, - [String[]] $StringArrayParam, - [SByte] $Int8Param, - [SByte[]] $Int8ArrayParam, - [Byte] $UInt8Param, - [Byte[]] $UInt8ArrayParam, - [Int16] $Int16Param, - [Int16[]] $Int16ArrayParam, - [UInt16] $UInt16Param, - [UInt16[]] $UInt16ArrayParam, - [Int32] $Int32Param, - [Int32[]] $Int32ArrayParam, - [UInt32] $UInt32Param, - [UInt32[]] $UInt32ArrayParam, - [Int64] $Int64Param, - [Int64[]] $Int64ArrayParam, - [UInt64] $UInt64Param, - [UInt64[]] $UInt64ArrayParam, - [Bool] $BooleanParam, - [Bool[]] $BooleanArrayParam, - [Char] $CharParam, - [Char[]] $CharArrayParam, - [Single] $SingleParam, - [Single[]] $SingleArrayParam, - [Double] $DoubleParam, - [Double[]] $DoubleArrayParam, - [DateTime] $DateTimeParam, - [DateTime[]] $DateTimeArrayParam, - [PSCredential] $PSCredentialParam, - [CimInstance[]] $HashtableParam, - [CimInstance] $CimInstanceParam, - [CimInstance[]] $CimInstanceArrayParam, - [CimInstance] $NestedCimInstanceParam, - [CimInstance[]] $NestedCimInstanceArrayParam - ) - - $info = @{ - Version = "1.0.1" - Ensure = @{ - Type = $Ensure.GetType().FullName - Value = $Ensure - } - Path = @{ - Type = $Path.GetType().FullName - Value = $Path - } - DefaultParam = @{ - Type = $DefaultParam.GetType().FullName - Value = $DefaultParam - } - } - - foreach ($kvp in $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator()) { - $info."$($kvp.Key)" = @{ - Type = $kvp.Value.GetType().FullName - Value = (ConvertTo-OutputValue -Value $kvp.Value) - } - } - - if (Test-Path -Path $Path) { - Remove-Item -Path $Path -Force > $null - } - New-Item -Path $Path -ItemType File > $null - Set-Content -Path $Path -Value (ConvertTo-Json -InputObject $info -Depth 10) > $null - Write-Verbose -Message "set verbose" - Write-Warning -Message "set warning" -} - -Function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] $Path, - - [String] $DefaultParam = "Default", - [String] $StringParam, - [String[]] $StringArrayParam, - [SByte] $Int8Param, - [SByte[]] $Int8ArrayParam, - [Byte] $UInt8Param, - [Byte[]] $UInt8ArrayParam, - [Int16] $Int16Param, - [Int16[]] $Int16ArrayParam, - [UInt16] $UInt16Param, - [UInt16[]] $UInt16ArrayParam, - [Int32] $Int32Param, - [Int32[]] $Int32ArrayParam, - [UInt32] $UInt32Param, - [UInt32[]] $UInt32ArrayParam, - [Int64] $Int64Param, - [Int64[]] $Int64ArrayParam, - [UInt64] $UInt64Param, - [UInt64[]] $UInt64ArrayParam, - [Bool] $BooleanParam, - [Bool[]] $BooleanArrayParam, - [Char] $CharParam, - [Char[]] $CharArrayParam, - [Single] $SingleParam, - [Single[]] $SingleArrayParam, - [Double] $DoubleParam, - [Double[]] $DoubleArrayParam, - [DateTime] $DateTimeParam, - [DateTime[]] $DateTimeArrayParam, - [PSCredential] $PSCredentialParam, - [CimInstance[]] $HashtableParam, - [CimInstance] $CimInstanceParam, - [CimInstance[]] $CimInstanceArrayParam, - [CimInstance] $NestedCimInstanceParam, - [CimInstance[]] $NestedCimInstanceArrayParam - ) - Write-Verbose -Message "test verbose" - Write-Warning -Message "test warning" - $exists = Test-Path -LiteralPath $Path -PathType Leaf - if ($Ensure -eq "Present") { - $exists - } else { - -not $exists - } -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof deleted file mode 100644 index 9301664b3c..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof +++ /dev/null @@ -1,63 +0,0 @@ -[ClassVersion("1.0.1")] -class ANSIBLE_xTestClass -{ - [Key] String KeyValue; - [Write, ValueMap{"Choice1", "Choice2"}, Values{"Choice1", "Choice2"}] String Choice; - [Write] String StringValue; - [Write] SInt32 IntValue; - [Write] String StringArrayValue[]; -}; - -[ClassVersion("1.0.1")] -class ANSIBLE_xNestedClass -{ - [Key] String KeyValue; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimValue; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimArrayValue[]; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashValue[]; - [Write] SInt16 IntValue; -}; - -[ClassVersion("1.0.1"), FriendlyName("xTestResource")] -class ANSIBLE_xTestResource : OMI_BaseResource -{ - [Key] String Path; - [Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; - [Read] String ReadParam; - [Write] String DefaultParam; - [Write] String StringParam; - [Write] String StringArrayParam[]; - [Write] SInt8 Int8Param; - [Write] SInt8 Int8ArrayParam[]; - [Write] UInt8 UInt8Param; - [Write] UInt8 UInt8ArrayParam[]; - [Write] SInt16 Int16Param; - [Write] SInt16 Int16ArrayParam[]; - [Write] UInt16 UInt16Param; - [Write] UInt16 UInt16ArrayParam[]; - [Write] SInt32 Int32Param; - [Write] SInt32 Int32ArrayParam[]; - [Write] UInt32 UInt32Param; - [Write] UInt32 UInt32ArrayParam[]; - [Write] SInt64 Int64Param; - [Write] SInt64 Int64ArrayParam[]; - [Write] UInt64 UInt64Param; - [Write] UInt64 UInt64ArrayParam[]; - [Write] Boolean BooleanParam; - [Write] Boolean BooleanArrayParam[]; - [Write] Char16 CharParam; - [Write] Char16 CharArrayParam[]; - [Write] Real32 SingleParam; - [Write] Real32 SingleArrayParam[]; - [Write] Real64 DoubleParam; - [Write] Real64 DoubleArrayParam[]; - [Write] DateTime DateTimeParam; - [Write] DateTime DateTimeArrayParam[]; - [Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashtableParam[]; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceParam; - [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[]; - [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceParam; - [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceArrayParam[]; -}; - diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 deleted file mode 100644 index 0c43b85238..0000000000 --- a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 +++ /dev/null @@ -1,13 +0,0 @@ -@{ - ModuleVersion = '1.0.1' - GUID = '80c895c4-de3f-4d6d-8fa4-c504c96b6f22' - Author = 'Ansible' - CompanyName = 'Ansible' - Copyright = '(c) 2019' - Description = 'Test DSC Resource for Ansible integration tests' - PowerShellVersion = '5.0' - CLRVersion = '4.0' - FunctionsToExport = '*' - CmdletsToExport = '*' -} - diff --git a/test/integration/targets/win_dsc/meta/main.yml b/test/integration/targets/win_dsc/meta/main.yml deleted file mode 100644 index 9f37e96cd9..0000000000 --- a/test/integration/targets/win_dsc/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_dsc/tasks/main.yml b/test/integration/targets/win_dsc/tasks/main.yml deleted file mode 100644 index f37295ab71..0000000000 --- a/test/integration/targets/win_dsc/tasks/main.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- name: get powershell version - win_shell: $PSVersionTable.PSVersion.Major - register: powershell_version - -- name: expect failure when running on old PS hosts - win_dsc: - resource_name: File - register: fail_dsc_old - failed_when: '"This module cannot run as it requires a minimum PowerShell version of 5.0" not in fail_dsc_old.msg' - when: powershell_version.stdout_lines[0]|int < 5 - -- name: run tests when PSv5+ - when: powershell_version.stdout_lines[0]|int >= 5 - block: - - name: add remote temp dir to PSModulePath - win_path: - name: PSModulePath - state: present - scope: machine - elements: - - '{{ remote_tmp_dir }}' - - - name: copy custom DSC resources to remote temp dir - win_copy: - src: xTestDsc - dest: '{{ remote_tmp_dir }}' - - - name: run tests - include_tasks: tests.yml - - always: - - name: remove remote tmp dir from PSModulePath - win_path: - name: PSModulePath - state: absent - scope: machine - elements: - - '{{ remote_tmp_dir }}' diff --git a/test/integration/targets/win_dsc/tasks/tests.yml b/test/integration/targets/win_dsc/tasks/tests.yml deleted file mode 100644 index d2a6802fdf..0000000000 --- a/test/integration/targets/win_dsc/tasks/tests.yml +++ /dev/null @@ -1,544 +0,0 @@ ---- -- name: fail with incorrect DSC resource name - win_dsc: - resource_name: FakeResource - register: fail_invalid_resource - failed_when: fail_invalid_resource.msg != "Resource 'FakeResource' not found." - -- name: fail with invalid DSC version - win_dsc: - resource_name: xTestResource - module_version: 0.0.1 - register: fail_invalid_version - failed_when: 'fail_invalid_version.msg != "Resource ''xTestResource'' with version ''0.0.1'' not found. Versions installed: ''1.0.0'', ''1.0.1''."' - -- name: fail with mandatory option not set - win_dsc: - resource_name: xSetReboot - Value: yes - register: fail_man_key - failed_when: 'fail_man_key.msg != "missing required arguments: KeyParam"' - -- name: fail with mandatory option not set in sub dict - win_dsc: - resource_name: xTestResource - Path: C:\path - Ensure: Present - CimInstanceParam: # Missing KeyValue in dict - Choice: Choice1 - register: fail_man_key_sub_dict - failed_when: 'fail_man_key_sub_dict.msg != "missing required arguments: KeyValue found in CimInstanceParam"' - -- name: fail invalid option - win_dsc: - resource_name: xSetReboot - KeyParam: key - OtherParam: invalid - register: fail_invalid_option - failed_when: 'fail_invalid_option.msg != "Unsupported parameters for (win_dsc) module: OtherParam. Supported parameters include: KeyParam, PsDscRunAsCredential_username, module_version, Value, PsDscRunAsCredential_password, resource_name, DependsOn"' - -- name: fail invalid option in sub dict - win_dsc: - resource_name: xTestResource - Path: C:\path - Ensure: Present - NestedCimInstanceParam: - KeyValue: key - CimValue: - KeyValue: other key - InvalidKey: invalid - register: fail_invalid_option_sub_dict - failed_when: 'fail_invalid_option_sub_dict.msg != "Unsupported parameters for (win_dsc) module: InvalidKey found in NestedCimInstanceParam -> CimValue. Supported parameters include: IntValue, KeyValue, StringArrayValue, Choice, StringValue"' - -- name: fail invalid read only option - win_dsc: - resource_name: xTestResource - Path: C:\path - Ensure: Present - ReadParam: abc - register: fail_invalid_option_read_only - failed_when: '"Unsupported parameters for (win_dsc) module: ReadParam" not in fail_invalid_option_read_only.msg' - -- name: fail invalid choice - win_dsc: - resource_name: xTestResource - Path: C:\path - Ensure: invalid - register: fail_invalid_choice - failed_when: 'fail_invalid_choice.msg != "value of Ensure must be one of: Present, Absent. Got no match for: invalid"' - -- name: fail invalid choice in sub dict - win_dsc: - resource_name: xTestResource - Path: C:\path - Ensure: Present - CimInstanceArrayParam: - - KeyValue: key - - KeyValue: key2 - Choice: Choice3 - register: fail_invalid_choice_sub_dict - failed_when: 'fail_invalid_choice_sub_dict.msg != "value of Choice must be one of: Choice1, Choice2. Got no match for: Choice3 found in CimInstanceArrayParam"' - -- name: fail old version missing new option - win_dsc: - resource_name: xTestResource - module_version: 1.0.0 - Path: C:\path - Ensure: Present - CimInstanceParam: # CimInstanceParam does not exist in the 1.0.0 version - Key: key - register: fail_invalid_option_old - failed_when: '"Unsupported parameters for (win_dsc) module: CimInstanceParam" not in fail_invalid_option_old.msg' - -- name: fail old version missing new option sub dict - win_dsc: - resource_name: xTestResource - module_version: 1.0.0 - Path: C:\path - Ensure: Present - CimInstanceArrayParam: - - Key: key - Choice: Choice1 - register: fail_invalid_option_old_sub_dict - failed_when: 'fail_invalid_option_old_sub_dict.msg != "Unsupported parameters for (win_dsc) module: Choice found in CimInstanceArrayParam. Supported parameters include: Key, IntValue, StringArrayValue, StringValue"' - -- name: create test file (check mode) - win_dsc: - resource_name: File - DestinationPath: '{{ remote_tmp_dir }}\dsc-file' - Contents: file contents - Attributes: - - Hidden - - ReadOnly - Ensure: Present - Type: File - register: create_file_check - check_mode: yes - -- name: get result of create test file (check mode) - win_stat: - path: '{{ remote_tmp_dir }}\dsc-file' - register: create_file_actual_check - -- name: assert create test file (check mode) - assert: - that: - - create_file_check is changed - - create_file_check.module_version == None # Some built in modules don't have a version set - - not create_file_check.reboot_required - - not create_file_actual_check.stat.exists - -- name: assert create test file verbosity (check mode) - assert: - that: - - create_file_check.verbose_test is defined - - not create_file_check.verbose_set is defined - when: ansible_verbosity >= 3 - -- name: create test file - win_dsc: - resource_name: File - DestinationPath: '{{ remote_tmp_dir }}\dsc-file' - Contents: file contents - Attributes: - - Hidden - - ReadOnly - Ensure: Present - Type: File - register: create_file - -- name: get result of create test file - win_stat: - path: '{{ remote_tmp_dir }}\dsc-file' - register: create_file_actual - -- name: assert create test file verbosity - assert: - that: - - create_file.verbose_test is defined - - create_file.verbose_set is defined - when: ansible_verbosity >= 3 - -- name: assert create test file - assert: - that: - - create_file is changed - - create_file.module_version == None - - not create_file.reboot_required - - create_file_actual.stat.exists - - create_file_actual.stat.attributes == "ReadOnly, Hidden, Archive" - - create_file_actual.stat.checksum == 'd48daab51112b49ecabd917adc345b8ba257055e' - -- name: create test file (idempotent) - win_dsc: - resource_name: File - DestinationPath: '{{ remote_tmp_dir }}\dsc-file' - Contents: file contents - Attributes: - - Hidden - - ReadOnly - Ensure: Present - Type: File - register: create_file_again - -- name: assert create test file (idempotent) - assert: - that: - - not create_file_again is changed - - create_file.module_version == None - - not create_file.reboot_required - -- name: get SID of the current Ansible user - win_shell: | - Add-Type -AssemblyName System.DirectoryServices.AccountManagement - [System.DirectoryServices.AccountManagement.UserPrincipal]::Current.Sid.Value - register: actual_sid - -- name: run DSC process as another user - win_dsc: - resource_name: Script - GetScript: '@{ Result= "" }' - SetScript: | - Add-Type -AssemblyName System.DirectoryServices.AccountManagement - $sid = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current.Sid.Value - Set-Content -Path "{{ remote_tmp_dir }}\runas.txt" -Value $sid - TestScript: $false - PsDscRunAsCredential_username: '{{ ansible_user }}' - PsDscRunAsCredential_password: '{{ ansible_password }}' - register: runas_user - -- name: get result of run DSC process as another user - slurp: - path: '{{ remote_tmp_dir }}\runas.txt' - register: runas_user_result - -- name: assert run DSC process as another user - assert: - that: - - runas_user is changed - - runas_user.module_version != None # Can't reliably set the version but we can test it is set - - not runas_user.reboot_required - - runas_user_result.content|b64decode == actual_sid.stdout - -- name: run DSC that sets reboot_required with defaults - win_dsc: - resource_name: xSetReboot - KeyParam: value # Just to satisfy the Resource with key validation - register: set_reboot_defaults - -- name: assert run DSC that sets reboot_required with defaults - assert: - that: - - set_reboot_defaults.reboot_required - -- name: run DSC that sets reboot_required with False - win_dsc: - resource_name: xSetReboot - KeyParam: value - Value: no - register: set_reboot_false - -- name: assert run DSC that sets reboot_required with False - assert: - that: - - not set_reboot_false.reboot_required - -- name: run DSC that sets reboot_required with True - win_dsc: - resource_name: xSetReboot - KeyParam: value - Value: yes - register: set_reboot_true - -- name: assert run DSC that sets reboot_required with True - assert: - that: - - set_reboot_true.reboot_required - -- name: test DSC with all types - win_dsc: - resource_name: xTestResource - Path: '{{ remote_tmp_dir }}\test-types.json' - Ensure: Present - StringParam: string param - StringArrayParam: - - string 1 - - string 2 - Int8Param: 127 # [SByte]::MaxValue - Int8ArrayParam: - - 127 - - '127' - UInt8Param: 255 # [Byte]::MaxValue - UInt8ArrayParam: - - 255 - - '255' - Int16Param: 32767 # [Int16]::MaxValue - Int16ArrayParam: 32767, 32767 - UInt16Param: '65535' # [UInt16]::MaxValue - UInt16ArrayParam: 65535 - Int32Param: 2147483647 # [Int32]::MaxValue - Int32ArrayParam: '2147483647' - UInt32Param: '4294967295' # [UInt32]::MaxValue - UInt32ArrayParam: - - '4294967295' - - 4294967295 - Int64Param: 9223372036854775807 # [Int64]::MaxValue - Int64ArrayParam: - - -9223372036854775808 # [Int64]::MinValue - - 9223372036854775807 - UInt64Param: 18446744073709551615 # [UInt64]::MaxValue - UInt64ArrayParam: - - 0 # [UInt64]::MinValue - - 18446744073709551615 - BooleanParam: True - BooleanArrayParam: - - True - - 'True' - - 'true' - - 'y' - - 'yes' - - 1 - - False - - 'False' - - 'false' - - 'n' - - 'no' - - 0 - CharParam: c - CharArrayParam: - - c - - h - - a - - r - SingleParam: 3.402823E+38 - SingleArrayParam: - - '3.402823E+38' - - 1.2393494 - DoubleParam: 1.79769313486232E+300 - DoubleArrayParam: - - '1.79769313486232E+300' - - 3.56821831681516 - DateTimeParam: '2019-02-22T13:57:31.2311892-04:00' - DateTimeArrayParam: - - '2019-02-22T13:57:31.2311892+00:00' - - '2019-02-22T13:57:31.2311892+04:00' - PSCredentialParam_username: username1 - PSCredentialParam_password: password1 - HashtableParam: - key1: string 1 - key2: '' - key3: 1 - CimInstanceParam: - KeyValue: a - CimInstanceArrayParam: - - KeyValue: b - Choice: Choice1 - StringValue: string 1 - IntValue: 1 - StringArrayValue: - - abc - - def - - KeyValue: c - Choice: Choice2 - StringValue: string 2 - IntValue: '2' - StringArrayValue: - - ghi - - jkl - NestedCimInstanceParam: - KeyValue: key value - CimValue: - KeyValue: d - CimArrayValue: - - KeyValue: e - Choice: Choice2 - HashValue: - a: a - IntValue: '300' - register: dsc_types - -- name: get result of test DSC with all types - slurp: - path: '{{ remote_tmp_dir }}\test-types.json' - register: dsc_types_raw - -- name: convert result of test DSC with all types to dict - set_fact: - dsc_types_actual: '{{ dsc_types_raw.content | b64decode | from_json }}' - -- name: assert test DSC with all types - assert: - that: - - dsc_types is changed - - dsc_types.module_version == '1.0.1' - - not dsc_types.reboot_required - - dsc_types_actual.Version == '1.0.1' - - dsc_types_actual.Verbose.Value.IsPresent - - dsc_types_actual.DefaultParam.Value == 'Default' # ensures that the default is set in the engine if we don't set it outselves - - dsc_types_actual.Ensure.Value == 'Present' - - dsc_types_actual.Path.Value == remote_tmp_dir + "\\test-types.json" - - dsc_types_actual.StringParam.Type == 'System.String' - - dsc_types_actual.StringParam.Value == 'string param' - - dsc_types_actual.StringArrayParam.Type == 'System.String[]' - - dsc_types_actual.StringArrayParam.Value == ['string 1', 'string 2'] - - dsc_types_actual.Int8Param.Type == 'System.SByte' - - dsc_types_actual.Int8Param.Value == 127 - - dsc_types_actual.Int8ArrayParam.Type == 'System.SByte[]' - - dsc_types_actual.Int8ArrayParam.Value == [127, 127] - - dsc_types_actual.UInt8Param.Type == 'System.Byte' - - dsc_types_actual.UInt8Param.Value == 255 - - dsc_types_actual.UInt8ArrayParam.Type == 'System.Byte[]' - - dsc_types_actual.UInt8ArrayParam.Value == [255, 255] - - dsc_types_actual.Int16Param.Type == 'System.Int16' - - dsc_types_actual.Int16Param.Value == 32767 - - dsc_types_actual.Int16ArrayParam.Type == 'System.Int16[]' - - dsc_types_actual.Int16ArrayParam.Value == [32767, 32767] - - dsc_types_actual.UInt16Param.Type == 'System.UInt16' - - dsc_types_actual.UInt16Param.Value == 65535 - - dsc_types_actual.UInt16ArrayParam.Type == 'System.UInt16[]' - - dsc_types_actual.UInt16ArrayParam.Value == [65535] - - dsc_types_actual.Int32Param.Type == 'System.Int32' - - dsc_types_actual.Int32Param.Value == 2147483647 - - dsc_types_actual.Int32ArrayParam.Type == 'System.Int32[]' - - dsc_types_actual.Int32ArrayParam.Value == [2147483647] - - dsc_types_actual.UInt32Param.Type == 'System.UInt32' - - dsc_types_actual.UInt32Param.Value == 4294967295 - - dsc_types_actual.UInt32ArrayParam.Type == 'System.UInt32[]' - - dsc_types_actual.UInt32ArrayParam.Value == [4294967295, 4294967295] - - dsc_types_actual.Int64Param.Type == 'System.Int64' - - dsc_types_actual.Int64Param.Value == 9223372036854775807 - - dsc_types_actual.Int64ArrayParam.Type == 'System.Int64[]' - - dsc_types_actual.Int64ArrayParam.Value == [-9223372036854775808, 9223372036854775807] - - dsc_types_actual.UInt64Param.Type == 'System.UInt64' - - dsc_types_actual.UInt64Param.Value == 18446744073709551615 - - dsc_types_actual.UInt64ArrayParam.Type == 'System.UInt64[]' - - dsc_types_actual.UInt64ArrayParam.Value == [0, 18446744073709551615] - - dsc_types_actual.BooleanParam.Type == 'System.Boolean' - - dsc_types_actual.BooleanParam.Value == True - - dsc_types_actual.BooleanArrayParam.Type == 'System.Boolean[]' - - dsc_types_actual.BooleanArrayParam.Value == [True, True, True, True, True, True, False, False, False, False, False, False] - - dsc_types_actual.CharParam.Type == 'System.Char' - - dsc_types_actual.CharParam.Value == 'c' - - dsc_types_actual.CharArrayParam.Type == 'System.Char[]' - - dsc_types_actual.CharArrayParam.Value == ['c', 'h', 'a', 'r'] - - dsc_types_actual.SingleParam.Type == 'System.Single' - - dsc_types_actual.SingleParam.Value|string == '3.402823e+38' - - dsc_types_actual.SingleArrayParam.Type == 'System.Single[]' - - dsc_types_actual.SingleArrayParam.Value|length == 2 - - dsc_types_actual.SingleArrayParam.Value[0]|string == '3.402823e+38' - - dsc_types_actual.SingleArrayParam.Value[1]|string == '1.23934937' - - dsc_types_actual.DoubleParam.Type == 'System.Double' - - dsc_types_actual.DoubleParam.Value == '1.79769313486232E+300' - - dsc_types_actual.DoubleArrayParam.Type == 'System.Double[]' - - dsc_types_actual.DoubleArrayParam.Value|length == 2 - - dsc_types_actual.DoubleArrayParam.Value[0] == '1.79769313486232E+300' - - dsc_types_actual.DoubleArrayParam.Value[1] == '3.56821831681516' - - dsc_types_actual.DateTimeParam.Type == 'System.DateTime' - - dsc_types_actual.DateTimeParam.Value == '2019-02-22T17:57:31.2311890+00:00' - - dsc_types_actual.DateTimeArrayParam.Type == 'System.DateTime[]' - - dsc_types_actual.DateTimeArrayParam.Value == ['2019-02-22T13:57:31.2311890+00:00', '2019-02-22T09:57:31.2311890+00:00'] - - dsc_types_actual.PSCredentialParam.Type == 'System.Management.Automation.PSCredential' - - dsc_types_actual.PSCredentialParam.Value.username == 'username1' - - dsc_types_actual.PSCredentialParam.Value.password == 'password1' - # Hashtable is actually a CimInstance[] of MSFT_KeyValuePairs - - dsc_types_actual.HashtableParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]' - - dsc_types_actual.HashtableParam.Value|length == 3 - # Can't guarantee the order of the keys so just check they are the values they could be - - dsc_types_actual.HashtableParam.Value[0].Key in ["key1", "key2", "key3"] - - dsc_types_actual.HashtableParam.Value[0].Value in ["string 1", "1", ""] - - dsc_types_actual.HashtableParam.Value[0]._cim_instance == 'MSFT_KeyValuePair' - - dsc_types_actual.HashtableParam.Value[1].Key in ["key1", "key2", "key3"] - - dsc_types_actual.HashtableParam.Value[1].Value in ["string 1", "1", ""] - - dsc_types_actual.HashtableParam.Value[1]._cim_instance == 'MSFT_KeyValuePair' - - dsc_types_actual.HashtableParam.Value[2].Key in ["key1", "key2", "key3"] - - dsc_types_actual.HashtableParam.Value[2].Value in ["string 1", "1", ""] - - dsc_types_actual.HashtableParam.Value[2]._cim_instance == 'MSFT_KeyValuePair' - - dsc_types_actual.CimInstanceParam.Type == 'Microsoft.Management.Infrastructure.CimInstance' - - dsc_types_actual.CimInstanceParam.Value.Choice == None - - dsc_types_actual.CimInstanceParam.Value.IntValue == None - - dsc_types_actual.CimInstanceParam.Value.KeyValue == 'a' - - dsc_types_actual.CimInstanceParam.Value.StringArrayValue == None - - dsc_types_actual.CimInstanceParam.Value.StringValue == None - - dsc_types_actual.CimInstanceParam.Value._cim_instance == "ANSIBLE_xTestClass" - - dsc_types_actual.CimInstanceArrayParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]' - - dsc_types_actual.CimInstanceArrayParam.Value|length == 2 - - dsc_types_actual.CimInstanceArrayParam.Value[0].Choice == 'Choice1' - - dsc_types_actual.CimInstanceArrayParam.Value[0].IntValue == 1 - - dsc_types_actual.CimInstanceArrayParam.Value[0].KeyValue == 'b' - - dsc_types_actual.CimInstanceArrayParam.Value[0].StringArrayValue == ['abc', 'def'] - - dsc_types_actual.CimInstanceArrayParam.Value[0].StringValue == 'string 1' - - dsc_types_actual.CimInstanceArrayParam.Value[0]._cim_instance == 'ANSIBLE_xTestClass' - - dsc_types_actual.CimInstanceArrayParam.Value[1].Choice == 'Choice2' - - dsc_types_actual.CimInstanceArrayParam.Value[1].IntValue == 2 - - dsc_types_actual.CimInstanceArrayParam.Value[1].KeyValue == 'c' - - dsc_types_actual.CimInstanceArrayParam.Value[1].StringArrayValue == ['ghi', 'jkl'] - - dsc_types_actual.CimInstanceArrayParam.Value[1].StringValue == 'string 2' - - dsc_types_actual.CimInstanceArrayParam.Value[1]._cim_instance == 'ANSIBLE_xTestClass' - - dsc_types_actual.NestedCimInstanceParam.Type == 'Microsoft.Management.Infrastructure.CimInstance' - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue|length == 1 - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].Choice == 'Choice2' - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].IntValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].KeyValue == 'e' - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].StringArrayValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].StringValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0]._cim_instance == 'ANSIBLE_xTestClass' - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.Choice == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.IntValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.KeyValue == 'd' - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.StringArrayValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.StringValue == None - - dsc_types_actual.NestedCimInstanceParam.Value.CimValue._cim_instance == 'ANSIBLE_xTestClass' - - dsc_types_actual.NestedCimInstanceParam.Value.HashValue|length == 1 - - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0].Key == 'a' - - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0].Value == 'a' - - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0]._cim_instance == 'MSFT_KeyValuePair' - - dsc_types_actual.NestedCimInstanceParam.Value.IntValue == 300 - - dsc_types_actual.NestedCimInstanceParam.Value.KeyValue == 'key value' - - dsc_types_actual.NestedCimInstanceParam.Value._cim_instance == 'ANSIBLE_xNestedClass' - -- name: test DSC with all types older version - win_dsc: - resource_name: xTestResource - module_version: 1.0.0 - Path: '{{ remote_tmp_dir }}\test-types.json' - Ensure: Absent - StringParam: string param old - CimInstanceArrayParam: - - Key: old key - StringValue: string old 1 - IntValue: 0 - StringArrayValue: - - zyx - - wvu - register: dsc_types_old - -- name: get result of test DSC with all types older version - slurp: - path: '{{ remote_tmp_dir }}\test-types.json' - register: dsc_types_old_raw - -- name: convert result of test DSC with all types to dict - set_fact: - dsc_types_old_actual: '{{ dsc_types_old_raw.content | b64decode | from_json }}' - -- name: assert test DSC with all types older version - assert: - that: - - dsc_types_old is changed - - dsc_types_old.module_version == '1.0.0' - - not dsc_types_old.reboot_required - - dsc_types_old_actual.Version == '1.0.0' - - dsc_types_old_actual.Verbose.Value.IsPresent - - dsc_types_old_actual.DefaultParam.Value == 'Default' - - dsc_types_old_actual.Ensure.Value == 'Absent' - - dsc_types_old_actual.Path.Value == remote_tmp_dir + "\\test-types.json" - - dsc_types_old_actual.StringParam.Type == 'System.String' - - dsc_types_old_actual.StringParam.Value == 'string param old' - - dsc_types_old_actual.CimInstanceArrayParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]' - - dsc_types_old_actual.CimInstanceArrayParam.Value|length == 1 - - not dsc_types_old_actual.CimInstanceArrayParam.Value[0].Choice is defined # 1.0.0 does not have a Choice option - - dsc_types_old_actual.CimInstanceArrayParam.Value[0].IntValue == 0 - - dsc_types_old_actual.CimInstanceArrayParam.Value[0].Key == 'old key' - - dsc_types_old_actual.CimInstanceArrayParam.Value[0].StringArrayValue == ['zyx', 'wvu'] - - dsc_types_old_actual.CimInstanceArrayParam.Value[0].StringValue == 'string old 1' - - dsc_types_old_actual.CimInstanceArrayParam.Value[0]._cim_instance == 'ANSIBLE_xTestClass' diff --git a/test/integration/targets/win_environment/aliases b/test/integration/targets/win_environment/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_environment/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_environment/defaults/main.yml b/test/integration/targets/win_environment/defaults/main.yml deleted file mode 100644 index 0eb44ae991..0000000000 --- a/test/integration/targets/win_environment/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ -test_environment_name: TEST_VALUE -test_machine_environment_value: "%SystemRoot%\\System32" -test_new_machine_environment_value: C:\Windows\System32 -test_user_environment_value: C:\Program Files -test_new_user_environment_value: C:\Program Files (x86) diff --git a/test/integration/targets/win_environment/tasks/main.yml b/test/integration/targets/win_environment/tasks/main.yml deleted file mode 100644 index 34f46f3bb3..0000000000 --- a/test/integration/targets/win_environment/tasks/main.yml +++ /dev/null @@ -1,267 +0,0 @@ ---- -- name: ensure test environment value is not set in all scope - win_environment: - name: "{{test_environment_name}}" - state: absent - level: "{{item}}" - with_items: - - machine - - process - - user - -- name: fail to create environment value with null value - win_environment: - name: "{{test_environment_name}}" - state: present - level: machine - register: create_fail_null - failed_when: 'create_fail_null.msg != "state is present but all of the following are missing: value"' - -- name: fail to create environment value with empty value - win_environment: - name: "{{test_environment_name}}" - value: '' - state: present - level: machine - register: create_fail_empty_string - failed_when: create_fail_empty_string.msg != "When state=present, value must be defined and not an empty string, if you wish to remove the envvar, set state=absent" - -- name: create test environment value for machine check - win_environment: - name: "{{test_environment_name}}" - value: "{{test_machine_environment_value}}" - state: present - level: machine - register: create_machine_check - check_mode: True - -- name: get value of environment key for machine after changing check - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_machine_check_actual - -- name: assert change test environment value for machine check - assert: - that: - - create_machine_check is changed - - create_machine_check_actual.stdout == "" - -- name: create test environment value for machine - win_environment: - name: "{{test_environment_name}}" - value: "{{test_machine_environment_value}}" - state: present - level: machine - register: create_machine - -- name: get value of environment key for machine after changing - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_machine_actual - -- name: assert test environment value for machine - assert: - that: - - create_machine is changed - - create_machine.before_value == None - - create_machine_actual.stdout == "{{test_machine_environment_value}}\r\n" - -- name: create test environment value for machine again - win_environment: - name: "{{test_environment_name}}" - value: "{{test_machine_environment_value}}" - state: present - level: machine - register: create_machine_again - -- name: get value of environment key for machine after changing again - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_machine_actual_again - -- name: assert create test environment value for machine again - assert: - that: - - create_machine_again is not changed - - create_machine_again.before_value == test_machine_environment_value - - create_machine_actual_again.stdout == "{{test_machine_environment_value}}\r\n" - -- name: change test environment value for machine check - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_machine_environment_value}}" - state: present - level: machine - register: change_machine_check - check_mode: True - -- name: get value of environment key for machine after changing check - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_machine_actual_check - -- name: assert change test environment value for machine check - assert: - that: - - change_machine_check is changed - - change_machine_check.before_value == test_machine_environment_value - - change_machine_actual_check.stdout == "{{test_machine_environment_value}}\r\n" - -- name: change test environment value for machine - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_machine_environment_value}}" - state: present - level: machine - register: change_machine - -- name: get value of environment key for machine after changing - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_machine_actual - -- name: assert change test environment value for machine - assert: - that: - - change_machine is changed - - change_machine.before_value == test_machine_environment_value - - change_machine_actual.stdout == "{{test_new_machine_environment_value}}\r\n" - -- name: change test environment value for machine again - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_machine_environment_value}}" - state: present - level: machine - register: change_machine_again - -- name: get value of environment key for machine after changing again - win_command: powershell.exe "[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_machine_actual_again - -- name: assert change test environment value for machine again - assert: - that: - - change_machine_again is not changed - - change_machine_again.before_value == test_new_machine_environment_value - - change_machine_actual_again.stdout == "{{test_new_machine_environment_value}}\r\n" - -- name: create test environment value for user check - win_environment: - name: "{{test_environment_name}}" - value: "{{test_user_environment_value}}" - state: present - level: user - register: create_user_check - check_mode: True - -- name: get value of environment key for user after changing check - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_user_check_actual - -- name: assert change test environment value for user check - assert: - that: - - create_user_check is changed - - create_user_check_actual.stdout == "" - -- name: create test environment value for user - win_environment: - name: "{{test_environment_name}}" - value: "{{test_user_environment_value}}" - state: present - level: user - register: create_user - -- name: get value of environment key for user after changing - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_user_actual - -- name: assert test environment value for user - assert: - that: - - create_user is changed - - create_user.before_value == None - - create_user_actual.stdout == "{{test_user_environment_value}}\r\n" - -- name: create test environment value for user again - win_environment: - name: "{{test_environment_name}}" - value: "{{test_user_environment_value}}" - state: present - level: user - register: create_user_again - -- name: get value of environment key for user after changing again - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: create_user_actual_again - -- name: assert create test environment value for user again - assert: - that: - - create_user_again is not changed - - create_user_again.before_value == test_user_environment_value - - create_user_actual_again.stdout == "{{test_user_environment_value}}\r\n" - -- name: change test environment value for user check - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_user_environment_value}}" - state: present - level: user - register: change_user_check - check_mode: True - -- name: get value of environment key for user after changing check - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_user_actual_check - -- name: assert change test environment value for user check - assert: - that: - - change_user_check is changed - - change_user_check.before_value == test_user_environment_value - - change_user_actual_check.stdout == "{{test_user_environment_value}}\r\n" - -- name: change test environment value for user - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_user_environment_value}}" - state: present - level: user - register: change_user - -- name: get value of environment key for user after changing - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_user_actual - -- name: assert change test environment value for user - assert: - that: - - change_user is changed - - change_user.before_value == test_user_environment_value - - change_user_actual.stdout == "{{test_new_user_environment_value}}\r\n" - -- name: change test environment value for user again - win_environment: - name: "{{test_environment_name}}" - value: "{{test_new_user_environment_value}}" - state: present - level: user - register: change_user_again - -- name: get value of environment key for user after changing again - win_command: powershell.exe "[Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true).GetValue('{{test_environment_name}}', $null, 'DoNotExpandEnvironmentNames')" - register: change_user_actual_again - -- name: assert change test environment value for user again - assert: - that: - - change_user_again is not changed - - change_user_again.before_value == test_new_user_environment_value - - change_user_actual_again.stdout == "{{test_new_user_environment_value}}\r\n" - -- name: cleanup test changes - win_environment: - name: "{{test_environment_name}}" - state: absent - level: "{{item}}" - with_items: - - machine - - process - - user diff --git a/test/integration/targets/win_feature/aliases b/test/integration/targets/win_feature/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_feature/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_feature/defaults/main.yml b/test/integration/targets/win_feature/defaults/main.yml deleted file mode 100644 index e1833cd8a8..0000000000 --- a/test/integration/targets/win_feature/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -# Feature not normally installed by default. -test_win_feature_name: Telnet-Client diff --git a/test/integration/targets/win_feature/tasks/main.yml b/test/integration/targets/win_feature/tasks/main.yml deleted file mode 100644 index a52b3c0160..0000000000 --- a/test/integration/targets/win_feature/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -# test code for the win_feature module -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - - -- name: check whether servermanager module is available (windows 2008 r2 or later) - win_shell: if (Get-Command -Name Add-WindowsFeature -ErrorAction SilentlyContinue) { $true } else { $false } - changed_when: False - register: win_feature_has_servermanager - -- name: run tests - include_tasks: tests.yml - when: win_feature_has_servermanager.stdout | trim | bool diff --git a/test/integration/targets/win_feature/tasks/tests.yml b/test/integration/targets/win_feature/tasks/tests.yml deleted file mode 100644 index 7a48117b70..0000000000 --- a/test/integration/targets/win_feature/tasks/tests.yml +++ /dev/null @@ -1,127 +0,0 @@ -# test code for the win_feature module -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: start with feature absent - win_feature: - name: "{{ test_win_feature_name }}" - state: absent - -- name: install feature - win_feature: - name: "{{ test_win_feature_name }}" - state: present - include_sub_features: yes - include_management_tools: yes - register: win_feature_install_result - -- name: check result of installing feature - assert: - that: - - "win_feature_install_result is changed" - - "win_feature_install_result.success" - - "win_feature_install_result.exitcode == 'Success'" - - "not win_feature_install_result.reboot_required" - - "win_feature_install_result.feature_result|length == 1" - - "win_feature_install_result.feature_result[0].id" - - "win_feature_install_result.feature_result[0].display_name" - - "win_feature_install_result.feature_result[0].message is defined" - - "win_feature_install_result.feature_result[0].reboot_required is defined" - - "win_feature_install_result.feature_result[0].skip_reason" - - "win_feature_install_result.feature_result[0].success is defined" - -- name: install feature again - win_feature: - name: "{{ test_win_feature_name }}" - state: present - include_sub_features: yes - include_management_tools: yes - register: win_feature_install_again_result - -- name: check result of installing feature again - assert: - that: - - "win_feature_install_again_result is not changed" - - "win_feature_install_again_result.success" - - "win_feature_install_again_result.exitcode == 'NoChangeNeeded'" - - "not win_feature_install_again_result.reboot_required" - - "win_feature_install_again_result.feature_result == []" - -- name: remove feature - win_feature: - name: "{{ test_win_feature_name }}" - state: absent - register: win_feature_remove_result - -- name: check result of removing feature - assert: - that: - - "win_feature_remove_result is changed" - - "win_feature_remove_result.success" - - "win_feature_remove_result.exitcode == 'Success'" - - "not win_feature_remove_result.reboot_required" - - "win_feature_remove_result.feature_result|length == 1" - - "win_feature_remove_result.feature_result[0].id" - - "win_feature_remove_result.feature_result[0].display_name" - - "win_feature_remove_result.feature_result[0].message is defined" - - "win_feature_remove_result.feature_result[0].reboot_required is defined" - - "win_feature_remove_result.feature_result[0].skip_reason" - - "win_feature_remove_result.feature_result[0].success is defined" - when: win_feature_has_servermanager is successful - -- name: remove feature again - win_feature: - name: "{{ test_win_feature_name }}" - state: absent - register: win_feature_remove_again_result - -- name: check result of removing feature again - assert: - that: - - "win_feature_remove_again_result is not changed" - - "win_feature_remove_again_result.success" - - "win_feature_remove_again_result.exitcode == 'NoChangeNeeded'" - - "not win_feature_remove_again_result.reboot_required" - - "win_feature_remove_again_result.feature_result == []" - -- name: try to install an invalid feature name - win_feature: - name: "Microsoft-Bob" - state: present - register: win_feature_install_invalid_result - ignore_errors: true - -- name: check result of installing invalid feature name - assert: - that: - - "win_feature_install_invalid_result is failed" - - "win_feature_install_invalid_result is not changed" - - "'The name was not found' in win_feature_install_invalid_result.msg" - -- name: try to remove an invalid feature name - win_feature: - name: "Microsoft-Bob" - state: absent - register: win_feature_remove_invalid_result - ignore_errors: true - -- name: check result of removing invalid feature name - assert: - that: - - "win_feature_remove_invalid_result is failed" - - "win_feature_remove_invalid_result is not changed" - - "'The name was not found' in win_feature_remove_invalid_result.msg" diff --git a/test/integration/targets/win_file/aliases b/test/integration/targets/win_file/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_file/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_file/files/foo.txt b/test/integration/targets/win_file/files/foo.txt deleted file mode 100644 index 7c6ded14ec..0000000000 --- a/test/integration/targets/win_file/files/foo.txt +++ /dev/null @@ -1 +0,0 @@ -foo.txt diff --git a/test/integration/targets/win_file/files/foobar/directory/fileC b/test/integration/targets/win_file/files/foobar/directory/fileC deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/integration/targets/win_file/files/foobar/directory/fileC +++ /dev/null diff --git a/test/integration/targets/win_file/files/foobar/directory/fileD b/test/integration/targets/win_file/files/foobar/directory/fileD deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/integration/targets/win_file/files/foobar/directory/fileD +++ /dev/null diff --git a/test/integration/targets/win_file/files/foobar/fileA b/test/integration/targets/win_file/files/foobar/fileA deleted file mode 100644 index ab47708c98..0000000000 --- a/test/integration/targets/win_file/files/foobar/fileA +++ /dev/null @@ -1 +0,0 @@ -fileA diff --git a/test/integration/targets/win_file/files/foobar/fileB b/test/integration/targets/win_file/files/foobar/fileB deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/integration/targets/win_file/files/foobar/fileB +++ /dev/null diff --git a/test/integration/targets/win_file/meta/main.yml b/test/integration/targets/win_file/meta/main.yml deleted file mode 100644 index d328716dfa..0000000000 --- a/test/integration/targets/win_file/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_file/tasks/main.yml b/test/integration/targets/win_file/tasks/main.yml deleted file mode 100644 index c528888665..0000000000 --- a/test/integration/targets/win_file/tasks/main.yml +++ /dev/null @@ -1,614 +0,0 @@ -# Test code for the file module. -# (c) 2014, Richard Isaacson <richard.c.isaacson@gmail.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- set_fact: output_file={{win_output_dir}}\\foo.txt - -- name: prep with a basic win copy - win_copy: src=foo.txt dest={{output_file}} - -- name: verify that we are checking a file and it is present - win_file: path={{output_file}} state=file - register: file_result - -- name: verify that the file was marked as changed - assert: - that: - - "file_result.changed == false" -# - "file_result.state == 'file'" - -- name: verify that we are checking an absent file - win_file: path={{win_output_dir}}/bar.txt state=absent - register: file2_result - -- name: verify that the file was marked as changed - assert: - that: - - "file2_result.changed == false" -# - "file2_result.state == 'absent'" - -- name: verify we can touch a file (check) - win_file: - path: '{{win_output_dir}}\touch.txt' - state: touch - register: touch_file_check - check_mode: yes - -- name: get details of touched file (check) - win_stat: - path: '{{win_output_dir}}\touch.txt' - register: touch_file_actual_check - -- name: assert touch a file (check) - assert: - that: - - touch_file_check.changed - - not touch_file_actual_check.stat.exists - -- name: verify we can touch a file - win_file: path={{win_output_dir}}/touch.txt state=touch - register: touch_file - -- name: get details of touched file - win_stat: - path: '{{win_output_dir}}\touch.txt' - register: touch_file_actual - -- name: assert touch a file - assert: - that: - - touch_file.changed - - touch_file_actual.stat.exists - - touch_file_actual.stat.size == 0 - -- name: touch a file again - win_file: - path: '{{win_output_dir}}\touch.txt' - state: touch - register: touch_file_again - -- name: get details of touched file again - win_stat: - path: '{{win_output_dir}}\touch.txt' - register: touch_file_actual_again - -- name: assert touch a file again - assert: - that: - - touch_file_again.changed - - touch_file_actual_again.stat.lastwritetime > touch_file_actual.stat.lastwritetime - -- name: touch an existing file in check mode - win_file: - path: '{{win_output_dir}}\touch.txt' - state: touch - register: touch_file_again_check - check_mode: yes - -- name: get details of touched file in check mode - win_stat: - path: '{{win_output_dir}}\touch.txt' - register: touch_file_again_actual_check - -- name: assert touch an existing file in check mode - assert: - that: - - touch_file_again_check.changed - - touch_file_again_actual_check.stat.lastwritetime == touch_file_actual_again.stat.lastwritetime - -#- name: change file mode -# win_file: path={{win_output_dir}}/baz.txt mode=0600 -# register: file4_result - -#- name: verify that the file was marked as changed -# assert: -# that: -# - "file4_result.changed == true" -# - "file4_result.mode == '0600'" -# -#- name: change ownership and group -# win_file: path={{win_output_dir}}/baz.txt owner=1234 group=1234 -# -#- name: setup a tmp-like directory for ownership test -# win_file: path=/tmp/worldwritable mode=1777 state=directory - -#- name: Ask to create a file without enough perms to change ownership -# win_file: path=/tmp/worldwritable/baz.txt state=touch owner=root -# become: yes -# become_user: nobody -# register: chown_result -# ignore_errors: True - -#- name: Ask whether the new file exists -# win_stat: path=/tmp/worldwritable/baz.txt -# register: file_exists_result - -#- name: Verify that the file doesn't exist on failure -# assert: -# that: -# - "chown_result.failed == True" -# - "file_exists_result.stat.exists == False" -# -#- name: clean up -# win_file: path=/tmp/worldwritable state=absent - -#- name: create soft link to file -# win_file: src={{output_file}} dest={{win_output_dir}}/soft.txt state=link -# register: file5_result - -#- name: verify that the file was marked as changed -# assert: -# that: -# - "file5_result.changed == true" -# -#- name: create hard link to file -# win_file: src={{output_file}} dest={{win_output_dir}}/hard.txt state=hard -# register: file6_result -# -#- name: verify that the file was marked as changed -# assert: -# that: -# - "file6_result.changed == true" -# -- name: create a directory - win_file: path={{win_output_dir}}/foobar state=directory - register: file7_result - -- debug: var=file7_result - -- name: verify that the file was marked as changed - assert: - that: - - "file7_result.changed == true" -# - "file7_result.state == 'directory'" - -# windows and selinux unlikely to ever mix, removing these tests: -#- name: determine if selinux is installed -# shell: which getenforce || exit 0 -# register: selinux_installed - -#- name: determine if selinux is enabled -# shell: getenforce -# register: selinux_enabled -# when: selinux_installed.stdout != "" -# ignore_errors: true - -#- name: decide to include or not include selinux tests -# include: selinux_tests.yml -# when: selinux_installed.stdout != "" and selinux_enabled.stdout != "Disabled" - -- name: remote directory foobar - win_file: path={{win_output_dir}}/foobar state=absent - -- name: remove file foo.txt - win_file: path={{win_output_dir}}/foo.txt state=absent - -- name: remove file bar.txt - win_file: path={{win_output_dir}}/foo.txt state=absent - -- name: remove file baz.txt - win_file: path={{win_output_dir}}/foo.txt state=absent - -- name: win copy directory structure over - win_copy: src=foobar dest={{win_output_dir}} - -- name: remove directory foobar - win_file: path={{win_output_dir}}/foobar state=absent - register: file14_result - -- debug: var=file14_result - -- name: verify that the directory was removed - assert: - that: - - 'file14_result.changed == true' -# - 'file14_result.state == "absent"' - -- name: create a test sub-directory - win_file: dest={{win_output_dir}}/sub1 state=directory - register: file15_result - -- name: verify that the new directory was created - assert: - that: - - 'file15_result.changed == true' -# - 'file15_result.state == "directory"' - -- name: create test files in the sub-directory - win_file: dest={{win_output_dir}}/sub1/{{item}} state=touch - with_items: - - file1 - - file2 - - file3 - register: file16_result - -- name: verify the files were created - assert: - that: - - 'item.changed == true' -# - 'item.state == "file"' - with_items: "{{file16_result.results}}" - -#- name: try to force the sub-directory to a link -# win_file: src={{win_output_dir}}/testing dest={{win_output_dir}}/sub1 state=link force=yes -# register: file17_result -# ignore_errors: true - -#- name: verify the directory was not replaced with a link -# assert: -# that: -# - 'file17_result.failed == true' -# - 'file17_result.state == "directory"' - -#- name: create soft link to directory using absolute path -# win_file: src=/ dest={{win_output_dir}}/root state=link -# register: file18_result -# -#- name: verify that the result was marked as changed -# assert: -# that: -# - "file18_result.changed == true" -# -- name: create another test sub-directory - win_file: dest={{win_output_dir}}/sub2 state=directory - register: file19_result - -- name: verify that the new directory was created - assert: - that: - - 'file19_result.changed == true' -# - 'file19_result.state == "directory"' - -#- name: create soft link to relative file -# win_file: src=../sub1/file1 dest={{win_output_dir}}/sub2/link1 state=link -# register: file20_result -# -#- name: verify that the result was marked as changed -# assert: -# that: -# - "file20_result.changed == true" - -#- name: create soft link to relative directory -# win_file: src=sub1 dest={{win_output_dir}}/sub1-link state=link -# register: file21_result -# -#- name: verify that the result was marked as changed -# assert: -# that: -# - "file21_result.changed == true" -# -#- name: test file creation with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u=rwx,g=rwx,o=rwx -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0777' - -#- name: modify symbolic mode for all -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=a=r -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0444' - -#- name: modify symbolic mode for owner -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u+w -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0644' - -#- name: modify symbolic mode for group -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=g+w -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0664' -# -#- name: modify symbolic mode for world -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=o+w -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0666' -# -#- name: modify symbolic mode for owner -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u+x -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0766' -## -#- name: modify symbolic mode for group -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=g+x -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0776' -# -#- name: modify symbolic mode for world -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=o+x -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0777' - -#- name: remove symbolic mode for world -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=o-wx -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0774' -# -#- name: remove symbolic mode for group -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=g-wx -# register: result -# -#- name: assert file mode -### assert: -# that: -# - result.mode == '0744' - -#- name: remove symbolic mode for owner -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u-wx -# register: result - -#- name: assert file mode -# assert: -# that: -# - result.mode == '0444' -# -#- name: set sticky bit with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=o+t -# register: result - -#- name: assert file mode -# assert: -# that: -# - result.mode == '01444' -# -#- name: remove sticky bit with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=o-t -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0444' - -#- name: add setgid with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=g+s -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '02444' -# -#- name: remove setgid with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=g-s -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0444' - -#- name: add setuid with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u+s -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '04444' - -#- name: remove setuid with symbolic mode -# win_file: dest={{win_output_dir}}/test_symbolic state=touch mode=u-s -# register: result -# -#- name: assert file mode -# assert: -# that: -# - result.mode == '0444' - -# test the file module using follow=yes, so that the target of a -# symlink is modified, rather than the link itself - -#- name: create a test file -# win_copy: dest={{win_output_dir}}\test_follow content="this is a test file\n" mode=0666 - -#- name: create a symlink to the test file -# win_file: path={{win_output_dir}}\test_follow_link src="./test_follow" state=link -# -#- name: modify the permissions on the link using follow=yes -# win_file: path={{win_output_dir}}\test_follow_link mode=0644 follow=yes -# register: result - -#- name: assert that the chmod worked -# assert: -# that: -# - result.changed -# -#- name: stat the link target -# win_stat: path={{win_output_dir}}/test_follow -# register: result -# -#- name: assert that the link target was modified correctly -# assert: -# that: -## - result.stat.mode == '0644' - -- name: create a directory - win_file: path={{win_output_dir}}/dirtest state=directory - register: file_result - -- name: stat the directory created - win_stat: path={{win_output_dir}}/dirtest - register: stat_result - -- name: assert the directory was created - assert: - that: - - file_result.changed - - stat_result.stat.exists - - stat_result.stat.isdir - -- name: re run create directory (bug 2147) - win_file: path={{win_output_dir}}/dirtest state=directory - register: file_result - -- name: stat the directory created again - win_stat: path={{win_output_dir}}/dirtest - register: stat_result - -- name: assert the directory exists but was not changed - assert: - that: - - file_result.changed == False - - stat_result.stat.exists - - stat_result.stat.isdir - -- name: remove empty dir we just created - win_file: path={{win_output_dir}}/dirtest state=absent - register: file_result - -- name: stat the removed directory - win_stat: path={{win_output_dir}}/dirtest - register: stat_result - -- name: assert the directory does not exist - assert: - that: - - file_result.changed - - "stat_result.stat.exists == False" - -- name: create dir with spaces and parens in the dir name - win_file: - path: '{{win_output_dir}}\dir with spaces (and parens) [block]' - state: directory - register: file_result - -- name: stat the directory with spaces and parens - win_stat: - path: '{{win_output_dir}}\dir with spaces (and parens) [block]' - register: stat_result - -- name: check dir with spaces and parens in the dir name has been created - assert: - that: - - file_result.changed - - stat_result.stat.exists - - stat_result.stat.isdir - -- name: create file in dir with special char - win_file: - path: '{{win_output_dir}}\dir with spaces (and parens) [block]\file[1].txt' - state: touch - register: file_result - -- name: stat the file with spaces and parens - win_stat: - path: '{{win_output_dir}}\dir with spaces (and parens) [block]\file[1].txt' - register: stat_result - -- name: check file in dir with spaces and parens exist - assert: - that: - - file_result.changed - - stat_result.stat.exists - - stat_result.stat.isreg - -- name: remove dir with spaces and parens in the dir name - win_file: - path: '{{win_output_dir}}/dir with spaces (and parens) [block]' - state: absent - register: file_result - -- name: stat the dir with spaces and parens in the dir name - win_stat: - path: '{{win_output_dir}}\dir with spaces (and parens) [block]' - register: stat_result - -- name: assert dir with spaces and parens in the dir name was removed - assert: - that: - - file_result.changed - - "stat_result.stat.exists == False" - -# Need to use shell to create the file as win_file doesn't support setting attributes -- name: create hidden file - win_shell: $file = New-Item -Path "{{ win_output_dir }}\hidden.txt" -ItemType File; $file.Attributes = "Hidden" - -- name: delete hidden file - win_file: - path: '{{ win_output_dir }}\hidden.txt' - state: absent - register: delete_hidden - -- name: get result of delete hidden file - win_stat: - path: '{{ win_output_dir }}\hidden.txt' - register: delete_hidden_actual - -- name: assert delete hidden file - assert: - that: - - delete_hidden is changed - - not delete_hidden_actual.stat.exists - -- name: create folder to point set symbolic link for - win_file: - path: "{{win_output_dir}}/link-test/link-target" - state: directory - -- name: create symbolic link - win_command: cmd.exe /c mklink /d "{{win_output_dir}}\link-test\link" "{{win_output_dir}}\link-test\link-target" - -- name: remove symbolic link target - win_file: - path: "{{win_output_dir}}/link-test/link-target" - state: absent - -- name: remove parent folder with broken link - win_file: - path: "{{win_output_dir}}/link-test" - state: absent - -- name: clean up sub1 - win_file: path={{win_output_dir}}/sub1 state=absent - -- name: clean up sub2 - win_file: path={{win_output_dir}}/sub2 state=absent diff --git a/test/integration/targets/win_find/aliases b/test/integration/targets/win_find/aliases deleted file mode 100644 index 215e0b0692..0000000000 --- a/test/integration/targets/win_find/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_find/defaults/main.yml b/test/integration/targets/win_find/defaults/main.yml deleted file mode 100644 index fc2e2e1179..0000000000 --- a/test/integration/targets/win_find/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -win_find_dir: '{{ win_output_dir }}\win_find .ÅÑŚÌβŁÈ [$!@^&test(;)]' -test_win_find_username: testuser diff --git a/test/integration/targets/win_find/meta/main.yml b/test/integration/targets/win_find/meta/main.yml deleted file mode 100644 index d328716dfa..0000000000 --- a/test/integration/targets/win_find/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_find/tasks/main.yml b/test/integration/targets/win_find/tasks/main.yml deleted file mode 100644 index c2f40a8fde..0000000000 --- a/test/integration/targets/win_find/tasks/main.yml +++ /dev/null @@ -1,114 +0,0 @@ ---- -- name: ensure the testing directory is cleared before setting up test - win_file: - path: '{{win_find_dir}}' - state: absent - -# while most of the setup can be done with modules, it is quicker to do them -# all in bulk than with with_items to save each round trip over WinRM -- name: set test files and folders - win_shell: | - $directories = @( - "nested", - "single", - "link-dest\sub-link", - "hard-link-dest", - "junction-link-dest", - "broken-link-dest", - "nested\sub-nest", - "shared\folder", - "hidden", - "date", - "emptynested\nest\dir1", - "emptynested\nest\dir2" - ) - - $tmp_dir = '{{ win_find_dir }}' - foreach ($directory in $directories) { - New-Item -Path "$tmp_dir\$directory" -ItemType Directory - } - - $normal_content = "abcdefg1234567" - $normal_files = @( - "nested\file.ps1", - "nested\test.ps1", - "nested\out.log", - "nested\archive.log", - "nested\sub-nest\test.ps1", - "nested\sub-nest\readonly.txt", - "link-dest\link.ps1", - "single\test.ps1", - "single\hidden.ps1", - "single\out_20161101-091005.log", - "hidden\out_20161101-091005.log", - "hard-link-dest\file-abc.log" - ) - foreach ($file in $normal_files) { - New-Item -Path "$tmp_dir\$file" -ItemType File - [System.IO.File]::WriteAllText("$tmp_dir\$file", $normal_content) - } - - New-Item -Path "$tmp_dir\single\small.ps1" -ItemType File - [System.IO.File]::WriteAllText("$tmp_dir\single\small.ps1", "a") - - New-Item -Path "$tmp_dir\date\new.ps1" -ItemType File - [System.IO.File]::WriteAllText("$tmp_dir\date\new.ps1", "random text for new date") - - New-Item -Path "$tmp_dir\date\old.ps1" -ItemType File - [System.IO.File]::WriteAllText("$tmp_dir\date\old.ps1", "random text for old date") - - New-Item -Path "$tmp_dir\single\large.ps1" -ItemType File - Set-Content -LiteralPath "$tmp_dir\single\large.ps1" -Value ('abcdefghijklmnopqrstuvwxyz' * 10000) - - $share_stat = Get-WmiObject -Class Win32_Share -Filter "name='folder-share'" - if ($share_stat) { - $share_stat.Delete() - } - $wmi = [wmiClass] 'Win32_Share' - $wmi.Create("$tmp_dir\shared\folder", "folder-share", 0) - - cmd.exe /c mklink /D "$tmp_dir\nested\link" "$tmp_dir\link-dest" - cmd.exe /c mklink /D "$tmp_dir\broken-link" "$tmp_dir\broken-link-dest" - cmd.exe /c mklink /H "$tmp_dir\hard-link-dest\hard-link.log" "$tmp_dir\hard-link-dest\file-abc.log" - cmd.exe /c mklink /J "$tmp_dir\junction-link" "$tmp_dir\junction-link-dest" - - $date = Get-Date -Year 2016 -Month 11 -Day 1 -Hour 7 -Minute 10 -Second 5 -Millisecond 0 - Set-Location -LiteralPath $tmp_dir - Get-ChildItem -Recurse | Where-Object { $_.Name -ne "new.ps1" } | ForEach-Object { - $_.CreationTime = $date - $_.LastAccessTime = $date - $_.LastWriteTime = $date - } - Pop-Location - - $attributes = @{ - "hidden" = "Hidden" - "date" = "Hidden" - "nested\archive.log" = "Archive" - "nested\sub-nest\readonly.txt" = "ReadOnly" - "single\hidden.ps1" = "Hidden" - } - foreach ($attribute in $attributes.GetEnumerator()) { - $item = Get-Item -LiteralPath "$tmp_dir\$($attribute.Name)" - $file_attributes = $item.Attributes -split ',' - if ($file_attributes -notcontains $attribute.Value) { - $file_attributes += $attribute.Value - } - $item.Attributes = $file_attributes -join ',' - } - - Remove-Item -LiteralPath "$tmp_dir\broken-link-dest" -Force - -- block: - - include_tasks: tests.yml - - always: - - name: remove test user - win_user: - name: '{{test_win_find_username}}' - state: absent - - - name: remove testing folder - win_file: - path: '{{win_find_dir}}' - state: absent diff --git a/test/integration/targets/win_find/tasks/tests.yml b/test/integration/targets/win_find/tasks/tests.yml deleted file mode 100644 index 82fa879ced..0000000000 --- a/test/integration/targets/win_find/tasks/tests.yml +++ /dev/null @@ -1,755 +0,0 @@ ---- -- name: expected skip when paths to a file - win_find: - paths: "{{win_find_dir}}\\single\\large.ps1" - register: actual - -- name: assert skip when path is set to a file - assert: - that: - - not actual is changed - - actual.examined == 0 - - actual.files == [] - - actual.matched == 0 - - actual.warnings == ["Argument path '" + win_find_dir + "\\single\\large.ps1' is a file not a directory, skipping"] - -- name: expect skip when path is set to a non existent folder - win_find: - paths: "{{win_find_dir}}\\thisisafakefolder" - register: actual - -- name: assert skip when path is set to a non existent folder - assert: - that: - - not actual is changed - - actual.examined == 0 - - actual.files == [] - - actual.matched == 0 - - actual.warnings == ["Argument path '" + win_find_dir + "\\thisisafakefolder' does not exist, skipping"] - -- name: get files in single directory - win_find: - paths: "{{win_find_dir}}\\single" - register: actual - -- name: assert get files in single directory - assert: - that: - - not actual is changed - - actual.examined == 5 - - actual.matched == 4 - - actual.files[0].attributes == 'Archive' - - actual.files[0].checksum == 'f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af' - - actual.files[0].creationtime == 1477984205 - - actual.files[0].exists == True - - actual.files[0].extension == '.ps1' - - actual.files[0].filename == 'large.ps1' - - actual.files[0].hlnk_targets == [] - - actual.files[0].isarchive == True - - actual.files[0].isdir == False - - actual.files[0].ishidden == False - - actual.files[0].isjunction == False - - actual.files[0].islnk == False - - actual.files[0].isreadonly == False - - actual.files[0].isreg == True - - actual.files[0].isshared == False - - actual.files[0].lastaccesstime == 1477984205 - - actual.files[0].lastwritetime == 1477984205 - - actual.files[0].lnk_source == None - - actual.files[0].lnk_target == None - - actual.files[0].nlink == 1 - - actual.files[0].owner == 'BUILTIN\\Administrators' - - actual.files[0].path == win_find_dir + '\\single\\large.ps1' - - actual.files[0].sharename == None - - actual.files[0].size == 260002 - - actual.files[1].attributes == 'Archive' - - actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[1].creationtime == 1477984205 - - actual.files[1].exists == True - - actual.files[1].extension == '.log' - - actual.files[1].filename == 'out_20161101-091005.log' - - actual.files[1].hlnk_targets == [] - - actual.files[1].isarchive == True - - actual.files[1].isdir == False - - actual.files[1].ishidden == False - - actual.files[1].isjunction == False - - actual.files[1].islnk == False - - actual.files[1].isreadonly == False - - actual.files[1].isreg == True - - actual.files[1].isshared == False - - actual.files[1].lastaccesstime == 1477984205 - - actual.files[1].lastwritetime == 1477984205 - - actual.files[1].lnk_source == None - - actual.files[1].lnk_target == None - - actual.files[1].nlink == 1 - - actual.files[1].owner == 'BUILTIN\\Administrators' - - actual.files[1].path == win_find_dir + '\\single\\out_20161101-091005.log' - - actual.files[1].sharename == None - - actual.files[1].size == 14 - - actual.files[2].attributes == 'Archive' - - actual.files[2].checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8' - - actual.files[2].creationtime == 1477984205 - - actual.files[2].exists == True - - actual.files[2].extension == '.ps1' - - actual.files[2].filename == 'small.ps1' - - actual.files[2].hlnk_targets == [] - - actual.files[2].isarchive == True - - actual.files[2].isdir == False - - actual.files[2].ishidden == False - - actual.files[2].isjunction == False - - actual.files[2].islnk == False - - actual.files[2].isreadonly == False - - actual.files[2].isreg == True - - actual.files[2].isshared == False - - actual.files[2].lastaccesstime == 1477984205 - - actual.files[2].lastwritetime == 1477984205 - - actual.files[2].lnk_source == None - - actual.files[2].lnk_target == None - - actual.files[2].nlink == 1 - - actual.files[2].owner == 'BUILTIN\\Administrators' - - actual.files[2].path == win_find_dir + '\\single\\small.ps1' - - actual.files[2].sharename == None - - actual.files[2].size == 1 - - actual.files[3].attributes == 'Archive' - - actual.files[3].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[3].creationtime == 1477984205 - - actual.files[3].exists == True - - actual.files[3].extension == '.ps1' - - actual.files[3].filename == 'test.ps1' - - actual.files[3].hlnk_targets == [] - - actual.files[3].isarchive == True - - actual.files[3].isdir == False - - actual.files[3].ishidden == False - - actual.files[3].isjunction == False - - actual.files[3].islnk == False - - actual.files[3].isreadonly == False - - actual.files[3].isreg == True - - actual.files[3].isshared == False - - actual.files[3].lastaccesstime == 1477984205 - - actual.files[3].lastwritetime == 1477984205 - - actual.files[3].lnk_source == None - - actual.files[3].lnk_target == None - - actual.files[3].nlink == 1 - - actual.files[3].owner == 'BUILTIN\\Administrators' - - actual.files[3].path == win_find_dir + '\\single\\test.ps1' - - actual.files[3].sharename == None - - actual.files[3].size == 14 - -- name: find hidden files - win_find: - paths: ['{{win_find_dir}}\\single', '{{win_find_dir}}\\nested'] - hidden: True - register: actual - -- name: assert get files in single directory - assert: - that: - - not actual is changed - - actual.examined == 11 - - actual.matched == 1 - - actual.files[0].attributes == 'Hidden, Archive' - - actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[0].creationtime == 1477984205 - - actual.files[0].exists == True - - actual.files[0].extension == '.ps1' - - actual.files[0].filename == 'hidden.ps1' - - actual.files[0].hlnk_targets == [] - - actual.files[0].isarchive == True - - actual.files[0].isdir == False - - actual.files[0].ishidden == True - - actual.files[0].isjunction == False - - actual.files[0].islnk == False - - actual.files[0].isreadonly == False - - actual.files[0].isreg == True - - actual.files[0].isshared == False - - actual.files[0].lastaccesstime == 1477984205 - - actual.files[0].lastwritetime == 1477984205 - - actual.files[0].lnk_source == None - - actual.files[0].lnk_target == None - - actual.files[0].nlink == 1 - - actual.files[0].owner == 'BUILTIN\\Administrators' - - actual.files[0].path == win_find_dir + '\\single\\hidden.ps1' - - actual.files[0].sharename == None - - actual.files[0].size == 14 - -- name: find file based on pattern - win_find: - paths: '{{win_find_dir}}\\single' - patterns: ['*.log', 'out_*'] - register: actual_pattern - -- name: find file based on pattern regex - win_find: - paths: '{{win_find_dir}}\\single' - patterns: "out_\\d{8}-\\d{6}.log" - use_regex: True - register: actual_regex - -- name: assert find file based on pattern - assert: - that: - - not actual_pattern is changed - - actual_pattern.examined == 5 - - actual_pattern.matched == 1 - - actual_pattern.files[0].attributes == 'Archive' - - actual_pattern.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual_pattern.files[0].creationtime == 1477984205 - - actual_pattern.files[0].exists == True - - actual_pattern.files[0].extension == '.log' - - actual_pattern.files[0].filename == 'out_20161101-091005.log' - - actual_pattern.files[0].hlnk_targets == [] - - actual_pattern.files[0].isarchive == True - - actual_pattern.files[0].isdir == False - - actual_pattern.files[0].ishidden == False - - actual_pattern.files[0].isjunction == False - - actual_pattern.files[0].islnk == False - - actual_pattern.files[0].isreadonly == False - - actual_pattern.files[0].isreg == True - - actual_pattern.files[0].isshared == False - - actual_pattern.files[0].lastaccesstime == 1477984205 - - actual_pattern.files[0].lastwritetime == 1477984205 - - actual_pattern.files[0].lnk_source == None - - actual_pattern.files[0].lnk_target == None - - actual_pattern.files[0].nlink == 1 - - actual_pattern.files[0].owner == 'BUILTIN\\Administrators' - - actual_pattern.files[0].path == win_find_dir + '\\single\\out_20161101-091005.log' - - actual_pattern.files[0].sharename == None - - actual_pattern.files[0].size == 14 - - actual_pattern == actual_regex - -- name: find files with recurse set - win_find: - paths: "{{win_find_dir}}\\nested" - recurse: True - patterns: "*.ps1" - register: actual - -- name: assert find files with recurse set - assert: - that: - - not actual is changed - - actual.examined == 8 - - actual.matched == 3 - - actual.files[0].attributes == 'Archive' - - actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[0].creationtime == 1477984205 - - actual.files[0].exists == True - - actual.files[0].extension == '.ps1' - - actual.files[0].filename == 'file.ps1' - - actual.files[0].hlnk_targets == [] - - actual.files[0].isarchive == True - - actual.files[0].isdir == False - - actual.files[0].ishidden == False - - actual.files[0].isjunction == False - - actual.files[0].islnk == False - - actual.files[0].isreadonly == False - - actual.files[0].isreg == True - - actual.files[0].isshared == False - - actual.files[0].lastaccesstime == 1477984205 - - actual.files[0].lastwritetime == 1477984205 - - actual.files[0].lnk_source == None - - actual.files[0].lnk_target == None - - actual.files[0].nlink == 1 - - actual.files[0].owner == 'BUILTIN\\Administrators' - - actual.files[0].path == win_find_dir + '\\nested\\file.ps1' - - actual.files[0].sharename == None - - actual.files[0].size == 14 - - actual.files[1].attributes == 'Archive' - - actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[1].creationtime == 1477984205 - - actual.files[1].exists == True - - actual.files[1].extension == '.ps1' - - actual.files[1].filename == 'test.ps1' - - actual.files[1].hlnk_targets == [] - - actual.files[1].isarchive == True - - actual.files[1].isdir == False - - actual.files[1].ishidden == False - - actual.files[1].isjunction == False - - actual.files[1].islnk == False - - actual.files[1].isreadonly == False - - actual.files[1].isreg == True - - actual.files[1].isshared == False - - actual.files[1].lastaccesstime == 1477984205 - - actual.files[1].lastwritetime == 1477984205 - - actual.files[1].lnk_source == None - - actual.files[1].lnk_target == None - - actual.files[1].nlink == 1 - - actual.files[1].owner == 'BUILTIN\\Administrators' - - actual.files[1].path == win_find_dir + '\\nested\\sub-nest\\test.ps1' - - actual.files[1].sharename == None - - actual.files[1].size == 14 - - actual.files[2].attributes == 'Archive' - - actual.files[2].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[2].creationtime == 1477984205 - - actual.files[2].exists == True - - actual.files[2].extension == '.ps1' - - actual.files[2].filename == 'test.ps1' - - actual.files[2].hlnk_targets == [] - - actual.files[2].isarchive == True - - actual.files[2].isdir == False - - actual.files[2].ishidden == False - - actual.files[2].isjunction == False - - actual.files[2].islnk == False - - actual.files[2].isreadonly == False - - actual.files[2].isreg == True - - actual.files[2].isshared == False - - actual.files[2].lastaccesstime == 1477984205 - - actual.files[2].lastwritetime == 1477984205 - - actual.files[2].lnk_source == None - - actual.files[2].lnk_target == None - - actual.files[2].nlink == 1 - - actual.files[2].owner == 'BUILTIN\\Administrators' - - actual.files[2].path == win_find_dir + '\\nested\\test.ps1' - - actual.files[2].sharename == None - - actual.files[2].size == 14 - -- name: find files with recurse set and follow links - win_find: - paths: "{{win_find_dir}}\\nested" - recurse: True - follow: True - patterns: "*.ps1" - register: actual - -- name: assert find files with recurse set and follow links - assert: - that: - - not actual is changed - - actual.examined == 10 - - actual.matched == 4 - - actual.files[0].attributes == 'Archive' - - actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[0].creationtime == 1477984205 - - actual.files[0].exists == True - - actual.files[0].extension == '.ps1' - - actual.files[0].filename == 'file.ps1' - - actual.files[0].hlnk_targets == [] - - actual.files[0].isarchive == True - - actual.files[0].isdir == False - - actual.files[0].ishidden == False - - actual.files[0].isjunction == False - - actual.files[0].islnk == False - - actual.files[0].isreadonly == False - - actual.files[0].isreg == True - - actual.files[0].isshared == False - - actual.files[0].lastaccesstime == 1477984205 - - actual.files[0].lastwritetime == 1477984205 - - actual.files[0].lnk_source == None - - actual.files[0].lnk_target == None - - actual.files[0].nlink == 1 - - actual.files[0].owner == 'BUILTIN\\Administrators' - - actual.files[0].path == win_find_dir + '\\nested\\file.ps1' - - actual.files[0].sharename == None - - actual.files[0].size == 14 - - actual.files[1].attributes == 'Archive' - - actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[1].creationtime == 1477984205 - - actual.files[1].exists == True - - actual.files[1].extension == '.ps1' - - actual.files[1].filename == 'link.ps1' - - actual.files[1].hlnk_targets == [] - - actual.files[1].isarchive == True - - actual.files[1].isdir == False - - actual.files[1].ishidden == False - - actual.files[1].isjunction == False - - actual.files[1].islnk == False - - actual.files[1].isreadonly == False - - actual.files[1].isreg == True - - actual.files[1].isshared == False - - actual.files[1].lastaccesstime == 1477984205 - - actual.files[1].lastwritetime == 1477984205 - - actual.files[1].lnk_source == None - - actual.files[1].lnk_target == None - - actual.files[1].nlink == 1 - - actual.files[1].owner == 'BUILTIN\\Administrators' - - actual.files[1].path == win_find_dir + '\\nested\\link\\link.ps1' - - actual.files[1].sharename == None - - actual.files[1].size == 14 - - actual.files[2].attributes == 'Archive' - - actual.files[2].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[2].creationtime == 1477984205 - - actual.files[2].exists == True - - actual.files[2].extension == '.ps1' - - actual.files[2].filename == 'test.ps1' - - actual.files[2].hlnk_targets == [] - - actual.files[2].isarchive == True - - actual.files[2].isdir == False - - actual.files[2].ishidden == False - - actual.files[2].isjunction == False - - actual.files[2].islnk == False - - actual.files[2].isreadonly == False - - actual.files[2].isreg == True - - actual.files[2].isshared == False - - actual.files[2].lastaccesstime == 1477984205 - - actual.files[2].lastwritetime == 1477984205 - - actual.files[2].lnk_source == None - - actual.files[2].lnk_target == None - - actual.files[2].nlink == 1 - - actual.files[2].owner == 'BUILTIN\\Administrators' - - actual.files[2].path == win_find_dir + '\\nested\\sub-nest\\test.ps1' - - actual.files[2].sharename == None - - actual.files[2].size == 14 - - actual.files[3].attributes == 'Archive' - - actual.files[3].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - - actual.files[3].creationtime == 1477984205 - - actual.files[3].exists == True - - actual.files[3].extension == '.ps1' - - actual.files[3].filename == 'test.ps1' - - actual.files[3].hlnk_targets == [] - - actual.files[3].isarchive == True - - actual.files[3].isdir == False - - actual.files[3].ishidden == False - - actual.files[3].isjunction == False - - actual.files[3].islnk == False - - actual.files[3].isreadonly == False - - actual.files[3].isreg == True - - actual.files[3].isshared == False - - actual.files[3].lastaccesstime == 1477984205 - - actual.files[3].lastwritetime == 1477984205 - - actual.files[3].lnk_source == None - - actual.files[3].lnk_target == None - - actual.files[3].nlink == 1 - - actual.files[3].owner == 'BUILTIN\\Administrators' - - actual.files[3].path == win_find_dir + '\\nested\\test.ps1' - - actual.files[3].sharename == None - - actual.files[3].size == 14 - -- name: find directories - win_find: - paths: "{{win_find_dir}}\\link-dest" - file_type: directory - register: actual - -- name: assert find directories - assert: - that: - - not actual is changed - - actual.examined == 2 - - actual.matched == 1 - - actual.files[0].attributes == 'Directory' - - actual.files[0].checksum == None - - actual.files[0].creationtime == 1477984205 - - actual.files[0].exists == True - - actual.files[0].extension == None - - actual.files[0].filename == 'sub-link' - - actual.files[0].hlnk_targets == [] - - actual.files[0].isarchive == False - - actual.files[0].isdir == True - - actual.files[0].ishidden == False - - actual.files[0].isjunction == False - - actual.files[0].islnk == False - - actual.files[0].isreadonly == False - - actual.files[0].isreg == False - - actual.files[0].isshared == False - - actual.files[0].lastaccesstime == 1477984205 - - actual.files[0].lastwritetime == 1477984205 - - actual.files[0].lnk_source == None - - actual.files[0].lnk_target == None - - actual.files[0].nlink == 1 - - actual.files[0].owner == 'BUILTIN\\Administrators' - - actual.files[0].path == win_find_dir + '\\link-dest\\sub-link' - - actual.files[0].sharename == None - - actual.files[0].size == None - -- name: find directories recurse and follow with a broken link - win_find: - paths: "{{win_find_dir}}" - file_type: directory - recurse: True - follow: True - register: actual - -- name: check directory count with recurse and follow is correct - assert: - that: - - not actual is changed - - actual.examined == 37 - - actual.matched == 17 - - actual.files[0].filename == 'broken-link' - - actual.files[0].isjunction == False - - actual.files[0].islnk == True - - actual.files[6].filename == 'junction-link' - - actual.files[6].isjunction == True - - actual.files[6].islnk == False - - actual.files[6].lnk_source == win_find_dir + '\\junction-link-dest' - - actual.files[11].filename == 'link' - - actual.files[11].islnk == True - - actual.files[11].lnk_source == win_find_dir + '\\link-dest' - - actual.files[15].filename == 'folder' - - actual.files[15].islnk == False - - actual.files[15].isshared == True - - actual.files[15].sharename == 'folder-share' - -- name: filter files by size without byte specified - win_find: - paths: "{{win_find_dir}}\\single" - size: 260002 - register: actual_without_byte - -- name: filter files by size with byte specified - win_find: - paths: "{{win_find_dir}}\\single" - size: 253k - register: actual_with_byte - -- name: assert filter files by size - assert: - that: - - not actual_without_byte is changed - - actual_without_byte.examined == 5 - - actual_without_byte.matched == 1 - - actual_without_byte.files[0].attributes == 'Archive' - - actual_without_byte.files[0].checksum == 'f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af' - - actual_without_byte.files[0].creationtime == 1477984205 - - actual_without_byte.files[0].exists == True - - actual_without_byte.files[0].extension == '.ps1' - - actual_without_byte.files[0].filename == 'large.ps1' - - actual_without_byte.files[0].hlnk_targets == [] - - actual_without_byte.files[0].isarchive == True - - actual_without_byte.files[0].isdir == False - - actual_without_byte.files[0].ishidden == False - - actual_without_byte.files[0].isjunction == False - - actual_without_byte.files[0].islnk == False - - actual_without_byte.files[0].isreadonly == False - - actual_without_byte.files[0].isreg == True - - actual_without_byte.files[0].isshared == False - - actual_without_byte.files[0].lastaccesstime == 1477984205 - - actual_without_byte.files[0].lastwritetime == 1477984205 - - actual_without_byte.files[0].lnk_source == None - - actual_without_byte.files[0].lnk_target == None - - actual_without_byte.files[0].nlink == 1 - - actual_without_byte.files[0].owner == 'BUILTIN\\Administrators' - - actual_without_byte.files[0].path == win_find_dir + '\\single\\large.ps1' - - actual_without_byte.files[0].sharename == None - - actual_without_byte.files[0].size == 260002 - - actual_without_byte == actual_with_byte - -- name: filter files by size (less than) without byte specified - win_find: - paths: "{{win_find_dir}}\\single" - size: -4 - register: actual_without_byte - -- name: filter files by size (less than) with byte specified - win_find: - paths: "{{win_find_dir}}\\single" - size: -4b - register: actual_with_byte - -- name: assert filter files by size (less than) without byte specified - assert: - that: - - not actual_without_byte is changed - - actual_without_byte.examined == 5 - - actual_without_byte.matched == 1 - - actual_without_byte.files[0].attributes == 'Archive' - - actual_without_byte.files[0].checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8' - - actual_without_byte.files[0].creationtime == 1477984205 - - actual_without_byte.files[0].exists == True - - actual_without_byte.files[0].extension == '.ps1' - - actual_without_byte.files[0].filename == 'small.ps1' - - actual_without_byte.files[0].hlnk_targets == [] - - actual_without_byte.files[0].isarchive == True - - actual_without_byte.files[0].isdir == False - - actual_without_byte.files[0].ishidden == False - - actual_without_byte.files[0].isjunction == False - - actual_without_byte.files[0].islnk == False - - actual_without_byte.files[0].isreadonly == False - - actual_without_byte.files[0].isreg == True - - actual_without_byte.files[0].isshared == False - - actual_without_byte.files[0].lastaccesstime == 1477984205 - - actual_without_byte.files[0].lastwritetime == 1477984205 - - actual_without_byte.files[0].lnk_source == None - - actual_without_byte.files[0].lnk_target == None - - actual_without_byte.files[0].nlink == 1 - - actual_without_byte.files[0].owner == 'BUILTIN\\Administrators' - - actual_without_byte.files[0].path == win_find_dir + '\\single\\small.ps1' - - actual_without_byte.files[0].sharename == None - - actual_without_byte.files[0].size == 1 - - actual_without_byte == actual_with_byte - -# For dates we cannot assert against expected as the times change, this is a poor mans attempt at testing -- name: filter files by age without unit specified - win_find: - paths: "{{win_find_dir}}\\date" - age: 3600 - register: actual_without_unit - -- name: filter files by age with unit specified - win_find: - paths: "{{win_find_dir}}\\date" - age: 1h - register: actual_with_unit - -- name: assert dates match each other - assert: - that: - - actual_without_unit == actual_with_unit - - actual_without_unit.matched == 1 - - actual_without_unit.files[0].checksum == 'd1185139c47f5bc951e2e9135922fe31059206b1' - - actual_without_unit.files[0].path == win_find_dir + '\\date\\old.ps1' - -- name: filter files by age (newer than) without unit specified - win_find: - paths: "{{win_find_dir}}\\date" - age: -3600 - register: actual_without_unit - -- name: filter files by age (newer than) without unit specified - win_find: - paths: "{{win_find_dir}}\\date" - age: -1h - register: actual_with_unit - -- name: assert dates match each other - assert: - that: - - actual_without_unit == actual_with_unit - - actual_without_unit.matched == 1 - - actual_without_unit.files[0].checksum == 'af99d0e98df4531b9f26c942f41d65c58766bfa9' - - actual_without_unit.files[0].path == win_find_dir + '\\date\\new.ps1' - -- name: get list of files with md5 checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - checksum_algorithm: md5 - register: actual_md5_checksum - -- name: assert md5 checksum value - assert: - that: - - actual_md5_checksum.files[0].checksum == 'd1713d0f1d2e8fae230328d8fd59de01' - -- name: get list of files with sha1 checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - checksum_algorithm: sha1 - register: actual_sha1_checksum - -- name: assert sha1 checksum value - assert: - that: - - actual_sha1_checksum.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3' - -- name: get list of files with sha256 checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - checksum_algorithm: sha256 - register: actual_sha256_checksum - -- name: assert sha256 checksum value - assert: - that: - - actual_sha256_checksum.files[0].checksum == 'c20d2eba7ffda0079812721b6f4e4e109e2f0c5e8cc3d1273a060df6f7d9f339' - -- name: get list of files with sha384 checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - checksum_algorithm: sha384 - register: actual_sha384_checksum - -- name: assert sha384 checksum value - assert: - that: - - actual_sha384_checksum.files[0].checksum == 'aed515eb216b9c7009ae8c4680f46c1e22004528b231aa0482a8587543bca47d3504e9f77e884eb2d11b2f9f5dc01651' - -- name: get list of files with sha512 checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - checksum_algorithm: sha512 - register: actual_sha512_checksum - -- name: assert sha512 checksum value - assert: - that: - - actual_sha512_checksum.files[0].checksum == '05abf64a68c4731699c23b4fc6894a36646fce525f3c96f9cf743b5d0c3bfd933dad0e95e449e3afe1f74d534d69a53b8f46cf835763dd42915813c897b02b87' - -- name: get list of files without checksum - win_find: - paths: "{{win_find_dir}}\\single" - patterns: test.ps1 - get_checksum: False - register: actual_no_checksum - -- name: assert no checksum is returned - assert: - that: - - actual_no_checksum.files[0].checksum == None - -# https://github.com/ansible/ansible/issues/26158 -- name: get list of files in an empty nested directory - win_find: - paths: '{{win_find_dir}}\emptynested' - register: actual_empty_nested - -- name: assert get list of files in an empty nested directory - assert: - that: - - actual_empty_nested.matched == 0 - -- name: create new folders for security tests - win_file: - path: '{{win_find_dir}}\{{item}}' - state: directory - with_items: - - secure-tests\secure\internal-folder - - secure-tests\open\internal-folder - -- name: create random password for test user - set_fact: - test_win_find_password: password123! + {{ lookup('password', '/dev/null chars=ascii_letters,digits length=8') }} - -- name: create test user who does not have access to secure folder - win_user: - name: '{{test_win_find_username}}' - password: '{{test_win_find_password}}' - state: present - groups: - - Users - -- name: change owner of secure folder - win_owner: - path: '{{win_find_dir}}\secure-tests\secure' - user: BUILTIN\Administrators - recurse: yes - -- name: set explicit inheritance of secure folder for the Administrators accounts - win_acl: - user: BUILTIN\Administrators - path: '{{win_find_dir}}\secure-tests\secure' - rights: FullControl - type: allow - state: present - inherit: None - -- name: remove inheritance on the secure folder - win_acl_inheritance: - path: '{{win_find_dir}}\secure-tests\secure' - reorganize: no - state: absent - -- name: run win_find with under-privileged account - win_find: - paths: '{{win_find_dir}}\secure-tests' - recurse: yes - file_type: directory - register: secure_result - become: yes - become_method: runas - become_user: '{{test_win_find_username}}' - vars: - ansible_become_password: '{{test_win_find_password}}' - -- name: assert win_find only examined 2 files with under-privileged account - assert: - that: - - secure_result.examined == 3 - - secure_result.matched == 3 - - secure_result.files[0].path == win_find_dir + "\secure-tests\open" - - secure_result.files[1].path == win_find_dir + "\secure-tests\open\internal-folder" - - secure_result.files[2].path == win_find_dir + "\secure-tests\secure" diff --git a/test/integration/targets/win_get_url/aliases b/test/integration/targets/win_get_url/aliases deleted file mode 100644 index ca4f45531a..0000000000 --- a/test/integration/targets/win_get_url/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group5 -needs/httptester -skip/windows/2008 # httptester requires SSH which doesn't work with 2008 diff --git a/test/integration/targets/win_get_url/files/ftp/anon/file.txt b/test/integration/targets/win_get_url/files/ftp/anon/file.txt deleted file mode 100644 index 7ffe02e39e..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/anon/file.txt +++ /dev/null @@ -1 +0,0 @@ -ftp/anon/file.txt diff --git a/test/integration/targets/win_get_url/files/ftp/anon/file2.txt b/test/integration/targets/win_get_url/files/ftp/anon/file2.txt deleted file mode 100644 index 9dfc1e4aba..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/anon/file2.txt +++ /dev/null @@ -1 +0,0 @@ -ftp/anon/file2.txt diff --git a/test/integration/targets/win_get_url/files/ftp/anon/sha1sum.txt b/test/integration/targets/win_get_url/files/ftp/anon/sha1sum.txt deleted file mode 100644 index c5cfcb4769..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/anon/sha1sum.txt +++ /dev/null @@ -1,3 +0,0 @@ -a97e6837f60cec6da4491bab387296bbcd72bdba cHR1eA== -3911340502960ca33aece01129234460bfeb2791 not_target1.txt -1b4b6adf30992cedb0f6edefd6478ff0a593b2e4 not_target2.txt diff --git a/test/integration/targets/win_get_url/files/ftp/anon/sha256sum.txt b/test/integration/targets/win_get_url/files/ftp/anon/sha256sum.txt deleted file mode 100644 index 599e3626af..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/anon/sha256sum.txt +++ /dev/null @@ -1,3 +0,0 @@ -b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006 cHR1eA== -30949cc401e30ac494d695ab8764a9f76aae17c5d73c67f65e9b558f47eff892 not_target1.txt -d0dbfc1945bc83bf6606b770e442035f2c4e15c886ee0c22fb3901ba19900b5b not_target2.txt diff --git a/test/integration/targets/win_get_url/files/ftp/anon/sha256sum_with_dot.txt b/test/integration/targets/win_get_url/files/ftp/anon/sha256sum_with_dot.txt deleted file mode 100644 index 1e46b89d6b..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/anon/sha256sum_with_dot.txt +++ /dev/null @@ -1,3 +0,0 @@ -b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006 ./cHR1eA== -30949cc401e30ac494d695ab8764a9f76aae17c5d73c67f65e9b558f47eff892 ./not_target1.txt -d0dbfc1945bc83bf6606b770e442035f2c4e15c886ee0c22fb3901ba19900b5b ./not_target2.txt diff --git a/test/integration/targets/win_get_url/files/ftp/user-pass/file.txt b/test/integration/targets/win_get_url/files/ftp/user-pass/file.txt deleted file mode 100644 index b0a23ddabc..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/user-pass/file.txt +++ /dev/null @@ -1 +0,0 @@ -ftp/user-pass/file.txt diff --git a/test/integration/targets/win_get_url/files/ftp/user/file.txt b/test/integration/targets/win_get_url/files/ftp/user/file.txt deleted file mode 100644 index 40438f769f..0000000000 --- a/test/integration/targets/win_get_url/files/ftp/user/file.txt +++ /dev/null @@ -1 +0,0 @@ -ftp/user/file.txt diff --git a/test/integration/targets/win_get_url/library/win_defender_exclusion.ps1 b/test/integration/targets/win_get_url/library/win_defender_exclusion.ps1 deleted file mode 100644 index c6f8744a45..0000000000 --- a/test/integration/targets/win_get_url/library/win_defender_exclusion.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -#!powershell - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#Requires -Module Ansible.ModuleUtils.Legacy - -$params = Parse-Args $args -supports_check_mode $true - -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "present" - -$result = @{ - changed = $false -} - -# This is a test module, just skip instead of erroring out if we cannot set the rule -if ($null -eq (Get-Command -Name Get-MpPreference -ErrorAction SilentlyContinue)) { - $result.skipped = $true - $result.msg = "Skip as cannot set exclusion rule" - Exit-Json -obj $result -} - -$exclusions = (Get-MpPreference).ExclusionPath -if ($null -eq $exclusions) { - $exclusions = @() -} - -if ($state -eq "absent") { - if ($path -in $exclusions) { - Remove-MpPreference -ExclusionPath $path - $result.changed = $true - } -} else { - if ($path -notin $exclusions) { - Add-MpPreference -ExclusionPath $path - $result.changed = $true - } -} - -Exit-Json -obj $result diff --git a/test/integration/targets/win_get_url/meta/main.yml b/test/integration/targets/win_get_url/meta/main.yml deleted file mode 100644 index 6baa762584..0000000000 --- a/test/integration/targets/win_get_url/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: -- setup_remote_tmp_dir -- prepare_http_tests diff --git a/test/integration/targets/win_get_url/tasks/main.yml b/test/integration/targets/win_get_url/tasks/main.yml deleted file mode 100644 index 842323d590..0000000000 --- a/test/integration/targets/win_get_url/tasks/main.yml +++ /dev/null @@ -1,75 +0,0 @@ -# Due to the special environment setup required for proxies, you can manually test out the proxy options with -# https://github.com/jborean93/ansible-powershell-url-proxy. ---- -- name: set fact out special testing dir - set_fact: - testing_dir: '{{ remote_tmp_dir }}\win_get_url .ÅÑŚÌβŁÈ [$!@^&test(;)]' - -- name: create test directory with space and special chars - win_file: - path: '{{ testing_dir }}' - state: directory - -- name: copy across testing files - win_copy: - src: files/ - dest: '{{ testing_dir }}' - -# False positive in Windows Defender is flagging the file as a virus and removing it. We need to add an exclusion so -# the tests continue to work -- name: add exclusion for the SlimFTPd binary - win_defender_exclusion: - path: '{{ remote_tmp_dir | win_dirname }}' - state: present - -- name: download SlimFTPd binary - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_get_url/SlimFTPd.exe - dest: '{{ testing_dir }}\SlimFTPd.exe' - -# SlimFTPd does not work with special chars because it is so old, use a symlink as a workaround -- name: set fact of temp symlink for SlimFTPd - set_fact: - slimftpd_link: C:\SlimFTPd - -- name: template SlimFTPd configuration file - win_template: - src: slimftpd.conf.tmpl - dest: '{{ testing_dir }}\slimftpd.conf' - -- block: - - name: create SLimFTPd symlink - win_command: cmd.exe /c mklink /d "{{ slimftpd_link }}" "{{ testing_dir }}" - - - name: create SlimFTPd service - win_service: - name: SlimFTPd - path: '"{{ slimftpd_link }}\SlimFTPd.exe" -service' - state: started - dependencies: - - tcpip - - - name: run URL tests - import_tasks: tests_url.yml - - - name: run FTP tests - import_tasks: tests_ftp.yml - - - name: run checksum tests - import_tasks: tests_checksum.yml - - always: - - name: remove SlimFTPd service - win_service: - name: SlimFTPd - state: absent - - - name: remove temp symlink - win_file: - path: '{{ slimftpd_link }}' - state: absent - - - name: remove exclusion for the SlimFTPd binary - win_defender_exclusion: - path: '{{ remote_tmp_dir | win_dirname }}' - state: absent diff --git a/test/integration/targets/win_get_url/tasks/tests_checksum.yml b/test/integration/targets/win_get_url/tasks/tests_checksum.yml deleted file mode 100644 index 8010580548..0000000000 --- a/test/integration/targets/win_get_url/tasks/tests_checksum.yml +++ /dev/null @@ -1,91 +0,0 @@ ---- -# These files are pre formatted and we want to get the base64 value so we can use it for httpbin -# dynamic content in checksum_url -- name: set base64 values for checksum files - set_fact: - sha1sum: '{{ lookup("file", "ftp/anon/sha1sum.txt") | b64encode }}' - sha256sum: '{{ lookup("file", "ftp/anon/sha256sum.txt") | b64encode }}' - sha256sum_dot: '{{ lookup("file", "ftp/anon/sha256sum_with_dot.txt") | b64encode }}' - -- name: download file with sha1 checksum url - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\sha1.txt' - checksum_url: https://{{ httpbin_host }}/base64/{{ sha1sum }} - force: True - register: download_sha1_url - -- name: download file with sha1 checksum value - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\sha1.txt' - checksum: a97e6837f60cec6da4491bab387296bbcd72bdba - force: True - register: download_sha1_value - -- name: assert download file with sha1 checksum - assert: - that: - - download_sha1_url is changed - - download_sha1_url.status_code == 200 - - download_sha1_url.checksum_dest == 'a97e6837f60cec6da4491bab387296bbcd72bdba' - - not download_sha1_value is changed - - download_sha1_value.status_code == 200 - - download_sha1_value.checksum_dest == 'a97e6837f60cec6da4491bab387296bbcd72bdba' - -- name: download file with sha256 checksum ftp - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\sha256.txt' - checksum_url: ftp://localhost/anon/sha256sum.txt # tests that a checksum can be from an FTP URI - checksum_algorithm: sha256 - force: True - register: download_sha256_ftp - -- name: download file with sha256 checksum dot leading source as file - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\sha256.txt' - checksum_url: '{{ testing_dir }}\ftp\anon\sha256sum_with_dot.txt' - checksum_algorithm: sha256 - force: True - register: download_sha256_file - -- name: download file with sha256 checksum value - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\sha256.txt' - checksum: b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006 - checksum_algorithm: sha256 - register: download_sha256_value - -- name: assert download file with sha256 checksum - assert: - that: - - download_sha256_ftp is changed - - download_sha256_ftp.status_code == 200 - - download_sha256_ftp.checksum_dest == 'b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006' - - not download_sha256_file is changed - - download_sha256_file.status_code == 200 - - download_sha256_file.checksum_dest == 'b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006' - - not download_sha256_value is changed - - download_sha256_value.status_code == 200 - - download_sha256_value.checksum_dest == 'b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006' - -- name: fail download with invalid checksum and force=no - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\fail.txt' - checksum: invalid - force: no - register: fail_checksum_force_no - failed_when: fail_checksum_force_no.msg != "The checksum for https://" + httpbin_host + "/base64/cHR1eA== did not match 'invalid', it was 'a97e6837f60cec6da4491bab387296bbcd72bdba'" - -- name: fail download with invalid checksum and force=yes - win_get_url: - url: https://{{ httpbin_host }}/base64/cHR1eA== - dest: '{{ testing_dir }}\fail.txt' - checksum: invalid - force: yes - register: fail_checksum_force_yes - failed_when: fail_checksum_force_yes.msg != "The checksum for https://" + httpbin_host + "/base64/cHR1eA== did not match 'invalid', it was 'a97e6837f60cec6da4491bab387296bbcd72bdba'" diff --git a/test/integration/targets/win_get_url/tasks/tests_ftp.yml b/test/integration/targets/win_get_url/tasks/tests_ftp.yml deleted file mode 100644 index ec389079b8..0000000000 --- a/test/integration/targets/win_get_url/tasks/tests_ftp.yml +++ /dev/null @@ -1,166 +0,0 @@ ---- -- name: download file from FTP source (check) - win_get_url: - url: ftp://localhost/anon/file.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - check_mode: yes - register: ftp_anon_check - -- name: get results of download file from FTP source (check) - win_stat: - path: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon_result_check - -- name: assert download file from FTP source (check) - assert: - that: - - ftp_anon_check is changed - - not ftp_anon_result_check.stat.exists - -- name: download file from FTP source - win_get_url: - url: ftp://localhost/anon/file.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon - -- name: get results of download file from FTP source - win_stat: - path: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon_result - -- name: assert download file from FTP source - assert: - that: - - ftp_anon is changed - - ftp_anon_result.stat.exists - - ftp_anon_result.stat.checksum == '67e0de92f29645cc30d8d147b767cceb81756651' - -- name: download file from FTP source (idempotent) - win_get_url: - url: ftp://localhost/anon/file.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon_again - -- name: assert download file from FTP source (idempotent) - assert: - that: - - not ftp_anon_again is changed - -- name: download file from FTP source with force no (check) - win_get_url: - url: ftp://localhost/anon/file.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - force: no - check_mode: yes - register: ftp_anon_force_no_check - -- name: assert download file from FTP source with force no - assert: - that: - - ftp_anon_force_no_check is not changed - -- name: download file from FTP source with force no - win_get_url: - url: ftp://localhost/anon/file.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - force: no - register: ftp_anon_force_no - -- name: assert download file from FTP source with force no - assert: - that: - - ftp_anon_force_no is not changed - -- name: set last modified time on FTP source to newer datetime - win_shell: (Get-Item -LiteralPath '{{ testing_dir }}\ftp\anon\file2.txt').LastWriteTime = (Get-Date).AddHours(24) - -- name: download newer file from FTP source to same dest (check) - win_get_url: - url: ftp://localhost/anon/file2.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - force: no - check_mode: yes - register: ftp_anon_force_no_different_check - -- name: get result of download newer file from FTP source to same dest (check) - win_stat: - path: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon_force_no_different_result_check - -- name: assert download newer file from FTP source to same dest (check) - assert: - that: - - ftp_anon_force_no_different_check is changed - - ftp_anon_force_no_different_result_check.stat.checksum == '67e0de92f29645cc30d8d147b767cceb81756651' - -- name: download newer file from FTP source to same dest - win_get_url: - url: ftp://localhost/anon/file2.txt - dest: '{{ testing_dir }}\ftp-anon.txt' - force: no - register: ftp_anon_force_no_different - -- name: get result of download newer file from FTP source to same dest - win_stat: - path: '{{ testing_dir }}\ftp-anon.txt' - register: ftp_anon_force_no_different_result - -- name: assert download newer file from FTP source to same dest (check) - assert: - that: - - ftp_anon_force_no_different is changed - - ftp_anon_force_no_different_result.stat.checksum == 'eac3baccd817f7137c00138559e2e62aca64aab0' - -- name: fail to download file from ftp protected by username - win_get_url: - url: ftp://localhost/user/file.txt - dest: '{{ testing_dir }}\ftp-user.txt' - register: fail_ftp_no_user - ignore_errors: yes - -- name: assert fail to download file from ftp protected by username - assert: - that: - - fail_ftp_no_user is failed - - fail_ftp_no_user is not changed - - fail_ftp_no_user.status_code == 550 - - '"File unavailable (e.g., file not found, no access)." in fail_ftp_no_user.msg' - -- name: download FTP file protected by username - win_get_url: - url: ftp://localhost/user/file.txt - dest: '{{ testing_dir }}\ftp-user.txt' - url_username: username - register: ftp_user_file - -- name: get result of download FTP file protected by username - win_stat: - path: '{{ testing_dir }}\ftp-user.txt' - register: ftp_user_file_result - -- name: assert download FTP file protected by username - assert: - that: - - ftp_user_file is changed - - ftp_user_file_result.stat.exists - - ftp_user_file_result.stat.checksum == '0efc2e97611cf74e25ec17a00d4b2cf65d0c28ba' - -- name: download FTP file protected by username and password - win_get_url: - url: ftp://localhost/user-pass/file.txt - dest: '{{ testing_dir }}\ftp-user-pass.txt' - url_username: userpass - url_password: password - register: ftp_user_pass_file - -- name: get result of download FTP file protected by username and password - win_stat: - path: '{{ testing_dir }}\ftp-user-pass.txt' - register: ftp_user_pass_file_result - -- name: assert download FTP file protected by username and password - assert: - that: - - ftp_user_pass_file is changed - - ftp_user_pass_file_result.stat.exists - - ftp_user_pass_file_result.stat.checksum == '7da5f1124d4a986cba2b4658d38d95eb55afe086' diff --git a/test/integration/targets/win_get_url/tasks/tests_url.yml b/test/integration/targets/win_get_url/tasks/tests_url.yml deleted file mode 100644 index 91c782c7fa..0000000000 --- a/test/integration/targets/win_get_url/tasks/tests_url.yml +++ /dev/null @@ -1,237 +0,0 @@ -- name: download single file (check) - win_get_url: - url: https://{{ httpbin_host }}/base64/SG93IG5vdyBicm93biBjb3c= - dest: '{{ testing_dir }}\output.txt' - check_mode: yes - register: http_download_check - -- name: get result of download single file (check) - win_stat: - path: '{{ testing_dir }}\output.txt' - register: http_download_result_check - -- name: assert download single file (check) - assert: - that: - - http_download_check is not failed - - http_download_check is changed - - http_download_check.url - - http_download_check.dest - - not http_download_result_check.stat.exists - -- name: download single file - win_get_url: - url: https://{{ httpbin_host }}/base64/SG93IG5vdyBicm93biBjb3c= - dest: '{{ testing_dir }}\output.txt' - register: http_download - -- name: get result of download single file - win_stat: - path: '{{ testing_dir }}\output.txt' - register: http_download_result - -- name: assert download single file - assert: - that: - - http_download is not failed - - http_download is changed - - http_download.url - - http_download.dest - - http_download_result.stat.exists - -- name: download single file (idempotent) - win_get_url: - url: https://{{ httpbin_host }}/base64/SG93IG5vdyBicm93biBjb3c= - dest: '{{ testing_dir }}\output.txt' - register: http_download_again - -- name: assert download single file (idempotent) - assert: - that: - - not http_download_again is changed - -# Cannot use httpbin as the Last-Modified date is generated dynamically -- name: download file for force=no tests - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_get_url/SlimFTPd.exe - dest: '{{ testing_dir }}\output' - -- name: download single file with force no - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_get_url/SlimFTPd.exe - dest: '{{ testing_dir }}\output' - force: no - register: http_download_no_force - -- name: assert download single file with force no - assert: - that: - - http_download_no_force is not changed - -- name: manually change the content and last modified time on FTP source to older datetime - win_shell: | - $path = '{{ testing_dir }}\output' - Set-Content -LiteralPath $path -Value 'abc' - (Get-Item -LiteralPath $path).LastWriteTime = (Get-Date -Date "01/01/1970") - -- name: download newer file with force no - win_get_url: - url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_get_url/SlimFTPd.exe - dest: '{{ testing_dir }}\output' - force: no - register: http_download_newer_no_force - -- name: assert download newer file with force no - assert: - that: - - http_download_newer_no_force is changed - -- name: download file to directory - win_get_url: - url: https://{{ httpbin_host }}/image/png - dest: '{{ testing_dir }}' - register: http_download_to_directory - -- name: get result of download to directory - win_stat: - path: '{{ testing_dir }}\png' - register: http_download_to_directory_result - -- name: assert download file to directory - assert: - that: - - http_download_to_directory is changed - - http_download_to_directory_result.stat.exists - -- name: download to path with env var - win_get_url: - url: https://{{ httpbin_host }}/image/jpeg - dest: '%TEST_WIN_GET_URL%\jpeg.jpg' - register: http_download_with_env - environment: - TEST_WIN_GET_URL: '{{ testing_dir }}' - -- name: get result of download to path with env var - win_stat: - path: '{{ testing_dir }}\jpeg.jpg' - register: http_download_with_env_result - -- name: assert download to path with env var - assert: - that: - - http_download_with_env is changed - - http_download_with_env_result.stat.exists - -- name: fail when link returns 404 - win_get_url: - url: https://{{ httpbin_host }}/status/404 - dest: '{{ testing_dir }}\skynet_module.html' - ignore_errors: yes - register: fail_download_404 - -- name: assert fail when link returns 404 - assert: - that: - - fail_download_404 is not changed - - fail_download_404 is failed - - fail_download_404.status_code == 404 - -- name: fail when dest is an invalid path - win_get_url: - url: https://{{ httpbin_host }}/base64/YQ== - dest: Q:\Filez\Cyberdyne.html - register: fail_invalid_path - failed_when: '"The path ''Q:\Filez'' does not exist for destination ''Q:\Filez\Cyberdyne.html''" not in fail_invalid_path.msg' - -- name: test basic authentication - win_get_url: - url: http://{{ httpbin_host }}/basic-auth/username/password - dest: '{{ testing_dir }}\basic.txt' - url_username: username - url_password: password - register: basic_auth - -- name: assert test basic authentication - assert: - that: - - basic_auth is changed - - basic_auth.status_code == 200 - -# httpbin hidden-basic-auth returns 404 not found on auth failure which stops the automatic auth handler from working. -# Setting force_basic_auth=yes means the Basic auth header is sent in the original request not after a 401 response -- name: test force basic authentication - win_get_url: - url: http://{{ httpbin_host }}/hidden-basic-auth/username/password - dest: '{{ testing_dir }}\force-basic.txt' - url_username: username - url_password: password - force_basic_auth: yes - register: force_basic_auth - -- name: assert test force basic auth - assert: - that: - - force_basic_auth is changed - - force_basic_auth.status_code == 200 - -- name: timeout request - win_get_url: - url: https://{{ httpbin_host }}/delay/7 - dest: '{{ testing_dir }}\timeout.txt' - timeout: 3 - register: timeout_req - failed_when: 'timeout_req.msg != "Error downloading ''https://" + httpbin_host + "/delay/7'' to ''" + testing_dir + "\\timeout.txt'': The operation has timed out"' - -- name: send request with headers - win_get_url: - url: https://{{ httpbin_host }}/headers - dest: '{{ testing_dir }}\headers.txt' - headers: - testing: 123 - User-Agent: 'badAgent' - accept: 'text/html' - register: headers - -- name: get result of send request with headers - slurp: - path: '{{ testing_dir }}\headers.txt' - register: headers_actual - -- name: assert send request with headers - assert: - that: - - headers is changed - - headers.status_code == 200 - - (headers_actual.content | b64decode | from_json).headers.Testing == '123' - - (headers_actual.content | b64decode | from_json).headers["User-Agent"] == 'badAgent' - - (headers_actual.content | b64decode | from_json).headers.Accept == 'text/html' - -- name: test download follow with redirects - win_get_url: - url: https://{{ httpbin_host }}/redirect/2 - dest: '{{ testing_dir }}\redirects.txt' - register: redirection - -- name: assert download follow with redirects - assert: - that: - - redirection is changed - - redirection.status_code == 200 - -- name: test download follow without redirects - win_get_url: - url: https://{{ httpbin_host }}/redirect/2 - dest: '{{ testing_dir }}\no_redirection.txt' - follow_redirects: none - register: no_redirection - -- name: get result of test download follow without redirects - slurp: - path: '{{ testing_dir }}\no_redirection.txt' - register: no_redirection_actual - -- name: assert test download follow without redirects - assert: - that: - - no_redirection is changed - - no_redirection.status_code == 302 diff --git a/test/integration/targets/win_get_url/templates/slimftpd.conf.tmpl b/test/integration/targets/win_get_url/templates/slimftpd.conf.tmpl deleted file mode 100644 index ce2f712927..0000000000 --- a/test/integration/targets/win_get_url/templates/slimftpd.conf.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -# http://www.wiki.uniformserver.com/index.php/SlimFTPd:_Config_File -BindInterface Local -BindPort 21 -CommandTimeout 300 -ConnectTimeout 15 -MaxConnections 20 -LookupHosts On - -<User "anonymous"> - Password "" - Mount / "{{ slimftpd_link | replace('\\', '\\\\') }}\\ftp" - Allow /anon All - Deny /user All - Deny /user-pass All -</User> - -<User "username"> - Mount / "{{ slimftpd_link | replace('\\', '\\\\') }}\\ftp" - Allow /anon All - Allow /user All - Deny /user-pass All -</User> - -<User "userpass"> - Password "password" - Mount / "{{ slimftpd_link | replace('\\', '\\\\') }}\\ftp" - Allow / All -</User> diff --git a/test/integration/targets/win_group/aliases b/test/integration/targets/win_group/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_group/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_group/defaults/main.yml b/test/integration/targets/win_group/defaults/main.yml deleted file mode 100644 index 2ab744e822..0000000000 --- a/test/integration/targets/win_group/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -test_win_group_name: Ansiblings -test_win_group_description: Test group for Ansible diff --git a/test/integration/targets/win_group/tasks/main.yml b/test/integration/targets/win_group/tasks/main.yml deleted file mode 100644 index f66e3c2e75..0000000000 --- a/test/integration/targets/win_group/tasks/main.yml +++ /dev/null @@ -1,101 +0,0 @@ -# test code for the slurp module when using winrm connection -# (c) 2015, Chris Church <cchurch@ansible.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: remove test group if it exists - win_group: - name: "{{test_win_group_name}}" - state: absent - -- name: create test group with missing name parameter - win_group: - description: "{{test_win_group_description}}" - register: win_group_create_noname - ignore_errors: true - -- name: check create result without name parameter - assert: - that: - - "win_group_create_noname is failed" - -- name: create test group with invalid state parameter - win_group: - name: "{{test_win_group_name}}" - state: "unknown" - register: win_group_create_invalid_state - ignore_errors: true - -- name: check create result with invalid state parameter - assert: - that: - - "win_group_create_invalid_state is failed" - -- name: create test group - win_group: - name: "{{test_win_group_name}}" - description: "{{test_win_group_description}}" - register: win_group_create - -- name: check create group results - assert: - that: - - "win_group_create is changed" - -- name: create test group again with same options - win_group: - name: "{{test_win_group_name}}" - description: "{{test_win_group_description}}" - state: "present" - register: win_group_create_again - -- name: check create group again results - assert: - that: - - "win_group_create_again is not changed" - -- name: create test group again but change description - win_group: - name: "{{test_win_group_name}}" - description: "{{test_win_group_description}} updated" - register: win_group_create_new_description - -- name: check create group results after updating description - assert: - that: - - "win_group_create_new_description is changed" - -- name: remove test group - win_group: - name: "{{test_win_group_name}}" - state: absent - register: win_group_remove - -- name: check remove group result - assert: - that: - - "win_group_remove is changed" - -- name: remove test group again - win_group: - name: "{{test_win_group_name}}" - state: absent - register: win_group_remove_again - -- name: check remove group again result - assert: - that: - - "win_group_remove_again is not changed" diff --git a/test/integration/targets/win_group_membership/aliases b/test/integration/targets/win_group_membership/aliases deleted file mode 100644 index 4c08975b17..0000000000 --- a/test/integration/targets/win_group_membership/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group6 diff --git a/test/integration/targets/win_group_membership/tasks/main.yml b/test/integration/targets/win_group_membership/tasks/main.yml deleted file mode 100644 index d26e2e6c96..0000000000 --- a/test/integration/targets/win_group_membership/tasks/main.yml +++ /dev/null @@ -1,47 +0,0 @@ -- name: Gather facts - setup: - -- name: Remove potentially leftover test group - win_group: &wg_absent - name: WinGroupMembershipTest - state: absent - -- name: Remove potentially leftover test user - win_user: &wu_absent - name: WinTestUser - state: absent - -- name: Add new test group - win_group: - name: WinGroupMembershipTest - state: present - -- name: Add new test user - win_user: - name: WinTestUser - password: "W1nGr0upM3mb3rsh1pT3$tP@$$w0rd" - state: present - -- name: Run tests for win_group_membership - block: - - - name: Test in normal mode - import_tasks: tests.yml - vars: - win_local_group: WinGroupMembershipTest - win_local_user: WinTestUser - in_check_mode: no - - - name: Test in check-mode - import_tasks: tests.yml - vars: - win_local_group: WinGroupMembershipTest - win_local_user: WinTestUser - in_check_mode: yes - check_mode: yes - -- name: Remove test group - win_group: *wg_absent - -- name: Remove test user - win_group: *wu_absent
\ No newline at end of file diff --git a/test/integration/targets/win_group_membership/tasks/tests.yml b/test/integration/targets/win_group_membership/tasks/tests.yml deleted file mode 100644 index 44a94a0473..0000000000 --- a/test/integration/targets/win_group_membership/tasks/tests.yml +++ /dev/null @@ -1,320 +0,0 @@ -# Test code for win_group_membership - -# Copyright: (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Look up built-in Administrator account name (-500 user whose domain == computer name) - raw: $machine_sid = (Get-CimInstance Win32_UserAccount -Filter "Domain='$env:COMPUTERNAME'")[0].SID -replace '(S-1-5-21-\d+-\d+-\d+)-\d+', '$1'; (Get-CimInstance Win32_UserAccount -Filter "SID='$machine_sid-500'").Name - check_mode: no - register: admin_account_result - -- set_fact: - admin_account_name: "{{ admin_account_result.stdout_lines[0] }}" - -- name: Remove potentially leftover group members - win_group_membership: - name: "{{ win_local_group }}" - members: - - "{{ admin_account_name }}" - - "{{ win_local_user }}" - - NT AUTHORITY\SYSTEM - - NT AUTHORITY\NETWORK SERVICE - state: absent - - -- name: Add user to fake group - win_group_membership: - name: FakeGroup - members: - - "{{ admin_account_name }}" - state: present - register: add_user_to_fake_group - failed_when: add_user_to_fake_group.changed != false or add_user_to_fake_group.msg != "Could not find local group FakeGroup" - - -- name: Add fake local user - win_group_membership: - name: "{{ win_local_group }}" - members: - - FakeUser - state: present - register: add_fake_local_user - failed_when: add_fake_local_user.changed != false or add_fake_local_user.msg is not search("account_name FakeUser is not a valid account, cannot get SID.*") - - -- name: Add users to group - win_group_membership: &wgm_present - name: "{{ win_local_group }}" - members: - - "{{ admin_account_name }}" - - "{{ win_local_user }}" - - NT AUTHORITY\SYSTEM - state: present - register: add_users_to_group - -- name: Test add_users_to_group (normal mode) - assert: - that: - - add_users_to_group.changed == true - - add_users_to_group.added == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - - add_users_to_group.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - when: not in_check_mode - -- name: Test add_users_to_group (check-mode) - assert: - that: - - add_users_to_group.changed == true - - add_users_to_group.added == [] - - add_users_to_group.members == [] - when: in_check_mode - - -- name: Add users to group (again) - win_group_membership: *wgm_present - register: add_users_to_group_again - -- name: Test add_users_to_group_again (normal mode) - assert: - that: - - add_users_to_group_again.changed == false - - add_users_to_group_again.added == [] - - add_users_to_group_again.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - when: not in_check_mode - - -- name: Add different syntax users to group (again) - win_group_membership: - <<: *wgm_present - members: - - '{{ ansible_hostname }}\{{ admin_account_name }}' - - '.\{{ win_local_user }}' - register: add_different_syntax_users_to_group_again - -- name: Test add_different_syntax_users_to_group_again (normal mode) - assert: - that: - - add_different_syntax_users_to_group_again.changed == false - - add_different_syntax_users_to_group_again.added == [] - - add_different_syntax_users_to_group_again.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - when: not in_check_mode - -- name: Test add_different_syntax_users_to_group_again (check-mode) - assert: - that: - - add_different_syntax_users_to_group_again.changed == true - - add_different_syntax_users_to_group_again.added == [] - - add_different_syntax_users_to_group_again.members == [] - when: in_check_mode - - -- name: Add another user to group - win_group_membership: &wgma_present - <<: *wgm_present - members: - - NT AUTHORITY\NETWORK SERVICE - register: add_another_user_to_group - -- name: Test add_another_user_to_group (normal mode) - assert: - that: - - add_another_user_to_group.changed == true - - add_another_user_to_group.added == ["NT AUTHORITY\\NETWORK SERVICE"] - - add_another_user_to_group.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM", "NT AUTHORITY\\NETWORK SERVICE"] - when: not in_check_mode - -- name: Test add_another_user_to_group (check-mode) - assert: - that: - - add_another_user_to_group.changed == true - - add_another_user_to_group.added == [] - - add_another_user_to_group.members == [] - when: in_check_mode - - -- name: Add another user to group (again) - win_group_membership: *wgma_present - register: add_another_user_to_group_again - -- name: Test add_another_user_to_group_1_again (normal mode) - assert: - that: - - add_another_user_to_group_again.changed == false - - add_another_user_to_group_again.added == [] - - add_another_user_to_group_again.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM", "NT AUTHORITY\\NETWORK SERVICE"] - when: not in_check_mode - - -- name: Remove users from group - win_group_membership: &wgm_absent - <<: *wgm_present - state: absent - register: remove_users_from_group - -- name: Test remove_users_from_group (normal mode) - assert: - that: - - remove_users_from_group.changed == true - - remove_users_from_group.removed == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - - remove_users_from_group.members == ["NT AUTHORITY\\NETWORK SERVICE"] - when: not in_check_mode - -- name: Test remove_users_from_group (check-mode) - assert: - that: - - remove_users_from_group.changed == false - - remove_users_from_group.removed == [] - - remove_users_from_group.members == [] - when: in_check_mode - - -- name: Remove users from group (again) - win_group_membership: *wgm_absent - register: remove_users_from_group_again - -- name: Test remove_users_from_group_again (normal mode) - assert: - that: - - remove_users_from_group_again.changed == false - - remove_users_from_group_again.removed == [] - - remove_users_from_group_again.members == ["NT AUTHORITY\\NETWORK SERVICE"] - when: not in_check_mode - - -- name: Remove different syntax users from group (again) - win_group_membership: - <<: *wgm_absent - members: - - '{{ ansible_hostname }}\{{ admin_account_name }}' - - '.\{{ win_local_user }}' - register: remove_different_syntax_users_from_group_again - -- name: Test remove_different_syntax_users_from_group_again (normal mode) - assert: - that: - - remove_different_syntax_users_from_group_again.changed == false - - remove_different_syntax_users_from_group_again.removed == [] - - remove_different_syntax_users_from_group_again.members == ["NT AUTHORITY\\NETWORK SERVICE"] - when: not in_check_mode - -- name: Test add_different_syntax_users_to_group_again (check-mode) - assert: - that: - - remove_different_syntax_users_from_group_again.changed == false - - remove_different_syntax_users_from_group_again.removed == [] - - remove_different_syntax_users_from_group_again.members == [] - when: in_check_mode - - -- name: Remove another user from group - win_group_membership: &wgma_absent - <<: *wgm_absent - members: - - NT AUTHORITY\NETWORK SERVICE - register: remove_another_user_from_group - -- name: Test remove_another_user_from_group (normal mode) - assert: - that: - - remove_another_user_from_group.changed == true - - remove_another_user_from_group.removed == ["NT AUTHORITY\\NETWORK SERVICE"] - - remove_another_user_from_group.members == [] - when: not in_check_mode - -- name: Test remove_another_user_from_group (check-mode) - assert: - that: - - remove_another_user_from_group.changed == false - - remove_another_user_from_group.removed == [] - - remove_another_user_from_group.members == [] - when: in_check_mode - - -- name: Remove another user from group (again) - win_group_membership: *wgma_absent - register: remove_another_user_from_group_again - -- name: Test remove_another_user_from_group_again (normal mode) - assert: - that: - - remove_another_user_from_group_again.changed == false - - remove_another_user_from_group_again.removed == [] - - remove_another_user_from_group_again.members == [] - when: not in_check_mode - - -- name: Setup users for pure testing - win_group_membership: - <<: *wgm_present - members: - - "{{ admin_account_name }}" - - NT AUTHORITY\NETWORK SERVICE - - -- name: Define users as pure - win_group_membership: &wgm_pure - <<: *wgm_present - state: pure - register: define_users_as_pure - -- name: Test define_users_as_pure (normal mode) - assert: - that: - - define_users_as_pure.changed == true - - define_users_as_pure.added == ["{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - - define_users_as_pure.removed == ["NT AUTHORITY\\NETWORK SERVICE"] - - define_users_as_pure.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - when: not in_check_mode - -- name: Test define_users_as_pure (check-mode) - assert: - that: - - define_users_as_pure.changed == true - - define_users_as_pure.added == [] - - define_users_as_pure.removed == [] - - define_users_as_pure.members == [] - when: in_check_mode - - -- name: Define users as pure (again) - win_group_membership: *wgm_pure - register: define_users_as_pure_again - -- name: Test define_users_as_pure_again (normal mode) - assert: - that: - - define_users_as_pure_again.changed == false - - define_users_as_pure_again.added == [] - - define_users_as_pure_again.removed == [] - - define_users_as_pure_again.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}", "NT AUTHORITY\\SYSTEM"] - when: not in_check_mode - - -- name: Define different syntax users as pure - win_group_membership: - <<: *wgm_pure - members: - - '{{ ansible_hostname }}\{{ admin_account_name }}' - - '.\{{ win_local_user }}' - register: define_different_syntax_users_as_pure - -- name: Test define_different_syntax_users_as_pure (normal mode) - assert: - that: - - define_different_syntax_users_as_pure.changed == true - - define_different_syntax_users_as_pure.added == [] - - define_different_syntax_users_as_pure.removed == ["NT AUTHORITY\\SYSTEM"] - - define_different_syntax_users_as_pure.members == ["{{ ansible_hostname }}\\{{ admin_account_name }}", "{{ ansible_hostname }}\\{{ win_local_user }}"] - when: not in_check_mode - -- name: Test define_different_syntax_users_as_pure (check-mode) - assert: - that: - - define_different_syntax_users_as_pure.changed == true - - define_different_syntax_users_as_pure.added == [] - - define_different_syntax_users_as_pure.removed == [] - - define_different_syntax_users_as_pure.members == [] - when: in_check_mode - - -- name: Teardown remaining pure users - win_group_membership: *wgm_absent
\ No newline at end of file diff --git a/test/integration/targets/win_hostname/aliases b/test/integration/targets/win_hostname/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_hostname/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_hostname/defaults/main.yml b/test/integration/targets/win_hostname/defaults/main.yml deleted file mode 100644 index dfc956db29..0000000000 --- a/test/integration/targets/win_hostname/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -test_win_hostname_name: abcdef-123 diff --git a/test/integration/targets/win_hostname/tasks/main.yml b/test/integration/targets/win_hostname/tasks/main.yml deleted file mode 100644 index 6f4df9be77..0000000000 --- a/test/integration/targets/win_hostname/tasks/main.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: get the current hostname - win_command: hostname - register: current_hostname - -- block: - - name: run tests - include_tasks: test.yml - - always: - - name: reset the hostname back to the original - win_hostname: - name: '{{current_hostname.stdout_lines[0]}}' - register: reset_hostname - - - name: reboot if required - win_reboot: - when: reset_hostname.reboot_required diff --git a/test/integration/targets/win_hostname/tasks/test.yml b/test/integration/targets/win_hostname/tasks/test.yml deleted file mode 100644 index 6c3c247a04..0000000000 --- a/test/integration/targets/win_hostname/tasks/test.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -- name: fail to set hostname to an invalid name - win_hostname: - name: invalid/name - register: fail_hostname - failed_when: '"Failed to rename computer to ''invalid/name''" not in fail_hostname.msg' - -- name: change the hostname (check) - win_hostname: - name: '{{test_win_hostname_name}}' - register: change_hostname_check - check_mode: yes - -- name: get actual hostname - win_shell: $env:COMPUTERNAME - register: change_hostname_actual_check - -- name: assert change the hostname (check) - assert: - that: - - change_hostname_check is changed - - change_hostname_check.old_name|upper != test_win_hostname_name|upper - - change_hostname_check.reboot_required - - change_hostname_actual_check.stdout_lines[0]|upper != test_win_hostname_name|upper - -- name: change the hostname - win_hostname: - name: '{{test_win_hostname_name}}' - register: change_hostname - -- name: reboot after changing the hostname - win_reboot: - -- name: get actual hostname - win_shell: $env:COMPUTERNAME - register: change_hostname_actual - -- name: assert change the hostname - assert: - that: - - change_hostname is changed - - change_hostname.old_name|upper == change_hostname_check.old_name|upper - - change_hostname.reboot_required - - change_hostname_actual.stdout_lines[0]|upper == test_win_hostname_name|upper - -- name: change the hostname (idempotent) - win_hostname: - name: '{{test_win_hostname_name}}' - register: change_hostname_again - -- name: assert change the hostname (idempotent) - assert: - that: - - not change_hostname_again is changed - - change_hostname_again.old_name|upper == test_win_hostname_name|upper - - not change_hostname_again.reboot_required diff --git a/test/integration/targets/win_optional_feature/aliases b/test/integration/targets/win_optional_feature/aliases deleted file mode 100644 index 9ad549d4a6..0000000000 --- a/test/integration/targets/win_optional_feature/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group2 -skip/windows/2008 -skip/windows/2008-R2 diff --git a/test/integration/targets/win_optional_feature/tasks/main.yml b/test/integration/targets/win_optional_feature/tasks/main.yml deleted file mode 100644 index 556590cee4..0000000000 --- a/test/integration/targets/win_optional_feature/tasks/main.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Test code for win_optional_feature module -# Copyright: (c) 2019, Carson Anderson <rcanderson23@gmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: check if host supports module - win_shell: if (Get-Command -Name Enable-WindowsOptionalFeature -ErrorAction SilentlyContinue) { $true } else { $false } - register: run_tests - -- name: run tests - when: run_tests.stdout | trim | bool - block: - - name: ensure we start test with removed features - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: absent - - include_tasks: tests.yml - - always: - - name: make sure test features have been removed after test - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: absent diff --git a/test/integration/targets/win_optional_feature/tasks/tests.yml b/test/integration/targets/win_optional_feature/tasks/tests.yml deleted file mode 100644 index ebec9e8d34..0000000000 --- a/test/integration/targets/win_optional_feature/tasks/tests.yml +++ /dev/null @@ -1,151 +0,0 @@ -# Test code for win_optional_feature module -# Copyright: (c) 2019, Carson Anderson <rcanderson23@gmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: fail with invalid feature name - win_optional_feature: - name: - - TelnetClient - - FakeFeature - state: present - register: invalid_name - failed_when: invalid_name.msg != "Failed to find feature 'FakeFeature'" - -- name: run with check_mode - win_optional_feature: - name: TelnetClient - state: present - include_parent: true - check_mode: yes - register: feature_check - -- name: assert check_mode - assert: - that: - - feature_check.changed - -- name: run without check_mode - win_optional_feature: - name: TelnetClient - state: present - include_parent: true - register: real_feature_check - -- name: assert feature installed - assert: - that: - - real_feature_check.changed - -- name: test idempotence for install - win_optional_feature: - name: TelnetClient - state: present - include_parent: true - register: real_feature_check - -- name: assert idempotence - assert: - that: - - not real_feature_check.changed - -- name: install feature with list - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: present - include_parent: true - register: install_list - -- name: assert install feature with list - assert: - that: - - install_list is changed - -- name: install feature with list (idempotent) - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: present - include_parent: true - register: install_list_again - -- name: assert install feature with list (idempotent) - assert: - that: - - not install_list_again is changed - -- name: removal run with check_mode - win_optional_feature: - name: TelnetClient - state: absent - check_mode: yes - register: feature_check - -- name: assert removal check_mode - assert: - that: - - feature_check.changed - -- name: remove feature - win_optional_feature: - name: TelnetClient - state: absent - register: real_feature_check - -- name: assert feature removed - assert: - that: - - real_feature_check.changed - -- name: test idempotence for removal - win_optional_feature: - name: TelnetClient - state: absent - register: real_feature_check - -- name: assert idempotence - assert: - that: - - not real_feature_check.changed - -- name: remove feature with list - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: absent - register: remove_feature_list - -- name: assert remove feature with list - assert: - that: - - remove_feature_list is changed - -- name: remove feature with list (idempotent) - win_optional_feature: - name: - - SimpleTCP - - TelnetClient - state: absent - register: remove_feature_list_again - -- name: assert remove feature with list (idempotent) - assert: - that: - - not remove_feature_list_again is changed diff --git a/test/integration/targets/win_owner/aliases b/test/integration/targets/win_owner/aliases deleted file mode 100644 index 641468f584..0000000000 --- a/test/integration/targets/win_owner/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group5 -shippable/windows/smoketest diff --git a/test/integration/targets/win_owner/defaults/main.yml b/test/integration/targets/win_owner/defaults/main.yml deleted file mode 100644 index a3882a95f6..0000000000 --- a/test/integration/targets/win_owner/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_win_owner_path: C:\ansible\win_owner .ÅÑŚÌβŁÈ [$!@^&test(;)] diff --git a/test/integration/targets/win_owner/tasks/main.yml b/test/integration/targets/win_owner/tasks/main.yml deleted file mode 100644 index 4b6046f409..0000000000 --- a/test/integration/targets/win_owner/tasks/main.yml +++ /dev/null @@ -1,209 +0,0 @@ ---- -# Setup tests -# Use single task to save on CI runtime -- name: create test files - win_shell: | - $folders = @( - "folder", - "folder\folder1", - "folder\folder2", - "folder with space", - "folder with space\folder1", - "folder with space\folder2" - ) - $tmp_dir = '{{ test_win_owner_path }}' - if (Test-Path -LiteralPath $tmp_dir) { - Remove-Item -LiteralPath $tmp_dir -Force -Recurse - } - New-Item -Path $tmp_dir -ItemType Directory - - foreach ($folder in $folders) { - New-Item -Path "$tmp_dir\$folder" -ItemType Directory - } - $files = @( - "folder\file.txt", - "folder\folder1\file.txt", - "folder\folder2\file.txt", - "folder with space\file.txt", - "folder with space\folder1\file.txt", - "folder with space\folder2\file.txt" - ) - foreach ($file in $files) { - Set-Content -LiteralPath "$tmp_dir\$file" -Value "content" - } - -# Run win_owner tests -- name: set owner for invalid path - win_owner: - path: C:\invalid - user: SYSTEM - register: invalid_path - failed_when: invalid_path.msg != 'C:\invalid file or directory does not exist on the host' - -- name: set owner for invalid user - win_owner: - path: "{{test_win_owner_path}}" - user: invalid-user - register: invalid_user - failed_when: invalid_user.msg is not search("account_name invalid-user is not a valid account, cannot get SID.*") - -- name: set owner defaults check - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - register: defaults_check - check_mode: True - -- name: get owner of folder of set owner defaults check - win_shell: (Get-Acl -LiteralPath '{{test_win_owner_path}}\\folder').Owner - register: actual_defaults_check - -- name: assert set owner defaults check - assert: - that: - - defaults_check is changed - - actual_defaults_check.stdout_lines[0] == 'BUILTIN\Administrators' - -- name: set owner defaults - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - register: defaults - -- name: get owner of folder of set owner defaults - win_shell: (Get-Acl -LiteralPath '{{test_win_owner_path}}\\folder').Owner - register: actual_defaults - -- name: assert set owner defaults - assert: - that: - - defaults is changed - - actual_defaults.stdout_lines[0] == 'NT AUTHORITY\SYSTEM' - -- name: set owner defaults again - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - register: defaults_again - -- name: assert set owner defaults again - assert: - that: - - defaults_again is not changed - -- name: set owner recurse check - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - recurse: True - register: recurse_check - check_mode: True - -- name: get owner of folder of set owner recurse check - win_shell: (Get-Acl -LiteralPath '{{test_win_owner_path}}\\{{item.path}}').Owner - register: actual_recurse_check - failed_when: actual_recurse_check.stdout_lines[0] != item.owner - with_items: - - { path: 'folder', owner: 'NT AUTHORITY\SYSTEM' } - - { path: 'folder\file.txt', owner: 'BUILTIN\Administrators' } - - { path: 'folder\folder1', owner: 'BUILTIN\Administrators' } - - { path: 'folder\folder1\file.txt', owner: 'BUILTIN\Administrators' } - - { path: 'folder\folder2', owner: 'BUILTIN\Administrators' } - - { path: 'folder\folder2\file.txt', owner: 'BUILTIN\Administrators' } - -- name: assert set owner recurse check - assert: - that: - - recurse_check is changed - -- name: set owner recurse - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - recurse: True - register: recurse - -- name: get owner of folder of set owner recurse - win_shell: (Get-Acl -LiteralPath '{{test_win_owner_path}}\\{{item}}').Owner - register: actual_recurse - failed_when: actual_recurse.stdout_lines[0] != 'NT AUTHORITY\SYSTEM' - with_items: - - folder - - folder\file.txt - - folder\folder1 - - folder\folder1\file.txt - - folder\folder2 - - folder\folder2\file.txt - -- name: assert set owner recurse - assert: - that: - - recurse is changed - -- name: set owner recurse again - win_owner: - path: "{{test_win_owner_path}}\\folder" - user: SYSTEM - recurse: True - register: recurse_again - -- name: assert set owner recurse again - assert: - that: - - recurse_again is not changed - -- name: create test user - win_user: - name: test win owner - password: E1K0-O8b1-c8M9-c6D5 - register: test_user - -- name: set owner with space recurse - win_owner: - path: "{{test_win_owner_path}}\\folder with space" - user: test win owner - recurse: True - register: recurse_space - -- name: get owner of folder of set owner with space recurse - win_shell: | - $owner = (Get-Acl -LiteralPath '{{ test_win_owner_path }}\{{ item }}').Owner - $account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $owner - $account.Translate([System.Security.Principal.SecurityIdentifier]).Value - register: actual_recurse_space - failed_when: actual_recurse_space.stdout_lines[0] != test_user.sid - with_items: - - folder with space - - folder with space\file.txt - - folder with space\folder1 - - folder with space\folder1\file.txt - - folder with space\folder2 - - folder with space\folder2\file.txt - -- name: assert set owner with space recurse - assert: - that: - - recurse_space is changed - -- name: set owner with space recurse again - win_owner: - path: "{{test_win_owner_path}}\\folder with space" - user: test win owner - recurse: True - register: recurse_space_again - -- name: assert set owner with space recurse again - assert: - that: - - recurse_space_again is not changed - -# Run cleanup after tests -- name: delete test path - win_file: - path: "{{test_win_owner_path}}" - state: absent - -- name: remove test user - win_user: - name: test win owner - state: absent diff --git a/test/integration/targets/win_package/aliases b/test/integration/targets/win_package/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_package/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_package/defaults/main.yml b/test/integration/targets/win_package/defaults/main.yml deleted file mode 100644 index 87d6ec8c16..0000000000 --- a/test/integration/targets/win_package/defaults/main.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -test_path: '{{ remote_tmp_dir }}\win_package .ÅÑŚÌβŁÈ [$!@^&test(;)]' - -# MSI packages -good_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_package/good.msi -reboot_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_package/reboot.msi -bad_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_win_package/bad.msi - -# MSIX tools -makeappx_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_package/makeappx.zip - -# MSP packages - https://wixtoolset.org/documentation/manual/v3/patching/patch_building.html -patch_msi_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_package/patch.msi -patch_msp_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_package/patch.msp -patch_install_file: C:\Program Files (x86)\Patch Sample Directory\Sample.txt - -good_id: '{223D9A13-653B-4231-A365-EDDC30B4F226}' -reboot_id: '{223D9A13-653B-4231-A365-EDDC30B4F227}' -patch_product_id: '{48C49ACE-90CF-4161-9C6E-9162115A54DD}' -patch_patch_id: '{224C316C-5894-4771-BABF-21A3AC1F75FF}' -msix_id: WinPackageMsix -msixbundle_id: WinPackageBundleMsix -appx_id: WinPackageAppx -appxbundle_id: WinPackageBundleAppx -registry_id: WinPackageRegistry - -all_ids: -- '{{ good_id }}' -- '{{ reboot_id }}' -- '{{ patch_product_id }}' -- '{{ msix_id }}' -- '{{ msixbundle_id }}' -- '{{ appx_id }}' -- '{{ appxbundle_id }}' -- '{{ registry_id }}' diff --git a/test/integration/targets/win_package/files/bad.wsx b/test/integration/targets/win_package/files/bad.wsx deleted file mode 100644 index 5014610940..0000000000 --- a/test/integration/targets/win_package/files/bad.wsx +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Product Id="223D9A13-653B-4231-A365-EDDC30B4F228" UpgradeCode="575580C0-AFA1-4C17-8A9C-3CB0CEDC6A06" Name="Bovine University" Manufacturer="Ansible" Version="1.0.0" Language="1033" Codepage="1252"> - <Package InstallerVersion="200" Compressed="yes" Comments="When I grow up I want to go to Bovine University" /> - <Media Id="1" Cabinet="product.cab" EmbedCab="yes" /> - </Product> -</Wix> diff --git a/test/integration/targets/win_package/files/good.wsx b/test/integration/targets/win_package/files/good.wsx deleted file mode 100644 index ee90745687..0000000000 --- a/test/integration/targets/win_package/files/good.wsx +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Product Id="223D9A13-653B-4231-A365-EDDC30B4F226" UpgradeCode="575580C0-AFA1-4C17-8A9C-3CB0CEDC6A05" Name="Bovine University" Manufacturer="Ansible" Version="1.0.0" Language="1033" Codepage="1252"> - <Package InstallerVersion="200" Compressed="yes" Comments="When I grow up I want to go to Bovine University" /> - <Media Id="1" Cabinet="product.cab" EmbedCab="yes" /> - <Directory Id="TARGETDIR" Name="SourceDir"> - <Directory Id="ProgramFilesFolder"> - <Directory Id="INSTALLDIR" Name="Bovine University"> - <Component Id="MooFiles" Guid="D7BC586D-A23C-4002-BC20-76579F25C67D"> - <File Id="MooFile" Source="moo.exe" /> - </Component> - <Component Id="CowFiles" Guid="D1801B2D-8E54-4F19-8B14-A42D8A122A24"> - <File Id="CowFile" Source="cow.exe" /> - </Component> - </Directory> - </Directory> - </Directory> - - <Feature Id="Moo" Level="1"> - <ComponentRef Id="MooFiles" /> - </Feature> - <Feature Id="Cow" Level="1"> - <ComponentRef Id="CowFiles" /> - </Feature> - </Product> -</Wix> diff --git a/test/integration/targets/win_package/files/reboot.wsx b/test/integration/targets/win_package/files/reboot.wsx deleted file mode 100644 index c6ded2a67d..0000000000 --- a/test/integration/targets/win_package/files/reboot.wsx +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Product Id="223D9A13-653B-4231-A365-EDDC30B4F227" UpgradeCode="575580C0-AFA1-4C17-8A9C-3CB0CEDC6A06" Name="Bovine University" Manufacturer="Ansible" Version="1.0.0" Language="1033" Codepage="1252"> - <Package InstallerVersion="200" Compressed="yes" Comments="When I grow up I want to go to Bovine University" /> - <Media Id="1" Cabinet="product.cab" EmbedCab="yes" /> - <Directory Id="TARGETDIR" Name="SourceDir"> - <Directory Id="ProgramFilesFolder"> - <Directory Id="INSTALLDIR" Name="Bovine University"> - <Component Id="MooFiles" Guid="D7BC586D-A23C-4002-BC20-76579F25C67D"> - <File Id="MooFile" Source="moo.exe" /> - </Component> - <Component Id="CowFiles" Guid="D1801B2D-8E54-4F19-8B14-A42D8A122A24"> - <File Id="CowFile" Source="cow.exe" /> - </Component> - </Directory> - </Directory> - </Directory> - - <Feature Id="Moo" Level="1"> - <ComponentRef Id="MooFiles" /> - </Feature> - <Feature Id="Cow" Level="1"> - <ComponentRef Id="CowFiles" /> - </Feature> - - <InstallExecuteSequence> - <ScheduleReboot After="InstallFinalize" /> - </InstallExecuteSequence> - </Product> -</Wix> diff --git a/test/integration/targets/win_package/handlers/main.yml b/test/integration/targets/win_package/handlers/main.yml deleted file mode 100644 index 41cdb8179e..0000000000 --- a/test/integration/targets/win_package/handlers/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: remove trusted root cert - win_certificate_store: - thumbprint: '{{ test_win_package_msix_packages.thumbprint }}' - store_location: LocalMachine - store_name: Root - state: absent - -- name: remove sideloading mode for msix - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock - name: AllowAllTrustedApps - data: 0 - type: dword - state: present diff --git a/test/integration/targets/win_package/library/win_make_appx.ps1 b/test/integration/targets/win_package/library/win_make_appx.ps1 deleted file mode 100644 index eaf6e8e1ee..0000000000 --- a/test/integration/targets/win_package/library/win_make_appx.ps1 +++ /dev/null @@ -1,194 +0,0 @@ -#!powershell - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.ArgvParser -#Requires -Module Ansible.ModuleUtils.CommandUtil - -$spec = @{ - options = @{ - packages = @{ - type = "list" - elements = "dict" - options = @{ - identity = @{ type = "str"; required = $true } - version = @{ type = "str"; required = $true } - architecture = @{ type = "str" } - resource_id = @{ type = "str" } - min_version = @{ type = "str"; default = "10.0.17763.0" } - max_version = @{ type = "str"; default = "10.0.18362.0" } - filename = @{ type = "str"; required = $true } - } - } - bundles = @{ - type = "list" - elements = "dict" - options = @{ - files = @{ type = "list"; elements = "str"; required = $true } - filename = @{ type = "str"; required = $true } - } - } - publisher = @{ type = "str"; required = $true } - path = @{ type = "str"; required = $true } - makeappx_path = @{ type = "str"; required = $true } - signtool_path = @{ type = "str"; required = $true } - } -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$packages = $module.Params.packages -$bundles = $module.Params.bundles -$publisher = $module.Params.publisher -$path = $module.Params.path -$makeappxPath = $module.Params.makeappx_path -$signtoolPath = $module.Params.signtool_path - -if (-not (Test-Path -LiteralPath $path)) { - $module.FailJson("The path at '$path' does not exist") -} - -$manifest = @' -<?xml version="1.0" encoding="utf-8"?> -<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"> - <Identity Name="{0}" Version="{1}" Publisher="{2}"{3}{4} /> - <Properties> - <DisplayName>{0}DisplayName</DisplayName> - <PublisherDisplayName>PublisherDisplayName</PublisherDisplayName> - <Description>Test MSIX Package for win_package</Description> - <Logo>icon.png</Logo> - </Properties> - <Resources> - <Resource Language="en-us" /> - </Resources> - <Dependencies> - <TargetDeviceFamily Name="Windows.Desktop" MinVersion="{5}" MaxVersionTested="{6}" /> - </Dependencies> - <Capabilities> - <rescap:Capability Name="runFullTrust"/> - </Capabilities> - <Applications> - <Application Id="MsixPackage" Executable="test.exe" EntryPoint="Windows.FullTrustApplication"> - <uap:VisualElements DisplayName="{0}AppDisplayName" Description="Description" Square150x150Logo="icon.png" Square44x44Logo="icon.png" BackgroundColor="#464646"/> - </Application> - </Applications> -</Package> -'@ - -# bytes of http://1x1px.me/000000-0.png -$iconBytes = [System.Convert]::FromBase64String('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNiYAAAAAkAAxkR2eQAAAAASUVORK5CYII=') - -$certParams = @{ - # Can only create in the My store, so store it there temporarily. - CertStoreLocation = 'Cert:\CurrentUser\My' - FriendlyName = 'win_package test' - KeyUsage = 'DigitalSignature' - Subject = $publisher - TextExtension = @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") - Type = 'Custom' -} -$cert = New-SelfSignedCertificate @certParams - -try { - # Need to create a temporary pfx for signtool.exe and we need to import the cert to the Trusted Root store. - $module.Result.thumbprint = $cert.Thumbprint - $certPath = Join-Path -Path $module.Tmpdir -ChildPath 'cert.pfx' - $certPassword = ([char[]]([char]33..[char]126) | Sort-Object {Get-Random})[0..16] -join '' - $certPasswordSS = ConvertTo-SecureString -String $certPassword -AsPlainText -Force - $null = $cert | Export-PfxCertificate -FilePath $certPath -Password $certPasswordSS - - $importParams = @{ - FilePath = $certPath - CertStoreLocation = 'Cert:\LocalMachine\Root' - Password = $certPasswordSS - } - $null = Import-PfxCertificate @importParams -} finally { - $cert | Remove-Item -Force -} - -$module.Result.changed = $true - -foreach ($info in $packages) { - $architectureAttribute = "" - if ($info.architecture) { - $architectureAttribute = " ProcessorArchitecture=`"$($info.architecture)`"" - } - - $resourceIdAttribute = "" - if ($info.resource_id) { - $resourceIdAttribute = " ResourceId=`"$($info.resource_id)`"" - } - - $xml = $manifest -f @( - $info.identity, $info.version, $publisher, $architectureAttribute, $resourceIdAttribute, $info.min_version, - $info.max_version - ) - - $tempDir = Join-Path -Path $module.Tmpdir -ChildPath ([System.IO.Path]::GetRandomFileName()) - New-Item -Path $tempDir -ItemType Directory > $null - Set-Content -LiteralPath (Join-Path -Path $tempDir -ChildPath 'AppxManifest.xml') -Value $xml - Set-Content -LiteralPath (Join-Path -Path $tempDir -ChildPath 'icon.png') -Value $iconBytes - Set-Content -LiteralPath (Join-Path -Path $tempDir -ChildPath 'test.exe') -Value '' - - $outPath = Join-Path -Path $path -ChildPath $info.filename - $makeArguments = @($makeappxPath, 'pack', '/d', $tempDir, '/p', $outPath, '/o') - $res = Run-Command -command (Argv-ToString -arguments $makeArguments) - - if ($res.rc -ne 0) { - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Failed to make package for $($info.filename): see stdout and stderr for more info") - } - - Remove-Item -Literalpath $tempDir -Force -Recurse - - $signArguments = @($signtoolPath, 'sign', '/a', '/v', '/fd', 'SHA256', '/f', $certPath, '/p', $certPassword, - $outPath) - $res = Run-Command -command (Argv-ToString -arguments $signArguments) - - if ($res.rc -ne 0) { - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Failed to sign package for $($info.filename): see stdout and stderr for more info") - } -} - -foreach ($info in $bundles) { - $tempDir = Join-Path -Path $module.Tmpdir -ChildPath ([System.IO.Path]::GetRandomFileName()) - New-Item -Path $tempDir -ItemType Directory > $null - foreach ($name in $info.files) { - $sourcePath = Join-Path -Path $path -ChildPath $name - $targetPath = Join-Path -Path $tempDir -ChildPath $name - Move-Item -LiteralPath $sourcePath -Destination $targetPath - } - $outPath = Join-Path -Path $path -ChildPath $info.filename - $makeArguments = @($makeappxPath, 'bundle', '/d', $tempDir, '/p', $outPath, '/o') - $res = Run-Command -command (Argv-ToString -arguments $makeArguments) - - if ($res.rc -ne 0) { - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Failed to make bundle for $($info.filename): see stdout and stderr for more info") - } - - Remove-Item -LiteralPath $tempDir -Force -Recurse - - $signArguments = @($signtoolPath, 'sign', '/a', '/v', '/fd', 'SHA256', '/f', $certPath, '/p', $certPassword, - $outPath) - $res = Run-Command -command (Argv-ToString -arguments $signArguments) - - if ($res.rc -ne 0) { - $module.Result.rc = $res.rc - $module.Result.stdout = $res.stdout - $module.Result.stderr = $res.stderr - $module.FailJson("Failed to sign bundle for $($info.filename): see stdout and stderr for more info") - } -} - -$module.ExitJson() diff --git a/test/integration/targets/win_package/meta/main.yml b/test/integration/targets/win_package/meta/main.yml deleted file mode 100644 index 9f37e96cd9..0000000000 --- a/test/integration/targets/win_package/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_package/tasks/failure_tests.yml b/test/integration/targets/win_package/tasks/failure_tests.yml deleted file mode 100644 index e37e757789..0000000000 --- a/test/integration/targets/win_package/tasks/failure_tests.yml +++ /dev/null @@ -1,60 +0,0 @@ -# these tests are invalid arguments and failure states for win_package ---- -- name: fail to install broken msi - win_package: - path: '{{ test_path }}\bad.msi' - state: present - register: fail_bad_rc - failed_when: "'unexpected rc from' not in fail_bad_rc.msg and fail_bad_rc.rc != 1603" - -- name: fail when not using an int for a return code - win_package: - path: '{{ test_path }}\good.msi' - state: present - expected_return_code: 0,abc - register: fail_invalid_return_code - failed_when: "'argument for list entry expected_return_code is of type System>String and we were unable to convert to in' in fail_invalid_return_code.msg" - -- name: fail when path is not set and state!= absent - win_package: - state: present - register: fail_no_path - failed_when: 'fail_no_path.msg != "state is present but all of the following are missing: path"' - -- name: fail when path is not set and state=absent but product_id is null - win_package: - state: absent - register: fail_no_path_state_absent_no_id - failed_when: 'fail_no_path_state_absent_no_id.msg != "state is absent but any of the following are missing: path, product_id"' - -- name: fail invalid local path - win_package: - path: '{{ test_path }}\no file.msi' - state: present - register: fail_invalid_local_path - failed_when: fail_invalid_local_path.msg != "the file at the path '" + test_path + "\\no file.msi' cannot be reached" - -- name: fail invalid URL - win_package: - path: http://fakeurl/file.msi - product_id: 'id' - state: present - register: fail_invalid_url_path - failed_when: "\"The remote name could not be resolved: 'fakeurl'\" not in fail_invalid_url_path.msg" - -- name: fail to check version without creates_path - win_package: - path: '{{ test_path }}\good.msi' - state: present - creates_version: 1 - register: fail_creates_version_without_path - failed_when: "fail_creates_version_without_path.msg != \"missing parameter(s) required by 'creates_version': creates_path\"" - -- name: fail to check version without when path is not a file - win_package: - path: '{{ test_path }}\good.msi' - state: present - creates_path: C:\Windows - creates_version: 1 - register: fail_creates_version_not_a_file - failed_when: "'creates_path must be a file not a directory when creates_version is set' not in fail_creates_version_not_a_file.msg" diff --git a/test/integration/targets/win_package/tasks/main.yml b/test/integration/targets/win_package/tasks/main.yml deleted file mode 100644 index 250bc8307f..0000000000 --- a/test/integration/targets/win_package/tasks/main.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -- name: ensure testing folder exists - win_file: - path: '{{ test_path }}' - state: directory - -# Some of the registry_tests.yml create a badly formed unisntall string so remove the reg entry in case the test -# didn't get to cleaning itself up -- name: remove registry package path - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - state: absent - -- name: download packages from S3 bucket - win_get_url: - url: '{{ item.url }}' - dest: '{{ test_path }}\{{ item.name }}' - with_items: - - url: '{{ good_url }}' - name: good.msi - - url: '{{ reboot_url }}' - name: reboot.msi - - url: '{{ bad_url }}' - name: bad.msi - - url: '{{ patch_msi_url }}' - name: patch.msi - - url: '{{ patch_msp_url }}' - name: patch.msp - -- name: make sure all test packages are uninstalled before test - win_package: - product_id: '{{ item }}' - state: absent - with_items: '{{ all_ids }}' - -- block: - - name: run tests for expected failures - include_tasks: failure_tests.yml - - - name: run tests for msi files and URL paths - include_tasks: msi_tests.yml - - # The msix test setup will only work on Server 2019 or newer so conditionally run this - - name: check if we can run the msix tests - win_shell: | - $osVersion = [Version](Get-Item -LiteralPath "$env:SystemRoot\System32\kernel32.dll").VersionInfo.ProductVersion - $osVersion -ge [Version]"10.0.17763" - register: can_run_msix - changed_when: False - - - name: run tests for msix packages - include_tasks: msix_tests.yml - when: can_run_msix.stdout | trim | bool - - - name: run tests for msp packages - include_tasks: msp_tests.yml - - - name: run tests for registry packages - include_tasks: registry_tests.yml - - always: - - name: remove registry package path - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - state: absent - - - name: make sure all test packages are uninstalled after test - win_package: - product_id: '{{ item }}' - state: absent - with_items: '{{ all_ids }}' diff --git a/test/integration/targets/win_package/tasks/msi_tests.yml b/test/integration/targets/win_package/tasks/msi_tests.yml deleted file mode 100644 index 4c76084dd1..0000000000 --- a/test/integration/targets/win_package/tasks/msi_tests.yml +++ /dev/null @@ -1,511 +0,0 @@ ---- -# this test just makes sure the task doesn't fail when we set out expected rc -- name: install broken msi override expected rc - win_package: - path: '{{ test_path }}\bad.msi' - state: present - expected_return_code: 0,1603 - -- name: install local msi (check mode) - win_package: - path: '{{ test_path }}\good.msi' - state: present - register: install_local_msi_check - check_mode: yes - -- name: get result of install local msi (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: install_local_msi_actual_check - -- name: assert install local msi (check mode) - assert: - that: - - install_local_msi_check is changed - - install_local_msi_check.reboot_required == False - - install_local_msi_actual_check.exists == False - -- name: install local msi with log - win_package: - path: '{{ test_path }}\good.msi' - state: present - log_path: '{{ test_path }}\msi.log' - register: install_local_msi - -- name: get result of install local msi - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: install_local_msi_actual - -- name: assert install local msi - assert: - that: - - install_local_msi is changed - - install_local_msi.reboot_required == False - - install_local_msi.rc == 0 - - install_local_msi_actual.exists == True - -- name: get result of install local msi log_path - win_stat: - path: '{{ test_path }}\msi.log' - register: install_local_msi_actual_log_path - -- name: assert install local msi log path - assert: - that: - - install_local_msi_actual_log_path.stat.exists == True - -- name: install local msi (idempotent) - win_package: - path: '{{ test_path }}\good.msi' - state: present - register: install_local_msi_idempotent - -- name: assert install local msi (idempotent) - assert: - that: - - install_local_msi_idempotent is not changed - -- name: uninstall local msi with path (check mode) - win_package: - path: '{{ test_path }}\good.msi' - state: absent - register: uninstall_path_local_msi_check - check_mode: yes - -- name: get result of uninstall local msi with path (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: uninstall_path_local_msi_actual_check - -- name: assert uninstall local msi with path (check mode) - assert: - that: - - uninstall_path_local_msi_check is changed - - uninstall_path_local_msi_check.reboot_required == False - - uninstall_path_local_msi_actual_check.exists == True - -- name: uninstall local msi with path - win_package: - path: '{{ test_path }}\good.msi' - state: absent - log_path: '{{ test_path }}\msi uninstall.log' - register: uninstall_path_local_msi - -- name: get result of uninstall local msi with path - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: uninstall_path_local_msi_actual - -- name: assert uninstall local msi with path - assert: - that: - - uninstall_path_local_msi is changed - - uninstall_path_local_msi.reboot_required == False - - uninstall_path_local_msi.rc == 0 - - uninstall_path_local_msi_actual.exists == False - -- name: get result of uninstall local msi with path - win_stat: - path: '{{ test_path }}\msi uninstall.log' - register: uninstall_path_local_msi_actual_log_path - -- name: assert uninstall local msi with path - assert: - that: - - uninstall_path_local_msi_actual_log_path.stat.exists == True # we expect log to remain - -- name: uninstall local msi with path (idempotent) - win_package: - path: '{{ test_path }}\good.msi' - state: absent - register: uninstall_path_local_msi_idempotent - -- name: assert uninstall local msi with path (idempotent) - assert: - that: - - uninstall_path_local_msi_idempotent is not changed - -- name: install url msi (check mode) - win_package: - path: '{{ good_url }}' - product_id: '{{ good_id }}' - state: present - register: install_url_msi_check - check_mode: yes - -- name: get result of install url msi (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: install_url_msi_actual_check - -- name: assert install url msi (check mode) - assert: - that: - - install_url_msi_check is changed - - install_url_msi_check.reboot_required == False - - install_url_msi_actual_check.exists == False - -- name: install url msi - win_package: - path: '{{ good_url }}' - product_id: '{{ good_id }}' - state: present - register: install_url_msi - -- name: get result of install url msi - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: install_url_msi_actual - -- name: assert install url msi - assert: - that: - - install_url_msi is changed - - install_url_msi.reboot_required == False - - install_url_msi.rc == 0 - - install_url_msi_actual.exists == True - -- name: install url msi (idempotent) - win_package: - path: '{{ good_url }}' - product_id: '{{ good_id }}' - state: present - register: install_url_msi_again - -- name: assert install url msi (idempotent) - assert: - that: - - install_url_msi_again is not changed - -- name: uninstall local msi with product_id (check mode) - win_package: - product_id: '{{ good_id }}' - state: absent - register: uninstall_id_local_msi_check - check_mode: yes - -- name: get result of uninstall local msi with product_id (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: uninstall_id_local_msi_actual_check - -- name: assert uninstall local msi with product_id (check mode) - assert: - that: - - uninstall_id_local_msi_check is changed - - uninstall_id_local_msi_check.reboot_required == False - - uninstall_id_local_msi_actual_check.exists == True - -- name: uninstall local msi with product_id - win_package: - product_id: '{{ good_id }}' - state: absent - register: uninstall_id_local_msi - -- name: get result of uninstall local msi with product_id - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ good_id }} - register: uninstall_id_local_msi_actual - -- name: assert uninstall local msi with product_id - assert: - that: - - uninstall_id_local_msi is changed - - uninstall_id_local_msi.reboot_required == False - - uninstall_id_local_msi.rc == 0 - - uninstall_id_local_msi_actual.exists == False - -- name: uninstall local msi with product_id (idempotent) - win_package: - product_id: '{{ good_id }}' - state: absent - register: uninstall_id_local_msi_idempotent - -- name: assert uninstall local msi with product_id (idempotent) - assert: - that: - - uninstall_id_local_msi_idempotent is not changed - -- name: install local reboot msi (check mode) - win_package: - path: '{{ test_path }}\reboot.msi' - state: present - register: install_local_reboot_msi_check - check_mode: yes - -- name: get result of install local reboot msi (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ reboot_id }} - register: install_local_reboot_msi_actual_check - -- name: assert install local reboot msi (check mode) - assert: - that: - - install_local_reboot_msi_check is changed - - install_local_reboot_msi_check.reboot_required == False - - install_local_reboot_msi_actual_check.exists == False - -- name: install local reboot msi - win_package: - path: '{{ test_path }}\reboot.msi' - state: present - register: install_local_reboot_msi - -- name: get result of install local reboot msi - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ reboot_id }} - register: install_local_reboot_msi_actual - -- name: assert install local reboot msi - assert: - that: - - install_local_reboot_msi is changed - - install_local_reboot_msi.reboot_required == True - - install_local_reboot_msi.rc == 3010 - - install_local_reboot_msi_actual.exists == True - -- name: install local reboot msi (idempotent) - win_package: - path: '{{ test_path }}\reboot.msi' - state: present - register: install_local_reboot_msi_idempotent - -- name: assert install local reboot msi (idempotent) - assert: - that: - - install_local_reboot_msi_idempotent is not changed - -- name: uninstall reboot msi after test - win_package: - path: '{{ test_path }}\reboot.msi' - state: absent - -- name: ensure the install folder is cleaned in case uninstall didn't work - win_file: - path: '%ProgramFiles(x86)%\Bovine University' - state: absent - -- name: install local msi with arguments (check mode) - win_package: - path: '{{ test_path }}\good.MSI' - state: present - arguments: ADDLOCAL=Cow - register: install_msi_argument_check - check_mode: yes - -- name: get result of moo file after install local msi with arguments (check mode) - win_stat: - path: '%ProgramFiles(x86)%\Bovine University\moo.exe' - register: install_msi_argument_moo_check - -- name: get result of cow file after install local msi with arguments (check mode) - win_stat: - path: '%ProgramFiles(x86)%\Bovine University\cow.exe' - register: install_msi_argument_cow_check - -- name: assert install local msi with arguments (check mode) - assert: - that: - - install_msi_argument_check is changed - - install_msi_argument_check.reboot_required == False - - install_msi_argument_moo_check.stat.exists == False - - install_msi_argument_cow_check.stat.exists == False - -- name: install local msi with arguments - win_package: - path: '{{ test_path}}\good.MSI' - state: present - arguments: ADDLOCAL=Cow - register: install_msi_argument - -- name: get result of moo file after install local msi with arguments - win_stat: - path: '%ProgramFiles(x86)%\Bovine University\moo.exe' - register: install_msi_argument_moo - -- name: get result of cow file after install local msi with arguments - win_stat: - path: '%ProgramFiles(x86)%\Bovine University\cow.exe' - register: install_msi_argument_cow - -- name: assert install local msi with arguments - assert: - that: - - install_msi_argument is changed - - install_msi_argument.reboot_required == False - - install_msi_argument.rc == 0 - - install_msi_argument_moo.stat.exists == False - - install_msi_argument_cow.stat.exists == True - -- name: install local msi with arguments (idempotent) - win_package: - path: '{{ test_path}}\good.MSI' - state: present - arguments: ADDLOCAL=Cow - register: install_msi_argument_again - -- name: assert install local msi with arguments (idempotent) - assert: - that: - - install_msi_argument_again is not changed - -- name: uninstall good msi after test - win_package: - path: '{{ test_path }}\good.msi' - state: absent - -- name: install good msi for all users - win_package: - path: '{{ test_path }}\good.msi' - state: present - arguments: ALLUSERS=1 - register: install_good_all_users - -- name: get result of install good msi for all users - win_shell: | - Add-Type -Namespace Msi -Name NativeMethods -UsingNamespace System.Text -MemberDefinition @' - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern UInt32 MsiGetProductInfoExW( - string szProductCode, - string szUserSid, - UInt32 dwContext, - string szProperty, - StringBuilder szValue, - ref UInt32 pcchValue); - '@ - - $productCode = '{{ good_id }}' - $sb = New-Object -TypeName System.Text.StringBuilder -ArgumentList 0 - $sbLength = [UInt32]0 - - $null = [Msi.NativeMethods]::MsiGetProductInfoExW($productCode, [NullString]::Value, 4, "State", $sb, [ref]$sbLength) - $sbLength += 1 - $null = $sb.EnsureCapacity($sbLength) - - $null = [Msi.NativeMethods]::MsiGetProductInfoExW($productCode, [NullString]::Value, 4, "State", $sb, [ref]$sbLength) - [int]$sb.ToString() - register: install_good_all_users_actual - -- name: assert install good msi for all users - assert: - that: - - install_good_all_users is changed - - install_good_all_users_actual.stdout | trim | int == 5 # INSTALLSTATE_DEFAULT - -- name: install good msi for all users (idempotent) - win_package: - path: '{{ test_path }}\good.msi' - state: present - arguments: ALLUSERS=1 - register: install_good_all_users_again - -- name: assert install good msi for all users (idempotent) - assert: - that: - - not install_good_all_users_again is changed - -- name: uninstall good msi for all users - win_package: - product_id: '{{ good_id }}' - state: absent - register: uninstall_good_all_users - -- name: get result of uninstall good msi for all users - win_shell: | - Add-Type -Namespace Msi -Name NativeMethods -MemberDefinition @' - [DllImport("Msi.dll", CharSet = CharSet.Unicode)] - public static extern Int32 MsiQueryProductStateW( - string szProductCode); - '@ - [Msi.NativeMethods]::MsiQueryProductStateW('{{ good_id }}') - register: uninstall_good_all_users_actual - -- name: assert uninstall good msi for all users - assert: - that: - - uninstall_good_all_users is changed - - uninstall_good_all_users_actual.stdout | trim | int == -1 # INSTALLSTATE_UNKNOWN - -- name: create custom install directory for msi install - win_file: - path: '{{ test_path }}\msi install' - state: directory - -- name: install msi to custom path using string arguments - win_package: - path: '{{ test_path }}\good.msi' - state: present - arguments: ADDLOCAL=Cow INSTALLDIR="{{ test_path }}\msi install" - register: install_msi_string_arguments - -- name: get result of moo file after install local msi with string arguments - win_stat: - path: '{{ test_path }}\msi install\moo.exe' - register: install_msi_string_arguments_moo - -- name: get result of cow file after install local msi with string arguments - win_stat: - path: '{{ test_path }}\msi install\cow.exe' - register: install_msi_string_arguments_cow - -- name: assert results of install msi to custom path using string arguments - assert: - that: - - install_msi_string_arguments is changed - - install_msi_string_arguments.reboot_required == False - - install_msi_string_arguments.rc == 0 - - install_msi_string_arguments_moo.stat.exists == False - - install_msi_string_arguments_cow.stat.exists == True - -- name: uninstall good msi after string argument test - win_package: - path: '{{ test_path }}\good.msi' - state: absent - -# MSI arguments KEY="value" are known to fail when set as a list, for this test just create a simple folder path that -# does not need to be escaped and cleanup at the end. -- name: create a simple spaceless folder for argument list test - win_file: - path: C:\ansible_win_package - state: directory - -- block: - - name: install msi to custom path using list arguments - win_package: - path: '{{ test_path }}\good.msi' - state: present - arguments: - - ADDLOCAL=Moo - - INSTALLDIR=C:\ansible_win_package - register: install_msi_list_arguments - - - name: get result of moo file after install local msi with list arguments - win_stat: - path: C:\ansible_win_package\moo.exe - register: install_msi_list_arguments_moo - - - name: get result of cow file after install local msi with list arguments - win_stat: - path: C:\ansible_win_package\cow.exe - register: install_msi_list_arguments_cow - - - name: assert results of install msi to custom path using list arguments - assert: - that: - - install_msi_list_arguments is changed - - install_msi_list_arguments.reboot_required == False - - install_msi_list_arguments.rc == 0 - - install_msi_list_arguments_moo.stat.exists == True - - install_msi_list_arguments_cow.stat.exists == False - - - name: uninstall good msi after list argument test - win_package: - path: '{{ test_path }}\good.msi' - state: absent - - always: - - name: remove spaceless folder for argument list test - win_file: - path: C:\ansible_win_package - state: absent diff --git a/test/integration/targets/win_package/tasks/msix_tests.yml b/test/integration/targets/win_package/tasks/msix_tests.yml deleted file mode 100644 index 1cec9d7bfa..0000000000 --- a/test/integration/targets/win_package/tasks/msix_tests.yml +++ /dev/null @@ -1,448 +0,0 @@ ---- -- name: enable sideloading of apps for test - win_regedit: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock - name: AllowAllTrustedApps - data: 1 - type: dword - state: present - notify: remove sideloading mode for msix - -- name: download makeappx binaries - win_get_url: - url: '{{ makeappx_url }}' - dest: '{{ test_path }}\makeappx.zip' - -- name: extract makeappx binaries - win_shell: Expand-Archive -LiteralPath '{{ test_path }}\makeappx.zip' -DestinationPath '{{ test_path }}\makeappx' - -- name: setup MSIX packages - win_make_appx: - packages: - - identity: '{{ msix_id }}' - version: 1.0.0.0 - filename: WinPackage-1.0.0.0.msix - - identity: '{{ msix_id }}' - version: 1.0.0.1 - filename: WinPackage-1.0.0.1.msix - - identity: '{{ appx_id }}' - version: 1.0.0.0 - filename: WinPackage.appx - - identity: '{{ msixbundle_id }}' - version: 1.0.0.1 - architecture: x64 - resource_id: resid - filename: WinPackageBundle-x64.msix - - identity: '{{ msixbundle_id }}' - version: 1.0.0.1 - architecture: x86 - resource_id: resid - filename: WinPackageBundle-x86.msix - - identity: '{{ appxbundle_id }}' - version: 1.0.0.1 - architecture: x64 - resource_id: resid - filename: WinPackageBundle-x64.appx - - identity: '{{ appxbundle_id }}' - version: 1.0.0.1 - architecture: x86 - resource_id: resid - filename: WinPackageBundle-x86.appx - - identity: FailMsix - version: 1.2.3.4 - min_version: 99.0.0.0 - max_version: 99.0.0.0 - filename: Fail.msix - bundles: - - files: - - WinPackageBundle-x64.msix - - WinPackageBundle-x86.msix - filename: WinPackageBundle.msixbundle - - files: - - WinPackageBundle-x64.appx - - WinPackageBundle-x86.appx - filename: WinPackageBundle.appxbundle - publisher: CN=Ansible Core, O=Ansible, L=Durhan, S=NC, C=USA - path: '{{ test_path }}' - makeappx_path: '{{ test_path }}\makeappx\makeappx.exe' - signtool_path: '{{ test_path }}\makeappx\signtool.exe' - become: yes # New-SelfSignedCertificate requires this to store the cert with key into the store. - become_method: runas - vars: - ansible_become_user: '{{ ansible_user }}' - ansible_become_pass: '{{ ansible_password }}' - register: test_win_package_msix_packages - notify: remove trusted root cert - -- name: install msix (check mode) - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.0.msix' - state: present - register: msix_install_check - check_mode: yes - -- name: get result of install msix (check mode) - win_shell: if (Get-AppxPackage -Name '{{ msix_id }}') { $true } else { $false } - register: msix_install_actual_check - changed_when: False - -- name: assert install msix (check mode) - assert: - that: - - msix_install_check is changed - - msix_install_check.rc == 0 - - not msix_install_check.reboot_required - - not msix_install_actual_check.stdout | trim | bool - -- name: install msix - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.0.msix' - state: present - register: msix_install - -- name: get result of install msix - win_shell: if (Get-AppxPackage -Name '{{ msix_id }}') { $true } else { $false } - register: msix_install_actual - changed_when: False - -- name: assert install msix - assert: - that: - - msix_install is changed - - msix_install.rc == 0 - - not msix_install.reboot_required - - msix_install_actual.stdout | trim | bool - -- name: install msix (idempotence) - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.0.msix' - state: present - register: msix_install_again - -- name: assert install msix (idempotence) - assert: - that: - - not msix_install_again is changed - -- name: install updated msix package - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.1.msix' - state: present - register: msix_install_updated - -- name: get result of install updated msix package - win_shell: Get-AppxPackage -Name '{{ msix_id }}' | Select-Object -ExpandProperty Version - changed_when: False - register: msix_install_updated_actual - -- name: assert result of install updated msix package - assert: - that: - - msix_install_updated is changed - - msix_install_updated.rc == 0 - - not msix_install_updated.reboot_required - - msix_install_updated_actual.stdout | trim == "1.0.0.1" - -- name: fail to install older msix when new is present - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.0.msix' - state: present - register: fail_msix_older - failed_when: "'unexpected status from Add-AppxPackage' not in fail_msix_older.msg" - -- name: remove msix by path (check mode) - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.1.msix' - state: absent - register: msix_uninstall_check - check_mode: yes - -- name: get result of remove msix by path (check mode) - win_shell: if (Get-AppxPackage -Name '{{ msix_id }}') { $true } else { $false } - changed_when: False - register: msix_uninstall_actual_check - -- name: assert results of remove msix by path (check mode) - assert: - that: - - msix_uninstall_check is changed - - msix_uninstall_check.rc == 0 - - not msix_uninstall_check.reboot_required - - msix_uninstall_actual_check.stdout | trim | bool - -- name: remove msix by path - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.1.msix' - state: absent - register: msix_uninstall - -- name: get result of remove msix by path - win_shell: if (Get-AppxPackage -Name '{{ msix_id }}') { $true } else { $false } - changed_when: False - register: msix_uninstall_actual - -- name: assert results of remove msix by path - assert: - that: - - msix_uninstall is changed - - msix_uninstall.rc == 0 - - not msix_uninstall.reboot_required - - not msix_uninstall_actual.stdout | trim | bool - -- name: remove msix by path (idempotence) - win_package: - path: '{{ test_path }}\WinPackage-1.0.0.1.msix' - state: absent - register: msix_uninstall_again - -- name: assert results of remove msix by path (idempotence) - assert: - that: - - not msix_uninstall_again is changed - -# The install steps are the same as msix so no need for check and idempotency tests -- name: install appx - win_package: - path: '{{ test_path }}\WinPackage.appx' - state: present - register: appx_install - -- name: get result of install appx - win_shell: if (Get-AppxPackage -Name '{{ appx_id }}') { $true } else { $false } - changed_when: False - register: appx_install_actual - -- name: assert results of install appx - assert: - that: - - appx_install is changed - - appx_install.rc == 0 - - not appx_install.reboot_required - - appx_install_actual.stdout | trim | bool - -- name: remove appx by id (check mode) - win_package: - product_id: '{{ appx_id }}' - state: absent - register: appx_uninstall_check - check_mode: yes - -- name: get result of remove appx (check mode) - win_shell: if (Get-AppxPackage -Name '{{ appx_id }}') { $true } else { $false } - changed_when: False - register: appx_uninstall_actual_check - -- name: assert results of remove appx by id (check mode) - assert: - that: - - appx_uninstall_check is changed - - appx_uninstall_check.rc == 0 - - not appx_uninstall_check.reboot_required - - appx_uninstall_actual_check.stdout | trim | bool - -- name: remove appx by id - win_package: - product_id: '{{ appx_id }}' - state: absent - register: appx_uninstall - -- name: get result of remove appx - win_shell: if (Get-AppxPackage -Name '{{ appx_id }}') { $true } else { $false } - changed_when: False - register: appx_uninstall_actual - -- name: assert results of remove appx by id - assert: - that: - - appx_uninstall is changed - - appx_uninstall.rc == 0 - - not appx_uninstall.reboot_required - - not appx_uninstall_actual.stdout | trim | bool - -- name: remove appx by id (idempotence) - win_package: - product_id: '{{ appx_id }}' - state: absent - register: appx_uninstall_again - -- name: assert results of remove appx by id (idempotence) - assert: - that: - - not appx_uninstall_again is changed - -- name: validate failures are detected on a bad package - win_package: - path: '{{ test_path }}\Fail.msix' - state: present - register: fail_msix - failed_when: "'unexpected status from Add-AppxPackage' not in fail_msix.msg" - -- name: install msixbundle (check mode) - win_package: - path: '{{ test_path }}\WinPackageBundle.msixbundle' - state: present - register: msixbundle_install_check - check_mode: yes - -- name: get result of install msixbundle (check mode) - win_shell: if (Get-AppxPackage -Name '{{ msixbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_install_actual_check - -- name: assert install msixbundle (check mode) - assert: - that: - - msixbundle_install_check is changed - - msixbundle_install_check.rc == 0 - - not msixbundle_install_check.reboot_required - - not msixbundle_install_actual_check.stdout | trim | bool - -- name: install msixbundle - win_package: - path: '{{ test_path }}\WinPackageBundle.msixbundle' - state: present - register: msixbundle_install - -- name: get result of install msixbundle - win_shell: if (Get-AppxPackage -Name '{{ msixbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_install_actual - -- name: assert install msixbundle - assert: - that: - - msixbundle_install is changed - - msixbundle_install.rc == 0 - - not msixbundle_install.reboot_required - - msixbundle_install_actual.stdout | trim | bool - -- name: install msixbundle (idempotence) - win_package: - path: '{{ test_path }}\WinPackageBundle.msixbundle' - state: present - register: msixbundle_install_again - -- name: assert install msixbundle (idempotence) - assert: - that: - - not msixbundle_install_again is changed - -- name: uninstall msixbundle by id (check mode) - win_package: - product_id: '{{ msixbundle_id }}' - state: absent - register: msixbundle_uninstall_check - check_mode: yes - -- name: get result of uninstall msixbundle by id (check mode) - win_shell: if (Get-AppxPackage -Name '{{ msixbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_uninstall_actual_check - -- name: assert uninstall msixbundle by id (check mode) - assert: - that: - - msixbundle_uninstall_check is changed - - msixbundle_uninstall_check.rc == 0 - - not msixbundle_uninstall_check.reboot_required - - msixbundle_uninstall_actual_check.stdout | trim | bool - -- name: uninstall msixbundle by id - win_package: - product_id: '{{ msixbundle_id }}' - state: absent - register: msixbundle_uninstall - -- name: get result of uninstall msixbundle by id - win_shell: if (Get-AppxPackage -Name '{{ msixbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_uninstall_actual - -- name: assert uninstall msixbundle by id - assert: - that: - - msixbundle_uninstall is changed - - msixbundle_uninstall.rc == 0 - - not msixbundle_uninstall.reboot_required - - not msixbundle_uninstall_actual.stdout | trim | bool - -- name: uninstall msixbundle by id (idempotence) - win_package: - product_id: '{{ msixbundle_id }}' - state: absent - register: msixbundle_uninstall_again - -- name: assert uninstall msixbundle by id (idempotence) - assert: - that: - - not msixbundle_uninstall_again is changed - -# The logic for appxbundle is the same for msixbundle no need for check and idempotence tests -- name: install appxbundle - win_package: - path: '{{ test_path }}\WinPackageBundle.appxbundle' - state: present - register: appxbundle_install - -- name: get result of install appxbundle - win_shell: if (Get-AppxPackage -Name '{{ appxbundle_id }}') { $true } else { $false } - changed_when: False - register: appxbundle_install_actual - -- name: assert install appxbundle - assert: - that: - - appxbundle_install is changed - - appxbundle_install.rc == 0 - - not appxbundle_install.reboot_required - - appxbundle_install_actual.stdout | trim | bool - -- name: uninstall appxbundle by path (check mode) - win_package: - path: '{{ test_path }}\WinPackageBundle.appxbundle' - state: absent - register: msixbundle_uninstall_check - check_mode: yes - -- name: get result of uninstall appxbundle by path (check mode) - win_shell: if (Get-AppxPackage -Name '{{ appxbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_uninstall_actual_check - -- name: assert uninstall appxbundle by path (check mode) - assert: - that: - - msixbundle_uninstall_check is changed - - msixbundle_uninstall_check.rc == 0 - - not msixbundle_uninstall_check.reboot_required - - msixbundle_uninstall_actual_check.stdout | trim | bool - -- name: uninstall appxbundle by path - win_package: - path: '{{ test_path }}\WinPackageBundle.appxbundle' - state: absent - register: msixbundle_uninstall - -- name: get result of uninstall appxbundle by path - win_shell: if (Get-AppxPackage -Name '{{ appxbundle_id }}') { $true } else { $false } - changed_when: False - register: msixbundle_uninstall_actual - -- name: assert uninstall appxbundle by path - assert: - that: - - msixbundle_uninstall is changed - - msixbundle_uninstall.rc == 0 - - not msixbundle_uninstall.reboot_required - - not msixbundle_uninstall_actual.stdout | trim | bool - -- name: uninstall appxbundle by path (idempotence) - win_package: - path: '{{ test_path }}\WinPackageBundle.appxbundle' - state: absent - register: msixbundle_uninstall_again - -- name: assert uninstall appxbundle by path (idempotence) - assert: - that: - - not msixbundle_uninstall_again is changed diff --git a/test/integration/targets/win_package/tasks/msp_tests.yml b/test/integration/targets/win_package/tasks/msp_tests.yml deleted file mode 100644 index cb7ffe9486..0000000000 --- a/test/integration/targets/win_package/tasks/msp_tests.yml +++ /dev/null @@ -1,167 +0,0 @@ ---- -- name: fail if base product is not applied - win_package: - path: '{{ test_path }}\patch.msp' - state: present - register: fail_no_product_found - failed_when: '"The specified patch does not apply to any installed MSI packages" not in fail_no_product_found.msg' - -- name: install base package for msp patch - win_package: - path: '{{ test_path }}\patch.msi' - state: present - -- name: install msp (check mode) - win_package: - path: '{{ test_path }}\patch.msp' - state: present - register: msp_install_check - check_mode: yes - -- name: get result of install msp (check mode) - slurp: - path: '{{ patch_install_file }}' - register: msp_install_actual_check - -- name: assert install msp (check mode) - assert: - that: - - msp_install_check is changed - - msp_install_check.rc == 0 - - not msp_install_check.reboot_required - - msp_install_actual_check.content | b64decode == 'This is version 1.0' - -- name: install msp - win_package: - path: '{{ test_path }}\patch.msp' - state: present - register: msp_install - -- name: get result of install msp - slurp: - path: '{{ patch_install_file }}' - register: msp_install_actual - -- name: assert install msp - assert: - that: - - msp_install is changed - - msp_install.rc == 0 - - not msp_install.reboot_required - - msp_install_actual.content | b64decode == 'This is version 1.1' - -- name: install msp (idempotence) - win_package: - path: '{{ test_path }}\patch.msp' - state: present - register: msp_install_again - -- name: assert install msp (idempotence) - assert: - that: - - not msp_install_again is changed - -- name: remove msp by path (check mode) - win_package: - path: '{{ test_path }}\patch.msp' - state: absent - register: msp_uninstall_path_check - check_mode: yes - -- name: get result of remove msp by path (check mode) - slurp: - path: '{{ patch_install_file }}' - register: msp_uninstall_path_actual_check - -- name: assert remove msp by path (check mode) - assert: - that: - - msp_uninstall_path_check is changed - - msp_uninstall_path_check.rc == 0 - - not msp_uninstall_path_check.reboot_required - - msp_uninstall_path_actual_check.content | b64decode == 'This is version 1.1' - -- name: remove msp by path - win_package: - path: '{{ test_path }}\patch.msp' - state: absent - register: msp_uninstall_path - -- name: get result of remove msp by path - slurp: - path: '{{ patch_install_file }}' - register: msp_uninstall_path_actual - -- name: assert remove msp by path - assert: - that: - - msp_uninstall_path is changed - - msp_uninstall_path.rc == 0 - - not msp_uninstall_path.reboot_required - - msp_uninstall_path_actual.content | b64decode == 'This is version 1.0' - -- name: remove msp by path (idempotence) - win_package: - path: '{{ test_path }}\patch.msp' - state: absent - register: msp_uninstall_path_again - -- name: assert remove msp by path (idempotence) - assert: - that: - - not msp_uninstall_path_again is changed - -- name: install patch again - win_package: - path: '{{ test_path }}\patch.msp' - state: present - -- name: remove msp by id (check mode) - win_package: - product_id: '{{ patch_patch_id }}' - state: absent - register: msp_uninstall_id_check - check_mode: yes - -- name: get result of remove msp by id (check mode) - slurp: - path: '{{ patch_install_file }}' - register: msp_uninstall_id_actual_check - -- name: assert remove msp by id (check mode) - assert: - that: - - msp_uninstall_id_check is changed - - msp_uninstall_id_check.rc == 0 - - not msp_uninstall_id_check.reboot_required - - msp_uninstall_id_actual_check.content | b64decode == 'This is version 1.1' - -- name: remove msp by id - win_package: - product_id: '{{ patch_patch_id }}' - state: absent - register: msp_uninstall_id - -- name: get result of remove msp by id - slurp: - path: '{{ patch_install_file }}' - register: msp_uninstall_id_actual - -- name: assert remove msp by id - assert: - that: - - msp_uninstall_id is changed - - msp_uninstall_id.rc == 0 - - not msp_uninstall_id.reboot_required - - msp_uninstall_id_actual.content | b64decode == 'This is version 1.0' - -- name: remove msp by id (idempotence) - win_package: - product_id: '{{ patch_patch_id }}' - state: absent - register: msp_uninstall_id_again - -- name: assert remove msp by id (idempotence) - assert: - that: - - not msp_uninstall_id_again is changed diff --git a/test/integration/targets/win_package/tasks/registry_tests.yml b/test/integration/targets/win_package/tasks/registry_tests.yml deleted file mode 100644 index b4b5a8e2bd..0000000000 --- a/test/integration/targets/win_package/tasks/registry_tests.yml +++ /dev/null @@ -1,393 +0,0 @@ ---- -# This symlink allows us to test paths with a space in the executable path -- name: create symbolic link in test folder to powershell - win_command: cmd.exe /c mklink "{{ test_path }}\powershell symlink.exe" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - -- name: copy across test script that creates a registry install entry - win_template: - src: registry_package.ps1.j2 - dest: '{{ test_path }}\registry_package.ps1' - -- name: install registry package not quoted and no spaces in path - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - UninstallString - - C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse - state: present - -- name: uninstall registry package not quoted and no spaces in path (check mode) - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_normal_check - check_mode: yes - -- name: get result of uninstall registry package not quoted and no spaces in path (check mode) - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_normal_actual_check - -- name: assert uninstall registry package not quoted and no spaces in path (check mode) - assert: - that: - - registry_uninstall_normal_check is changed - - registry_uninstall_normal_check.rc == 0 - - not registry_uninstall_normal_check.reboot_required - - registry_uninstall_normal_actual_check.exists - -- name: uninstall registry package not quoted and no spaces in path - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_normal - -- name: get result of uninstall registry package not quoted and no spaces in path - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_normal_actual - -- name: assert uninstall registry package not quoted and no spaces in path - assert: - that: - - registry_uninstall_normal is changed - - registry_uninstall_normal.rc == 0 - - not registry_uninstall_normal.reboot_required - - not registry_uninstall_normal_actual.exists - -- name: uninstall registry package not quoted and no spaces in path (idempotence) - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_normal_again - -- name: assert uninstall registry package not quoted and no spaces in path (idempotence) - assert: - that: - - not registry_uninstall_normal_again is changed - -- name: install registry package not quoted and spaces in path - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx86 - - QuietUninstallString - - '{{ test_path }}\powershell symlink.exe -Command Remove-Item -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse' - state: present - -- name: uninstall registry package not quoted and spaces in path - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_not_quoted - -- name: get result of uninstall registry package not quoted and spaces in path - win_reg_stat: - path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_not_quoted_actual - -- name: assert uninstall registry package not quoted and spaces in path - assert: - that: - - registry_uninstall_not_quoted is changed - - registry_uninstall_not_quoted.rc == 0 - - not registry_uninstall_not_quoted.reboot_required - - not registry_uninstall_not_quoted_actual.exists - -- name: install registry package quoted and no spaces in path - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKCUx64 - - UninstallString - - '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Command Remove-Item -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse' - state: present - -- name: uninstall registry package quoted and no spaces in path - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_quoted_normal - -- name: get result of uninstall registry package quoted and no spaces in path - win_reg_stat: - path: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Unisntall\{{ registry_id }} - register: registry_uninstall_quoted_normal_actual - -- name: assert uninstall registry package quoted and no spaces in path - assert: - that: - - registry_uninstall_quoted_normal is changed - - registry_uninstall_quoted_normal.rc == 0 - - not registry_uninstall_quoted_normal.reboot_required - - not registry_uninstall_quoted_normal_actual.exists - -- name: install registry package quoted and spaces in path - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKCUx86 - - QuietUninstallString - - '"{{ test_path }}\powershell symlink.exe" -Command Remove-Item -Path HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse' - state: present - -- name: uninstall registry package quoted and spaces in path - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_quoted_spaces - -- name: get result of uninstall registry package quoted and spaces in path - win_reg_stat: - path: HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_quoted_spaces_actual - -- name: assert uninstall registry package quoted and spaces in path - assert: - that: - - registry_uninstall_quoted_spaces is changed - - registry_uninstall_quoted_spaces.rc == 0 - - not registry_uninstall_quoted_spaces.reboot_required - - not registry_uninstall_quoted_spaces_actual.exists - -- name: install registry package with unquoted env vars - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - UninstallString - - '%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse' - state: present - -- name: uninstall registry package with unquoted env vars - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_env - -- name: get result of ininstall registry package with unquoted env vars - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_env_actual - -- name: assert uninstall registry package with unquoted env vars - assert: - that: - - registry_uninstall_env is changed - - registry_uninstall_env.rc == 0 - - not registry_uninstall_env.reboot_required - - not registry_uninstall_env_actual.exists - -- name: install registry package quoted env vars - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - UninstallString - - '"%TestVar%\powershell symlink.exe" -Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse' - state: present - -- name: uninstall registry package quoted env vars - win_package: - product_id: '{{ registry_id }}' - state: absent - register: registry_uninstall_env_quoted - environment: - TestVar: '{{ test_path }}' - -- name: get result of uninstall registry package quoted env vars - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_env_quoted_actual - -- name: assert uninstall registry package quoted env vars - assert: - that: - - registry_uninstall_env_quoted is changed - - registry_uninstall_env_quoted.rc == 0 - - not registry_uninstall_env_quoted.reboot_required - - not registry_uninstall_env_quoted_actual.exists - -- name: install registry package for overriding path test - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - UninstallString - - Fail path - state: present - -- name: uninstall registry package with overridden path and explicit error code - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - product_id: '{{ registry_id }}' - arguments: '-Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }}; exit 1' - expected_return_code: 1 - state: absent - register: registry_uninstall_explicit_path - -- name: get result of uninstall registry package with overridden path and explicit error code - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_explicit_path_actual - -- name: assert unisntall registry package with overridden path and explicit error code - assert: - that: - - registry_uninstall_explicit_path is changed - - registry_uninstall_explicit_path.rc == 1 - - not registry_uninstall_explicit_path.reboot_required - - not registry_uninstall_explicit_path_actual.exists - -- name: create registry package for uninstal with explicit arguments test - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - QuietUninstallString - - C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - state: present - -- name: uninstall registry package with explicit arguments and chdir - win_package: - product_id: '{{ registry_id }}' - arguments: -Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse; [System.IO.File]::WriteAllText('{{ test_path }}\reg_out.txt', $pwd.Path, [System.Text.Encoding]::Unicode); exit 3010 - state: absent - chdir: C:\Users - register: registry_uninstall_arguments - -- name: get package result of uninstall registry package with explicit arguments and chdir - win_reg_stat: - path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} - register: registry_uninstall_arguments_reg_actual - -- name: get package output of uninstall registry package with explicit arguments and chdir - slurp: - path: '{{ test_path }}\reg_out.txt' - register: registry_uninstall_arguments_chdir_actual - -- name: assert uninstall registry package with explicit arguments and chdir - assert: - that: - - registry_uninstall_arguments is changed - - registry_uninstall_arguments.rc == 3010 - - registry_uninstall_arguments.reboot_required - - not registry_uninstall_arguments_reg_actual.exists - # backslash escaping makes it hard to compare the value, just compare the raw base64 string expected which is 'C:\Users' as UTF-16-LE - - registry_uninstall_arguments_chdir_actual.content == '//5DADoAXABVAHMAZQByAHMA' - -- name: install package for creates_* tests - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: - - -File - - '{{ test_path }}\registry_package.ps1' - - HKLMx64 - - UninstallString - - powershell.exe -Command Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{ registry_id }} -Force -Recurse - state: present - -- name: get actual PowerShell file version for tests - win_shell: | - $path = '{{ test_path }}\powershell symlink.exe' - $version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($path) - (New-Object -TypeName System.Version -ArgumentList @( - $version.FileMajorPart, $version.FileMinorPart, $version.FileBuildPart, $version.FilePrivatePart - )).ToString() - changed_when: False - register: powershell_version - -- name: test creates_path overrides product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: '{{ registry_id }}' - creates_path: C:\missing - state: present - register: creates_path - -- name: test creates_version overrides product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: '{{ registry_id }}' - creates_path: '{{ test_path }}\powershell symlink.exe' - creates_version: 1.0.0 - state: present - register: creates_version - -- name: assert test creates_path and creates_version override product_id is changed - assert: - that: - - creates_path is changed - - creates_version is changed - -- name: test creates_path to existing but no product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: Fake - creates_path: C:\Windows - state: present - register: creates_path_present - -- name: test creates_version to existing but no product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: Fake - creates_path: '{{ test_path }}\powershell symlink.exe' - creates_version: '{{ powershell_version.stdout | trim }}' - state: present - register: creates_version_present - -- name: assert test creates_path to existing but no product_Id - assert: - that: - - not creates_path_present is changed - - not creates_version_present is changed - -- name: test creates_service overrides product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: '{{ registry_id }}' - creates_service: missing service - state: present - register: creates_service - -- name: assert test creates_service overrides product_id - assert: - that: - - creates_service is changed - -- name: test creates_service to existing but no product_id - win_package: - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe - arguments: echo hi - product_id: Fake - creates_service: winrm - state: present - register: creates_service_present - -- name: assert test creates_service to existing but no product_Id - assert: - that: - - not creates_service_present is changed diff --git a/test/integration/targets/win_package/templates/registry_package.ps1.j2 b/test/integration/targets/win_package/templates/registry_package.ps1.j2 deleted file mode 100644 index b82b21d0c0..0000000000 --- a/test/integration/targets/win_package/templates/registry_package.ps1.j2 +++ /dev/null @@ -1,26 +0,0 @@ -$ErrorActionPreference = 'Stop' - -$productId = '{{ registry_id }}' - -$regPath = switch ($args[0]) { - HKLMx64 { 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' } - HKLMx86 { 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' } - HKCUx64 { 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' } - HKCUx86 { 'HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' } - default { throw "Invalid registry path specified $($args[0])" } -} -$regProperty = $args[1] -$regUninstallString = $args[2] -#$regUninstallString = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($args[2])) - -$null = New-Item -Path $regPath -Name $productId -Force - -$propParams = @{ - Path = "$regPath\$productId" - Force = $true - PropertyType = 'String' -} -New-ItemProperty -Name $regProperty -Value $regUninstallString @propParams -if ($regProperty -eq 'QuietUninstallString') { - New-ItemProperty -Name 'UninstallString' -Value 'Fail if used' @propParams -} diff --git a/test/integration/targets/win_path/aliases b/test/integration/targets/win_path/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_path/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_path/tasks/main.yml b/test/integration/targets/win_path/tasks/main.yml deleted file mode 100644 index bf27cec663..0000000000 --- a/test/integration/targets/win_path/tasks/main.yml +++ /dev/null @@ -1,183 +0,0 @@ -- set_fact: - varname: WINPATH_TEST - -- name: Remove {{ varname }} vars from user and machine scope - raw: '[Environment]::SetEnvironmentVariable("{{ varname }}", $null, "User"); [Environment]::SetEnvironmentVariable("{{ varname }}", $null, "Machine")' - -- name: Set a var at the machine and user levels - win_path: - name: "{{ varname }}" - elements: C:\{{ item }}Path - scope: "{{ item }}" - with_items: - - machine - - user - register: pathout - -- name: Get path value from machine and user levels - raw: '[Environment]::GetEnvironmentVariable("{{ varname }}","{{ item.item }}")' - with_items: "{{ pathout.results }}" - register: varout - -- name: Ensure output - assert: - that: - - item.0 is changed - - item.0.path_value == "C:\\" + item.0.item + "Path" - - item.1.stdout_lines[0] == 'C:\\' + item.0.item + 'Path' - with_together: - - "{{ pathout.results }}" - - "{{ varout.results }}" - -- name: Remove {{ varname }} vars from user and machine scope - raw: '[Environment]::SetEnvironmentVariable("{{ varname }}", $null, "User"); [Environment]::SetEnvironmentVariable("{{ varname }}", $null, "Machine")' - -- name: Create multi-element path - win_path: - name: "{{ varname }}" - elements: - - C:\PathZ - - C:\PathA - register: multiout - -- name: Get path value - raw: $env:{{ varname }} - register: varout - -- name: Ensure output - assert: - that: - - multiout is changed - - multiout.path_value == "C:\\PathZ;C:\\PathA" - - varout.stdout_lines[0] == "C:\\PathZ;C:\\PathA" - -- name: Add value to middle and end - win_path: - name: "{{ varname }}" - elements: - - C:\NewPath - - C:\PathA - - 'C:\PathWithTrailingBackslash\' # store with a trailing backslash - - '"C:\Quoted;With;Semicolons"' # embedded semicolon, wrapped in quotes - - '%SystemRoot%\stuff' - register: addout - -- name: Get path value - raw: $env:{{ varname }} - register: varout - -- name: Test idempotence- retry values to middle and end, test case-insensitive comparison, backslash canonicalization - win_path: - name: "{{ varname }}" - elements: - - c:\nEwPaTh - - c:\patha - - C:\pathwithtrailingbackslash # no trailing backslash, should be the same - - '"C:\Quoted;With;Semicolons"' - - '%SystemRoot%\stuff' - register: idemout - -- name: Get path value - raw: $env:{{ varname }} - register: idemvarout - -- name: Ensure output - assert: - that: - - addout is changed - - addout.path_value == 'C:\\PathZ;C:\\NewPath;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";%SystemRoot%\stuff' - - varout.stdout_lines[0] == ('C:\\PathZ;C:\\NewPath;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";C:\Windows\stuff') - - idemout is not changed - - idemout.path_value == 'C:\\PathZ;C:\\NewPath;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";%SystemRoot%\stuff' - - idemvarout.stdout_lines[0] == ('C:\\PathZ;C:\\NewPath;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";C:\Windows\stuff') - -- name: Remove single element - win_path: - name: "{{ varname }}" - elements: C:\NewPath - state: absent - register: removeout - -- name: Get path value - raw: $env:{{ varname }} - register: varout - -- name: Test idempotence- retry remove single element - win_path: - name: "{{ varname }}" - elements: C:\NewPath - state: absent - register: idemremoveout - -- name: Get path value - raw: $env:{{ varname }} - register: idemvarout - -- name: Ensure output - assert: - that: - - removeout is changed - - removeout.path_value == 'C:\\PathZ;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";%SystemRoot%\stuff' - - varout.stdout_lines[0] == 'C:\\PathZ;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";C:\Windows\stuff' - - idemremoveout is not changed - - idemremoveout.path_value == 'C:\\PathZ;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";%SystemRoot%\stuff' - - idemvarout.stdout_lines[0] == 'C:\\PathZ;C:\\PathA;C:\\PathWithTrailingBackslash\\;"C:\Quoted;With;Semicolons";C:\Windows\stuff' - -- name: Remove multiple elements - win_path: - name: "{{ varname }}" - elements: - - C:\PathWithTrailingBackslash # no trailing backslash - - c:\pathz - - '"C:\Quoted;With;Semicolons"' - - '%SystemRoot%\stuff\' # add trailing backslash - state: absent - register: removeout - -- name: Get path value - raw: $env:{{ varname }} - register: varout - -- name: Ensure output - assert: - that: - - removeout is changed - - removeout.path_value == "C:\\PathA" - - varout.stdout_lines[0] == "C:\\PathA" - -- name: Test check mode add - check_mode: yes - win_path: - name: "{{ varname }}" - elements: - - C:\MissingPath - register: checkadd - -- name: Get path value - raw: $env:{{ varname }} - register: checkaddvarout - -- name: Test check mode remove - check_mode: yes - win_path: - name: "{{ varname }}" - elements: C:\PathA - state: absent - register: checkremove - -- name: Get path value - raw: $env:{{ varname }} - register: checkremovevarout - -- name: Ensure output - assert: - that: - - checkadd is changed - - checkadd.path_value == "C:\\PathA;C:\\MissingPath" - - checkaddvarout.stdout_lines[0] == "C:\\PathA" # shouldn't have actually changed the value - - checkremove is changed - - checkremove.path_value == "" - - checkremovevarout.stdout_lines[0] == "C:\\PathA" # shouldn't have actually changed the value - -- name: Remove {{ varname }} vars from user and machine scope - raw: '[Environment]::SetEnvironmentVariable("{{ varname }}", $null, "User"); [Environment]::SetEnvironmentVariable("{{ varname }}", $null, "Machine")' diff --git a/test/integration/targets/win_ping/aliases b/test/integration/targets/win_ping/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_ping/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_ping/library/win_ping_set_attr.ps1 b/test/integration/targets/win_ping/library/win_ping_set_attr.ps1 deleted file mode 100644 index f17049643b..0000000000 --- a/test/integration/targets/win_ping/library/win_ping_set_attr.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -#!powershell -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# POWERSHELL_COMMON - -$params = Parse-Args $args $true; - -$data = Get-Attr $params "data" "pong"; - -$result = @{ - changed = $false - ping = "pong" -}; - -# Test that Set-Attr will replace an existing attribute. -Set-Attr $result "ping" $data - -Exit-Json $result; diff --git a/test/integration/targets/win_ping/library/win_ping_strict_mode_error.ps1 b/test/integration/targets/win_ping/library/win_ping_strict_mode_error.ps1 deleted file mode 100644 index 508174afcc..0000000000 --- a/test/integration/targets/win_ping/library/win_ping_strict_mode_error.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -#!powershell -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# POWERSHELL_COMMON - -$params = Parse-Args $args $true; - -$params.thisPropertyDoesNotExist - -$data = Get-Attr $params "data" "pong"; - -$result = @{ - changed = $false - ping = $data -}; - -Exit-Json $result; diff --git a/test/integration/targets/win_ping/library/win_ping_syntax_error.ps1 b/test/integration/targets/win_ping/library/win_ping_syntax_error.ps1 deleted file mode 100644 index d4c9f07ad5..0000000000 --- a/test/integration/targets/win_ping/library/win_ping_syntax_error.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -#!powershell -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# POWERSHELL_COMMON - -$blah = 'I can't quote my strings correctly.' - -$params = Parse-Args $args $true; - -$data = Get-Attr $params "data" "pong"; - -$result = @{ - changed = $false - ping = $data -}; - -Exit-Json $result; diff --git a/test/integration/targets/win_ping/library/win_ping_throw.ps1 b/test/integration/targets/win_ping/library/win_ping_throw.ps1 deleted file mode 100644 index 7306f4d280..0000000000 --- a/test/integration/targets/win_ping/library/win_ping_throw.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -#!powershell -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# POWERSHELL_COMMON - -throw - -$params = Parse-Args $args $true; - -$data = Get-Attr $params "data" "pong"; - -$result = @{ - changed = $false - ping = $data -}; - -Exit-Json $result; diff --git a/test/integration/targets/win_ping/library/win_ping_throw_string.ps1 b/test/integration/targets/win_ping/library/win_ping_throw_string.ps1 deleted file mode 100644 index 09e3b7cb45..0000000000 --- a/test/integration/targets/win_ping/library/win_ping_throw_string.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -#!powershell -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# POWERSHELL_COMMON - -throw "no ping for you" - -$params = Parse-Args $args $true; - -$data = Get-Attr $params "data" "pong"; - -$result = @{ - changed = $false - ping = $data -}; - -Exit-Json $result; diff --git a/test/integration/targets/win_ping/tasks/main.yml b/test/integration/targets/win_ping/tasks/main.yml deleted file mode 100644 index a7e6ba7fc4..0000000000 --- a/test/integration/targets/win_ping/tasks/main.yml +++ /dev/null @@ -1,67 +0,0 @@ -# test code for the win_ping module -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: test win_ping - action: win_ping - register: win_ping_result - -- name: check win_ping result - assert: - that: - - win_ping_result is not failed - - win_ping_result is not changed - - win_ping_result.ping == 'pong' - -- name: test win_ping with data - win_ping: - data: ☠ - register: win_ping_with_data_result - -- name: check win_ping result with data - assert: - that: - - win_ping_with_data_result is not failed - - win_ping_with_data_result is not changed - - win_ping_with_data_result.ping == '☠' - -- name: test win_ping.ps1 with data as complex args - # win_ping.ps1: # TODO: do we want to actually support this? no other tests that I can see... - win_ping: - data: bleep - register: win_ping_ps1_result - -- name: check win_ping.ps1 result with data - assert: - that: - - win_ping_ps1_result is not failed - - win_ping_ps1_result is not changed - - win_ping_ps1_result.ping == 'bleep' - -- name: test win_ping using data=crash so that it throws an exception - win_ping: - data: crash - register: win_ping_crash_result - ignore_errors: yes - -- name: check win_ping_crash result - assert: - that: - - win_ping_crash_result is failed - - win_ping_crash_result is not changed - - 'win_ping_crash_result.msg == "Unhandled exception while executing module: boom"' - - '"throw \"boom\"" in win_ping_crash_result.exception' diff --git a/test/integration/targets/win_reboot/aliases b/test/integration/targets/win_reboot/aliases deleted file mode 100644 index f687b0e0ef..0000000000 --- a/test/integration/targets/win_reboot/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group4 -shippable/windows/smoketest diff --git a/test/integration/targets/win_reboot/tasks/main.yml b/test/integration/targets/win_reboot/tasks/main.yml deleted file mode 100644 index 7757e08fcd..0000000000 --- a/test/integration/targets/win_reboot/tasks/main.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -- name: make sure win output dir exists - win_file: - path: "{{win_output_dir}}" - state: directory - -- name: reboot with defaults - win_reboot: - -- name: test with negative values for delays - win_reboot: - post_reboot_delay: -0.5 - pre_reboot_delay: -61 - -- name: schedule a reboot for sometime in the future - win_command: shutdown.exe /r /t 599 - -- name: reboot with a shutdown already scheduled - win_reboot: - -# test a reboot that reboots again during the test_command phase -- name: create test file - win_file: - path: '{{win_output_dir}}\win_reboot_test' - state: touch - -- name: reboot with secondary reboot stage - win_reboot: - test_command: '{{ lookup("template", "post_reboot.ps1") }}' - -- name: reboot with test command that fails - win_reboot: - test_command: 'FAIL' - reboot_timeout: 120 - register: reboot_fail_test - failed_when: "reboot_fail_test.msg != 'Timed out waiting for post-reboot test command (timeout=120)'" - -- name: remove SeRemoteShutdownPrivilege - win_user_right: - name: SeRemoteShutdownPrivilege - users: [] - action: set - register: removed_shutdown_privilege - -- block: - - name: try and reboot without required privilege - win_reboot: - register: fail_privilege - failed_when: - - "'Reboot command failed, error was:' not in fail_privilege.msg" - - "'Access is denied.(5)' not in fail_privilege.msg" - - always: - - name: reset the SeRemoteShutdownPrivilege - win_user_right: - name: SeRemoteShutdownPrivilege - users: '{{ removed_shutdown_privilege.removed }}' - action: add - -- name: Use invalid parameter - reboot: - foo: bar - ignore_errors: true - register: invalid_parameter - -- name: Ensure task fails with error - assert: - that: - - invalid_parameter is failed - - "invalid_parameter.msg == 'Invalid options for reboot: foo'" diff --git a/test/integration/targets/win_reboot/templates/post_reboot.ps1 b/test/integration/targets/win_reboot/templates/post_reboot.ps1 deleted file mode 100644 index e4a99a721d..0000000000 --- a/test/integration/targets/win_reboot/templates/post_reboot.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -if (Test-Path -Path '{{win_output_dir}}\win_reboot_test') { - New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' ` - -Name PendingFileRenameOperations ` - -Value @("\??\{{win_output_dir}}\win_reboot_test`0") ` - -PropertyType MultiString - Restart-Computer -Force - exit 1 -} diff --git a/test/integration/targets/win_reg_stat/aliases b/test/integration/targets/win_reg_stat/aliases deleted file mode 100644 index 4cd27b3cb2..0000000000 --- a/test/integration/targets/win_reg_stat/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group1 diff --git a/test/integration/targets/win_reg_stat/defaults/main.yml b/test/integration/targets/win_reg_stat/defaults/main.yml deleted file mode 100644 index a714e4399d..0000000000 --- a/test/integration/targets/win_reg_stat/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -test_reg_path: Test Key / [&Ansible*] diff --git a/test/integration/targets/win_reg_stat/meta/main.yml b/test/integration/targets/win_reg_stat/meta/main.yml deleted file mode 100644 index d328716dfa..0000000000 --- a/test/integration/targets/win_reg_stat/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_reg_stat/tasks/main.yml b/test/integration/targets/win_reg_stat/tasks/main.yml deleted file mode 100644 index bb12c91665..0000000000 --- a/test/integration/targets/win_reg_stat/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: get value of expand string %windir% - win_command: powershell.exe $env:windir - register: win_dir_value - -- name: template out test registry structure - win_template: - src: test_reg.reg.j2 - dest: '{{ win_output_dir }}\test_reg.reg' - -- name: import test registry structure - win_command: reg.exe import "{{ win_output_dir }}\test_reg.reg" - -- block: - - name: run tests - import_tasks: tests.yml - - always: - - name: remove test registry key - win_regedit: - path: HKCU:\{{ test_reg_path }} - state: absent - delete_key: True - - - name: remove template registry file - win_file: - path: '{{ win_output_dir }}\test_reg.reg' - state: absent diff --git a/test/integration/targets/win_reg_stat/tasks/tests.yml b/test/integration/targets/win_reg_stat/tasks/tests.yml deleted file mode 100644 index 5424ba4d45..0000000000 --- a/test/integration/targets/win_reg_stat/tasks/tests.yml +++ /dev/null @@ -1,377 +0,0 @@ ---- -- name: expect failure when not passing in path option - win_reg_stat: - name: a - register: actual - failed_when: "actual.msg != 'Get-AnsibleParam: Missing required argument: path'" - -- name: expect failure when passing in an invalid hive - win_reg_stat: - path: ABCD:\test - register: actual - failed_when: 'actual.msg != "path: ABCD:\\test is not a valid registry path, see module documentation for examples."' - -- name: get known nested reg key structure - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - register: actual - -- name: set expected value for reg structure - set_fact: - expected: - changed: false - exists: true - failed: false - properties: - binary: { raw_value: ["0x01", "0x16"], type: 'REG_BINARY', value: [1, 22] } - dword: { raw_value: 1, type: 'REG_DWORD', value: 1 } - expand: { raw_value: '%windir%\dir', type: 'REG_EXPAND_SZ', value: "{{win_dir_value.stdout_lines[0]}}\\dir" } - large_dword: { raw_value: 4294967295, type: 'REG_DWORD', value: 4294967295 } - large_qword: { raw_value: 18446744073709551615, type: 'REG_QWORD', value: 18446744073709551615 } - multi: { raw_value: ['a, b', 'c'], type: 'REG_MULTI_SZ', value: ['a, b', 'c'] } - qword: { raw_value: 1, type: 'REG_QWORD', value: 1 } - string: { raw_value: 'test', type: 'REG_SZ', value: 'test' } - sub_keys: - - nest1 - - nest2 - -- name: assert get known nested reg key structure - assert: - that: - - actual == expected - -- name: get known reg key with no sub keys but some properties - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\single - register: actual - -- name: set expected value for reg key with no sub keys but some properties - set_fact: - expected: - changed: false - exists: true - failed: false - properties: - none: { raw_value: [], type: 'REG_NONE', value: [] } - none1: { raw_value: ["0x00"], type: 'REG_NONE', value: [0] } - string1: { raw_value: '', type: 'REG_SZ', value: '' } - string2: { raw_value: 'abc123', type: 'REG_SZ', value: 'abc123' } - sub_keys: [] - -- name: assert get known reg key with no sub keys but some properties - assert: - that: - - actual == expected - -- name: get known reg key without sub keys and properties - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested\nest2 - register: actual - -- name: set expected value for reg key without sub keys or properties - set_fact: - expected: - changed: false - exists: true - failed: false - properties: {} - sub_keys: [] - register: expected - -- name: assert get known reg key without sub keys and properties - assert: - that: - - actual == expected - -- name: get non-existent reg key - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Thispathwillneverexist - register: actual - -- name: set expected value for non-existent reg key - set_fact: - expected: - changed: false - exists: false - failed: false - -- name: assert get non-existent reg key - assert: - that: - - actual == expected - -- name: get string property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: string - register: actual - -- name: set expected string property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: 'test' - type: 'REG_SZ' - value: 'test' - -- name: assert get string property - assert: - that: - - actual == expected - -- name: get expand string property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: expand - register: actual - -- name: set expected expand string property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: '%windir%\dir' - type: 'REG_EXPAND_SZ' - value: "{{win_dir_value.stdout_lines[0]}}\\dir" - -- name: assert get expand string property - assert: - that: - - actual == expected - -- name: get multi string property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: multi - register: actual - -- name: set expected multi string property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: ['a, b', 'c'] - type: 'REG_MULTI_SZ' - value: ['a, b', 'c'] - -- name: assert get multi string property - assert: - that: - - actual == expected - -- name: get binary property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: binary - register: actual - -- name: set expected binary property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: ["0x01", "0x16"] - type: 'REG_BINARY' - value: [1, 22] - -- name: assert get binary property - assert: - that: - - actual == expected - -- name: get dword property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: dword - register: actual - -- name: set expected dword property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: 1 - type: 'REG_DWORD' - value: 1 - -- name: assert get dword property - assert: - that: - - actual == expected - -- name: get qword property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\nested - name: qword - register: actual - -- name: set expected qword property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: 1 - type: 'REG_QWORD' - value: 1 - -- name: assert get qword property - assert: - that: - - actual == expected - -- name: get none property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\single - name: none - register: actual - -- name: set expected none property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: [] - type: 'REG_NONE' - value: [] - -- name: assert get none property - assert: - that: - - actual == expected - -- name: get none with value property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\single - name: none1 - register: actual - -- name: set expected none with value property - set_fact: - expected: - changed: false - exists: true - failed: false - raw_value: ["0x00"] - type: 'REG_NONE' - value: [0] - -- name: assert get non with value property - assert: - that: - - actual == expected - -- name: get non-existent property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\single - name: doesnotexist - register: actual - -- name: set expected non-existent property - set_fact: - expected: - changed: false - exists: false - failed: false - -- name: assert get non-existent property - assert: - that: - - actual == expected - -- name: get key with default property set - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Duplicate Default - register: actual - -- name: assert get key with default property set - assert: - that: - - actual.properties[""]['raw_value'] == "default" - - actual.properties[""]['type'] == "REG_SZ" - - actual.properties[""]['value'] == "default" - - actual.properties['(Default)'].raw_value == "custom" - - actual.properties['(Default)'].type == "REG_SZ" - - actual.properties['(Default)'].value == "custom" - -- name: get default property - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Duplicate Default - name: '' - register: actual - -- name: assert get default property - assert: - that: - - actual.value == "default" - - actual.raw_value == "default" - - actual.type == "REG_SZ" - -- name: get key with blank property set - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Blank Default - register: actual - -- name: assert get key with blank property set - assert: - that: - - actual.properties[""].raw_value == "" - - actual.properties[""].type == "REG_SZ" - - actual.properties[""].value == "" - - actual.properties['(Default)'].raw_value == "" - - actual.properties['(Default)'].type == "REG_SZ" - - actual.properties['(Default)'].value == "" - -- name: get default property as empty string - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Blank Default - name: '' - register: actual - -- name: assert get default property as empty string - assert: - that: - - actual.value == "" - - actual.raw_value == "" - - actual.type == "REG_SZ" - -- name: get key with no properties set - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Empty Default - register: actual - -- name: assert get key with no properties set - assert: - that: - - actual.properties == {} - -- name: get default property that has not been set - win_reg_stat: - path: HKCU:\{{ test_reg_path }}\Empty Default - name: '' - register: actual - -- name: assert get default property that has not been set - assert: - that: - - not actual.exists - -# Tests https://github.com/ansible/ansible/issues/59337 -- name: test out all registry hives - win_reg_stat: - path: '{{ item }}' - register: reg_hive_stat - failed_when: not reg_hive_stat.exists - with_items: - - HKCR:\* - - HKCC:\Software - - HKCU:\Software - - HKLM:\Software - - HKU:\.DEFAULT diff --git a/test/integration/targets/win_reg_stat/templates/test_reg.reg.j2 b/test/integration/targets/win_reg_stat/templates/test_reg.reg.j2 deleted file mode 100644 index ac3d44ed73..0000000000 --- a/test/integration/targets/win_reg_stat/templates/test_reg.reg.j2 +++ /dev/null @@ -1,37 +0,0 @@ -Windows Registry Editor Version 5.00 - -[HKEY_CURRENT_USER\{{ test_reg_path }}] - -[HKEY_CURRENT_USER\{{ test_reg_path }}\nested] -"string"="test" -"binary"=hex:01,16 -"dword"=dword:00000001 -"qword"=hex(b):01,00,00,00,00,00,00,00 -"large_dword"=dword:ffffffff -"large_qword"=hex(b):ff,ff,ff,ff,ff,ff,ff,ff -"multi"=hex(7):61,00,2c,00,20,00,62,00,00,00,63,00,00,00,00,00 -"expand"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,64,00,69,\ - 00,72,00,00,00 - -[HKEY_CURRENT_USER\{{ test_reg_path }}\nested\nest1] -"dontcare"="" - -[HKEY_CURRENT_USER\{{ test_reg_path }}\nested\nest2] - - -[HKEY_CURRENT_USER\{{ test_reg_path }}\single] -"string1"="" -"string2"="abc123" -"none"=hex(0): -"none1"=hex(0):00 - -[HKEY_CURRENT_USER\{{ test_reg_path }}\Empty Default] - - -[HKEY_CURRENT_USER\{{ test_reg_path }}\Blank Default] -@="" -"(Default)"="" - -[HKEY_CURRENT_USER\{{ test_reg_path }}\Duplicate Default] -@="default" -"(Default)"="custom" diff --git a/test/integration/targets/win_regedit/aliases b/test/integration/targets/win_regedit/aliases deleted file mode 100644 index 4f4664b685..0000000000 --- a/test/integration/targets/win_regedit/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group5 diff --git a/test/integration/targets/win_regedit/defaults/main.yml b/test/integration/targets/win_regedit/defaults/main.yml deleted file mode 100644 index ec88487556..0000000000 --- a/test/integration/targets/win_regedit/defaults/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -test_win_regedit_local_key: 'HKLM:\Software\Moo []{}!@#$%^&*()-_=+/key''"?<>' -test_win_regedit_classes_key: HKCR:\.test-ansible -test_win_regedit_hive_key: HKLM:\ANSIBLE\NewKey diff --git a/test/integration/targets/win_regedit/tasks/cleanup.yml b/test/integration/targets/win_regedit/tasks/cleanup.yml deleted file mode 100644 index f10452506e..0000000000 --- a/test/integration/targets/win_regedit/tasks/cleanup.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: load HKLM:\ANSIBLE with test hive - win_command: reg.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat - failed_when: false - -- name: make sure testing keys are removed before test - win_regedit: - path: '{{item}}' - delete_key: yes - state: absent - with_items: - - '{{test_win_regedit_local_key}}' - - '{{test_win_regedit_classes_key}}' - - '{{test_win_regedit_hive_key}}' - -- name: ensure HKLM:\ANSIBLE is unloaded - win_command: reg.exe unload HKLM\ANSIBLE - failed_when: false diff --git a/test/integration/targets/win_regedit/tasks/create_tests.yml b/test/integration/targets/win_regedit/tasks/create_tests.yml deleted file mode 100644 index e8cc536774..0000000000 --- a/test/integration/targets/win_regedit/tasks/create_tests.yml +++ /dev/null @@ -1,228 +0,0 @@ -# repeatable tests for each key type -# takes in the following variables -# test_win_regedit_key_type: the type of key -# test_win_regedit_key_expected_type: the expected key type -# test_win_regedit_key_data1: the data to create first -# test_win_regedit_key_data2: the data to change tp -# test_win_regedit_key_expected_value_null: the expected value for a null key -# test_win_regedit_key_expected_value1: the expected value for the data1 -# test_win_regedit_key_expected_value2: the expected value for the data2 ---- -- name: create a null {{test_win_regedit_key_type}} check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: empty_{{test_win_regedit_key_type}} - type: '{{test_win_regedit_key_type}}' - state: present - register: null_check - check_mode: yes - -- name: get actual on null {{test_win_regedit_key_type}} check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: empty_{{test_win_regedit_key_type}} - register: null_actual_check - -- name: assert create a null {{test_win_regedit_key_type}} check - assert: - that: - - null_check is changed - - null_check.data_changed == False - - null_check.data_type_changed == False - - null_actual_check.exists == False - -- name: create a null {{test_win_regedit_key_type}} - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: empty_{{test_win_regedit_key_type}} - type: '{{test_win_regedit_key_type}}' - state: present - register: null_create - -- name: get actual on null {{test_win_regedit_key_type}} - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: empty_{{test_win_regedit_key_type}} - register: null_create_actual - -- name: assert create a null {{test_win_regedit_key_type}} - assert: - that: - - null_create is changed - - null_create.data_changed == False - - null_create.data_type_changed == False - - null_create_actual.exists == True - - null_create_actual.raw_value == test_win_regedit_key_expected_value_null - - null_create_actual.type == test_win_regedit_key_expected_type - when: test_win_regedit_key_type not in ['dword', 'qword'] - -# dword and qword are different, need to convert the expected value null to an int -- name: assert create a null {{test_win_regedit_key_type}} for dword and qword - assert: - that: - - null_create is changed - - null_create.data_changed == False - - null_create.data_type_changed == False - - null_create_actual.exists == True - - null_create_actual.raw_value == test_win_regedit_key_expected_value_null|int - - null_create_actual.type == test_win_regedit_key_expected_type - when: test_win_regedit_key_type in ['dword', 'qword'] - -- name: create a null {{test_win_regedit_key_type}} again - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: empty_{{test_win_regedit_key_type}} - type: '{{test_win_regedit_key_type}}' - state: present - register: null_create_again - -- name: assert create a null {{test_win_regedit_key_type}} again - assert: - that: - - null_create_again is not changed - -- name: create a {{test_win_regedit_key_type}} check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data1}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: data_create_check - check_mode: yes - -- name: get actual on {{test_win_regedit_key_type}} check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - register: data_create_actual_check - -- name: assert create a {{test_win_regedit_key_type}} check - assert: - that: - - data_create_check is changed - - data_create_check.data_changed == False - - data_create_check.data_type_changed == False - - data_create_actual_check.exists == False - -- name: create a {{test_win_regedit_key_type}} - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data1}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: data_create - -- name: get actual on {{test_win_regedit_key_type}} - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - register: data_create_actual - -- name: assert create a {{test_win_regedit_key_type}} - assert: - that: - - data_create is changed - - data_create.data_changed == False - - data_create.data_type_changed == False - - data_create_actual.exists == True - - data_create_actual.raw_value == test_win_regedit_key_expected_value1 - - data_create_actual.type == test_win_regedit_key_expected_type - when: test_win_regedit_key_type not in ['dword', 'qword'] - -- name: assert create a {{test_win_regedit_key_type}} for dword or qword - assert: - that: - - data_create is changed - - data_create.data_changed == False - - data_create.data_type_changed == False - - data_create_actual.exists == True - - data_create_actual.raw_value == test_win_regedit_key_expected_value1|int - - data_create_actual.type == test_win_regedit_key_expected_type - when: test_win_regedit_key_type in ['dword', 'qword'] - -- name: create a {{test_win_regedit_key_type}} again - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data1}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: data_create_again - -- name: assert create a {{test_win_regedit_key_type}} again - assert: - that: - - data_create_again is not changed - -- name: change existing {{test_win_regedit_key_type}} data check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data2}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: change_data_check - check_mode: yes - -- name: get actual of change existing {{test_win_regedit_key_type}} data check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - register: change_data_actual_check - -- name: assert change existing {{test_win_regedit_key_type}} data check - assert: - that: - - change_data_check is changed - - change_data_check.data_changed == True - - change_data_check.data_type_changed == False - - change_data_actual_check == data_create_actual - -- name: change existing {{test_win_regedit_key_type}} data - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data2}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: change_data - -- name: get actual of change existing {{test_win_regedit_key_type}} data - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - register: change_data_actual - -- name: assert change existing {{test_win_regedit_key_type}} data - assert: - that: - - change_data is changed - - change_data.data_changed == True - - change_data.data_type_changed == False - - change_data_actual.raw_value == test_win_regedit_key_expected_value2 - when: test_win_regedit_key_type not in ['dword', 'qword'] - -- name: assert change existing {{test_win_regedit_key_type}} data for dword or qword - assert: - that: - - change_data is changed - - change_data.data_changed == True - - change_data.data_type_changed == False - - change_data_actual.raw_value == test_win_regedit_key_expected_value2|int - when: test_win_regedit_key_type in ['dword', 'qword'] - -- name: change existing {{test_win_regedit_key_type}} data again - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_{{test_win_regedit_key_type}} - data: '{{test_win_regedit_key_data2}}' - type: '{{test_win_regedit_key_type}}' - state: present - register: change_data_again - -- name: assert change existing {{test_win_regedit_key_type}} data again - assert: - that: - - change_data_again is not changed diff --git a/test/integration/targets/win_regedit/tasks/main.yml b/test/integration/targets/win_regedit/tasks/main.yml deleted file mode 100644 index 9b55ed332a..0000000000 --- a/test/integration/targets/win_regedit/tasks/main.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -- name: make sure we start on a blank state - include_tasks: cleanup.yml - -- block: - - name: run tests for each property type - include_tasks: create_tests.yml - vars: - test_win_regedit_key_type: '{{item.type}}' - test_win_regedit_key_expected_type: '{{item.reg_type}}' - test_win_regedit_key_data1: '{{item.data1}}' - test_win_regedit_key_data2: '{{item.data2}}' - test_win_regedit_key_expected_value_null: '{{item.value_null}}' - test_win_regedit_key_expected_value1: '{{item.value1}}' - test_win_regedit_key_expected_value2: '{{item.value2}}' - loop: - - type: dword - reg_type: REG_DWORD - data1: 1337 # decimal format - data2: 0xffffffff # hex format and larger number - value_null: 0 - value1: 1337 - value2: 4294967295 - - - type: qword - reg_type: REG_QWORD - data1: 18446744073709551615 # larger decimal format - data2: 0x1ffffffff # hex format and larger number - value_null: 0 - value1: 18446744073709551615 - value2: 8589934591 - - - type: string - reg_type: REG_SZ - data1: hello world - data2: new hello world - value_null: "" - value1: hello world - value2: new hello world - - - type: expandstring - reg_type: REG_EXPAND_SZ - data1: '%windir%\test' - data2: '%AppData%\local' - value_null: "" - value1: '%windir%\test' - value2: '%AppData%\local' - - - type: multistring - reg_type: REG_MULTI_SZ - data1: 'entry1' # test single entry as multi string - data2: ['entry1', 2] - value_null: [] - value1: ['entry1'] - value2: ['entry1', '2'] - - - type: binary - reg_type: REG_BINARY - data1: hex:00,01,ee,ff # testing hex string format with hex: in front - data2: [0xff, 0xee, 0x01, 0x00] # testing using just raw hex values - value_null: [] - value1: ["0x00", "0x01", "0xee", "0xff"] - value2: ["0xff", "0xee", "0x01", "0x00"] - - - type: none - reg_type: REG_NONE - data1: aa,bb,be,ef # testing hex string format with hex: in front - data2: [0x01, 0x02] - value_null: [] - value1: ["0xaa", "0xbb", "0xbe", "0xef"] - value2: ["0x01", "0x02"] - - - name: run remaining tests - include_tasks: tests.yml - - always: - - name: make sure testing keys are removed after test - include_tasks: cleanup.yml diff --git a/test/integration/targets/win_regedit/tasks/tests.yml b/test/integration/targets/win_regedit/tasks/tests.yml deleted file mode 100644 index d633e5333b..0000000000 --- a/test/integration/targets/win_regedit/tasks/tests.yml +++ /dev/null @@ -1,737 +0,0 @@ ---- -- name: check warning is fired if path with / as separators is used - win_regedit: - path: HKLM:\SOFTWARE/Microsoft - state: present - register: forward_separator_warn - -- name: assert warning is fired if / is used as a separator - assert: - that: - - forward_separator_warn.deprecations|length == 1 - - forward_separator_warn.deprecations[0].msg == "path is not using '\\' as a separator, support for '/' as a separator will be removed in a future Ansible version" - - forward_separator_warn.deprecations[0].version == 2.12 - -- name: fail run win_regedit with larger dword - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: test - data: 0xffffffff1 - type: dword - state: present - register: large_dword - failed_when: large_dword.msg != 'data cannot be larger than 0xffffffff when type is dword' - -- name: fail run win_regedit with larger qword - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: test - data: 0xffffffffffffffff1 - type: qword - state: present - register: large_qword - failed_when: large_qword.msg != 'data cannot be larger than 0xffffffffffffffff when type is qword' - -- name: run win_regedit with invalid path - win_regedit: - path: ABCD:\efg - register: invalid_path - failed_when: "invalid_path.msg != 'path: ABCD:\\efg is not a valid powershell path, see module documentation for examples.'" - -- name: change string to binary check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_string - data: hex:00,01 - type: binary - state: present - register: change_string_binary_check - check_mode: yes - -- name: get actual change string to binary check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_string - register: change_string_binary_actual_check - -- name: assert change string to binary check - assert: - that: - - change_string_binary_check is changed - - change_string_binary_check.data_changed == True - - change_string_binary_check.data_type_changed == True - - change_string_binary_actual_check.type == 'REG_SZ' - - change_string_binary_actual_check.raw_value == "new hello world" - -- name: change string to binary - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_string - data: hex:00,01 - type: binary - state: present - register: change_string_binary - -- name: get actual change string to binary - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_string - register: change_string_binary_actual - -- name: assert change string to binary check - assert: - that: - - change_string_binary is changed - - change_string_binary.data_changed == True - - change_string_binary.data_type_changed == True - - change_string_binary_actual.type == 'REG_BINARY' - - change_string_binary_actual.raw_value == ["0x00", "0x01"] - -- name: modify the (Default) key property check - win_regedit: - path: '{{test_win_regedit_local_key}}' - data: default value - state: present - register: modify_default_check - check_mode: yes - -- name: get actual modify the (Default) key property check - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - name: '' - register: modify_default_actual_check - -- name: assert modify the (Default) key property check - assert: - that: - - modify_default_check is changed - - not modify_default_actual_check.exists - -- name: modify the (Default) key property - win_regedit: - path: '{{test_win_regedit_local_key}}' - data: default value - state: present - register: modify_default - -- name: get actual modify the (Default) key property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - name: '' - register: modify_default_actual - -- name: assert modify the (Default) key property - assert: - that: - - modify_default is changed - - modify_default_actual.value == "default value" - -- name: create an actual property called (Default) - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: (Default) - data: custom default value - type: expandstring - state: present - register: create_specific_default_check - check_mode: yes - -- name: get actual value for (Default) property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: create_specific_default_actual_check - -- name: assert create specific property called (Default) check - assert: - that: - - create_specific_default_check is changed - - create_specific_default_actual_check.properties[""].value == "default value" - - not "(Default)" in create_specific_default_actual_check.properties - -- name: create an actual property called (Default) - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: (Default) - data: custom default value - type: expandstring - state: present - register: create_specific_default - -- name: get actual value for (Default) property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: create_specific_default_actual - -- name: assert create specific property called (Default) - assert: - that: - - create_specific_default is changed - - create_specific_default_actual.properties[""].value == "default value" - - create_specific_default_actual.properties["(Default)"].value == "custom default value" - -- name: delete property check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_binary - state: absent - register: delete_property_check - check_mode: yes - -- name: get actual of delete property check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_binary - register: delete_property_actual_check - -- name: assert delete property check - assert: - that: - - delete_property_check is changed - - delete_property_actual_check.exists == True - -- name: delete property - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_binary - state: absent - register: delete_property - -- name: get actual of delete property - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - name: data_binary - register: delete_property_actual - -- name: assert delete property - assert: - that: - - delete_property is changed - - delete_property_actual.exists == False - -- name: delete property again - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: data_binary - state: absent - register: delete_property_again - -- name: assert delete property again - assert: - that: - - delete_property_again is not changed - -- name: delete the key's (Default) property check - win_regedit: - path: '{{test_win_regedit_local_key}}' - state: absent - delete_key: no - register: delete_default_check - check_mode: yes - -- name: get actual of key's (Default) property check - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: delete_default_actual_check - -- name: assert delete the key's (Default) property check - assert: - that: - - delete_default_check is changed - - delete_default_actual_check.properties[""].value == "default value" - - delete_default_actual_check.properties["(Default)"].value == "custom default value" - -- name: delete the key's (Default) property - win_regedit: - path: '{{test_win_regedit_local_key}}' - state: absent - delete_key: no - register: delete_default - -- name: get actual of key's (Default) property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: delete_default_actual - -- name: assert delete the key's (Default) property - assert: - that: - - delete_default is changed - - not "" in delete_default_actual.properties - - delete_default_actual.properties["(Default)"].value == "custom default value" - -- name: recreate the key's (Default) property for next test - win_regedit: - path: '{{test_win_regedit_local_key}}' - data: default value - -- name: delete the custom (Default) property check - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: (Default) - state: absent - delete_key: no - register: delete_custom_default_check - check_mode: yes - -- name: get actual of key's (Default) property check - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: delete_custom_default_actual_check - -- name: assert delete the custom (Default) property check - assert: - that: - - delete_custom_default_check is changed - - delete_custom_default_actual_check.properties[""].value == "default value" - - delete_custom_default_actual_check.properties["(Default)"].value == "custom default value" - -- name: delete the custom (Default) property - win_regedit: - path: '{{test_win_regedit_local_key}}' - name: (Default) - state: absent - delete_key: no - register: delete_custom_default - -- name: get actual of key's (Default) property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}' - register: delete_custom_default_actual - -- name: assert delete the custom (Default) property - assert: - that: - - delete_custom_default is changed - - delete_custom_default_actual.properties[""].value == "default value" - - not "(Default)" in delete_custom_default_actual.properties - -- name: add some nested keys for later deletion - win_regedit: - path: '{{test_win_regedit_local_key}}\{{item}}' - state: present - loop: - - nest1 - - nest2 - - nest1\nested - -- name: delete key and it's sub keys check - win_regedit: - path: '{{test_win_regedit_local_key}}' - state: absent - delete_key: yes - register: delete_key_check - check_mode: yes - -- name: get actual of delete key and it's sub keys check - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - register: delete_key_actual_check - -- name: assert delete key and it's sub keys check - assert: - that: - - delete_key_check is changed - - delete_key_actual_check.exists - - delete_key_actual_check.sub_keys == ["nest1", "nest2"] - -- name: delete key and it's sub keys - win_regedit: - path: '{{test_win_regedit_local_key}}' - state: absent - delete_key: yes - register: delete_key - -- name: get actual of delete key and it's sub keys - win_reg_stat: - path: '{{test_win_regedit_local_key}}' - register: delete_key_actual - -- name: assert delete key and it's sub keys - assert: - that: - - delete_key is changed - - delete_key_actual.exists == False - -- name: delete key and it's sub keys again - win_regedit: - path: '{{test_win_regedit_local_key}}' - state: absent - delete_key: yes - register: delete_key_again - -- name: assert delete key and it's sub keys again - assert: - that: - - delete_key_again is not changed - -- name: create a new key without specifying the property - win_regedit: - path: '{{ test_win_regedit_local_key }}\new' - state: present - register: create_key_no_prop - -- name: get result of create a new key without specifying the property - win_reg_stat: - path: '{{ test_win_regedit_local_key }}\new' - register: create_key_no_prop_actual - -- name: assert create a new key without specifying the property - assert: - that: - - create_key_no_prop is changed - - not create_key_no_prop.data_changed - - not create_key_no_prop.data_type_changed - - create_key_no_prop_actual.exists - - create_key_no_prop_actual.properties == {} - -- name: create key in HKEY_CLASSES_ROOT check - win_regedit: - path: '{{test_win_regedit_classes_key}}' - name: test - data: test - type: string - state: present - register: create_hkcr_key_check - check_mode: yes - -- name: get actual of create key in HKEY_CLASSES_ROOT check - win_reg_stat: - path: '{{test_win_regedit_classes_key}}' - register: create_hkcr_key_actual_check - -- name: assert create key in HKEY_CLASSES_ROOT check - assert: - that: - - create_hkcr_key_check is changed - - create_hkcr_key_actual_check.exists == False - -- name: create key in HKEY_CLASSES_ROOT - win_regedit: - path: '{{test_win_regedit_classes_key}}' - name: test - data: test - type: string - state: present - register: create_hkcr_key - -- name: get actual of create key in HKEY_CLASSES_ROOT - win_reg_stat: - path: '{{test_win_regedit_classes_key}}' - register: create_hkcr_key_actual - -- name: assert create key in HKEY_CLASSES_ROOT - assert: - that: - - create_hkcr_key is changed - - create_hkcr_key_actual.exists == True - - create_hkcr_key_actual.properties.test is defined - -- name: create key in HKEY_CLASSES_ROOT again - win_regedit: - path: '{{test_win_regedit_classes_key}}' - name: test - data: test - type: string - state: present - register: create_hkcr_key_again - -- name: assert create key in HKEY_CLASSES_ROOT again - assert: - that: - - create_hkcr_key_again is not changed - -# https://github.com/ansible/ansible/issues/31782 -- name: create property like a json string - win_regedit: - path: '{{test_win_regedit_local_key}}\NewKey' - name: '{7f51bda7-bcea-465a-9eb6-5a2bcd9cb52f}' - data: test data - type: string - state: present - register: create_prop_with_json - -- name: get result of create property like a json string - win_reg_stat: - path: '{{test_win_regedit_local_key}}\NewKey' - name: '{7f51bda7-bcea-465a-9eb6-5a2bcd9cb52f}' - register: create_prop_with_json_result - -- name: assert results of create property like a json string - assert: - that: - - create_prop_with_json is changed - - create_prop_with_json_result.exists == True - - create_prop_with_json_result.value == 'test data' - -- name: create property like a json string (idempotent) - win_regedit: - path: '{{test_win_regedit_local_key}}\NewKey' - name: '{7f51bda7-bcea-465a-9eb6-5a2bcd9cb52f}' - data: test data - type: string - state: present - register: create_prop_with_json_again - -- name: assert results of create property like a json string (idempotent) - assert: - that: - - create_prop_with_json_again is not changed - -- name: create new key in loaded hive (check mode) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_key_in_hive_check - check_mode: yes - -- name: get result of create new key in loaded hive (check mode) - win_shell: | - $ErrorActionPreference = "Stop" - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - Test-Path -Path HKLM:\ANSIBLE\NewKey - [GC]::Collect() - [GC]::WaitForPendingFinalizers() - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: new_key_in_hive_result_check - -- name: assert result of create new key in loaded hive (check mode) - assert: - that: - - new_key_in_hive_check is changed - - new_key_in_hive_result_check.stdout == "False\r\n" - -- name: create new key in loaded hive - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_key_in_hive - -- name: get result of create new key in loaded hive - win_shell: | - $ErrorActionPreference = "Stop" - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - Test-Path -Path HKLM:\ANSIBLE\NewKey - [GC]::Collect() - [GC]::WaitForPendingFinalizers() - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: new_key_in_hive_result - -- name: assert result of create new key in loaded hive - assert: - that: - - new_key_in_hive is changed - - new_key_in_hive_result.stdout == "True\r\n" - -- name: create new key in loaded hive (idempotent) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_key_in_hive_again - -- name: assert result of create new key in loaded hive (idempotent) - assert: - that: - - new_key_in_hive_again is not changed - -- name: set hive key property (check mode) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - data: string - type: string - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_prop_in_hive_check - check_mode: yes - -- name: get result of set hive key property (check mode) - win_shell: | - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - $prop = Get-ItemProperty -Path HKLM:\ANSIBLE\NewKey -Name TestProp -ErrorAction SilentlyContinue - if ($prop) { - $prop.TestProp - } - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: new_prop_in_hive_result_check - -- name: assert result of set hive key property (check mode) - assert: - that: - - new_prop_in_hive_check is changed - - new_prop_in_hive_result_check.stdout == "" - -- name: set hive key property - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - data: string - type: string - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_prop_in_hive - -- name: get result of set hive key property - win_shell: | - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - $prop = Get-ItemProperty -Path HKLM:\ANSIBLE\NewKey -Name TestProp -ErrorAction SilentlyContinue - if ($prop) { - $prop.TestProp - } - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: new_prop_in_hive_result - -- name: assert result of set hive key property - assert: - that: - - new_prop_in_hive is changed - - new_prop_in_hive_result.stdout == "string\r\n" - -- name: set hive key property (idempotent) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - data: string - type: string - state: present - hive: C:\Users\Default\NTUSER.dat - register: new_prop_in_hive_again - -- name: assert result of set hive key property (idempotent) - assert: - that: - - new_prop_in_hive_again is not changed - -- name: remove hive key property (check mode) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - state: absent - hive: C:\Users\Default\NTUSER.dat - register: remove_prop_in_hive_check - check_mode: yes - -- name: get result of remove hive key property (check mode) - win_shell: | - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - $prop = Get-ItemProperty -Path HKLM:\ANSIBLE\NewKey -Name TestProp -ErrorAction SilentlyContinue - if ($prop) { - $prop.TestProp - } - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: remove_prop_in_hive_result_check - -- name: assert result of remove hive key property (check mode) - assert: - that: - - remove_prop_in_hive_check is changed - - remove_prop_in_hive_result_check.stdout == "string\r\n" - -- name: remove hive key property - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - state: absent - hive: C:\Users\Default\NTUSER.dat - register: remove_prop_in_hive - -- name: get result of remove hive key property - win_shell: | - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - $prop = Get-ItemProperty -Path HKLM:\ANSIBLE\NewKey -Name TestProp -ErrorAction SilentlyContinue - if ($prop) { - $prop.TestProp - } - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: remove_prop_in_hive_result - -- name: assert result of remove hive key property - assert: - that: - - remove_prop_in_hive is changed - - remove_prop_in_hive_result.stdout == "" - -- name: remove hive key property (idempotent) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - name: TestProp - state: absent - hive: C:\Users\Default\NTUSER.dat - register: remove_prop_in_hive_again - -- name: assert result of set hive key property (idempotent) - assert: - that: - - remove_prop_in_hive_again is not changed - -- name: remove key in loaded hive (check mode) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: absent - delete_key: yes - hive: C:\Users\Default\NTUSER.dat - register: remove_key_in_hive_check - check_mode: yes - -- name: get result of remove key in loaded hive (check mode) - win_shell: | - $ErrorActionPreference = "Stop" - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - Test-Path -Path HKLM:\ANSIBLE\NewKey - [GC]::Collect() - [GC]::WaitForPendingFinalizers() - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: remove_key_in_hive_result_check - -- name: assert result of removekey in loaded hive (check mode) - assert: - that: - - remove_key_in_hive_check is changed - - remove_key_in_hive_result_check.stdout == "True\r\n" - -- name: remove key in loaded hive - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: absent - delete_key: yes - hive: C:\Users\Default\NTUSER.dat - register: remove_key_in_hive - -- name: get result of remove key in loaded hive - win_shell: | - $ErrorActionPreference = "Stop" - ®.exe load HKLM\ANSIBLE C:\Users\Default\NTUSER.dat > $null - Test-Path -Path HKLM:\ANSIBLE\NewKey - [GC]::Collect() - [GC]::WaitForPendingFinalizers() - ®.exe unload HKLM\ANSIBLE > $null - exit 0 - register: remove_key_in_hive_result - -- name: assert result of remove key in loaded hive - assert: - that: - - remove_key_in_hive is changed - - remove_key_in_hive_result.stdout == "False\r\n" - -- name: remove key in loaded hive (idempotent) - win_regedit: - path: '{{test_win_regedit_hive_key}}' - state: absent - delete_key: yes - hive: C:\Users\Default\NTUSER.dat - register: remove_key_in_hive_again - -- name: assert result of remove key in loaded hive (idempotent) - assert: - that: - - remove_key_in_hive_again is not changed diff --git a/test/integration/targets/win_service/aliases b/test/integration/targets/win_service/aliases deleted file mode 100644 index 71fee86193..0000000000 --- a/test/integration/targets/win_service/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group7 -shippable/windows/smoketest diff --git a/test/integration/targets/win_service/defaults/main.yml b/test/integration/targets/win_service/defaults/main.yml deleted file mode 100644 index 51567c7e06..0000000000 --- a/test/integration/targets/win_service/defaults/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -test_win_service_binary_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_service/SleepService.exe -test_win_service_dir: C:\ansible testing\[win_service] -test_win_service_path: '{{ test_win_service_dir }}\SleepService.exe' -test_win_service_name: TestService [*abc] -test_win_service_display_name: Test Service -test_win_service_description: Test Service description diff --git a/test/integration/targets/win_service/files/Program.cs b/test/integration/targets/win_service/files/Program.cs deleted file mode 100644 index d566cb8376..0000000000 --- a/test/integration/targets/win_service/files/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ServiceProcess; - -namespace SleepService -{ - internal static class Program - { - private static void Main(string[] args) - { - ServiceBase.Run(new ServiceBase[1] - { - (ServiceBase) new SleepService(args) - }); - } - } -} - diff --git a/test/integration/targets/win_service/files/SleepService.cs b/test/integration/targets/win_service/files/SleepService.cs deleted file mode 100644 index c82d7e3314..0000000000 --- a/test/integration/targets/win_service/files/SleepService.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.ComponentModel; -using System.Diagnostics; -using System.Management; -using System.ServiceProcess; - -namespace SleepService -{ - public class SleepService : ServiceBase - { - private IContainer components = null; - private string[] serviceArgs; - private string displayName; - - public SleepService(string[] args) - { - CanPauseAndContinue = true; - CanShutdown = true; - CanStop = true; - AutoLog = false; - serviceArgs = args; - InitializeComponent(); - - string eventSource = "Ansible Test"; - if (!EventLog.SourceExists(eventSource)) - EventLog.CreateEventSource(eventSource, "Application"); - EventLog.Source = eventSource; - EventLog.Log = "Application"; - } - - private string GetServiceName() - { - using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = new ManagementObjectSearcher(string.Format("SELECT * FROM Win32_Service WHERE ProcessId = {0}", (object)Process.GetCurrentProcess().Id)).Get().GetEnumerator()) - { - if (enumerator.MoveNext()) - return enumerator.Current["Name"].ToString(); - } - return ServiceName; - } - - protected override void OnContinue() - { - EventLog.WriteEntry(string.Format("{0} OnContinue", displayName)); - } - - protected override void OnCustomCommand(int command) - { - EventLog.WriteEntry(string.Format("{0} OnCustomCommand {1}", displayName, command.ToString())); - } - - protected override void OnPause() - { - EventLog.WriteEntry(string.Format("{0} OnPause", displayName)); - } - - protected override void OnStart(string[] args) - { - displayName = this.GetServiceName(); - EventLog.WriteEntry(string.Format("{0} OnStart Args:\n{1}", displayName, string.Join("\n", serviceArgs))); - } - - protected override void OnShutdown() - { - EventLog.WriteEntry(string.Format("{0} OnShutdown", displayName)); - } - - protected override void OnStop() - { - EventLog.WriteEntry(string.Format("{0} OnStop", displayName)); - } - - protected override void Dispose(bool disposing) - { - if (disposing && components != null) - components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - components = new Container(); - ServiceName = nameof(SleepService); - } - } -} - diff --git a/test/integration/targets/win_service/tasks/main.yml b/test/integration/targets/win_service/tasks/main.yml deleted file mode 100644 index 5d7a0c2bc1..0000000000 --- a/test/integration/targets/win_service/tasks/main.yml +++ /dev/null @@ -1,57 +0,0 @@ -# test code for the win_service module -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: create test directory - win_file: - path: '{{ test_win_service_dir }}' - state: directory - -# This binary has been pre-compiled with the code in the files directory of this role -- name: download service executable - win_get_url: - url: '{{ test_win_service_binary_url }}' - dest: '{{ test_win_service_path }}' - -- name: remove the dummy test services if it is left over from previous tests - win_service: - name: '{{ item }}' - force_dependent_services: True - state: absent - with_items: - - '{{ test_win_service_name }}' - - TestServiceParent2 - - TestServiceDependency - -- block: - - include_tasks: tests.yml - - always: - - name: remove test services - win_service: - name: '{{ item }}' - force_dependent_services: True - state: absent - with_items: - - '{{ test_win_service_name }}' - - TestServiceParent2 - - TestServiceDependency - - - name: remove test directory - win_file: - path: '{{ test_win_service_dir }}' - state: absent diff --git a/test/integration/targets/win_service/tasks/tests.yml b/test/integration/targets/win_service/tasks/tests.yml deleted file mode 100644 index 05ada8094b..0000000000 --- a/test/integration/targets/win_service/tasks/tests.yml +++ /dev/null @@ -1,912 +0,0 @@ ---- -- name: create new dummy test service - win_service: - name: "{{test_win_service_name}}" - path: "{{test_win_service_path}}" - display_name: "{{test_win_service_display_name}}" - description: "{{test_win_service_description}}" - register: win_service_added - -- name: check that creating a new service succeeds with a change - assert: - that: - - win_service_added is changed - - win_service_added.name == test_win_service_name - - win_service_added.can_pause_and_continue == False - - win_service_added.display_name == test_win_service_display_name - - win_service_added.description == test_win_service_description - - win_service_added.path == test_win_service_path - - win_service_added.state == 'stopped' - - win_service_added.start_mode == 'auto' - - win_service_added.username == 'LocalSystem' - - win_service_added.desktop_interact == False - - win_service_added.dependencies == [] - - win_service_added.depended_by == [] - - win_service_added.exists == True - -- name: test win_service module with short name - win_service: - name: "{{test_win_service_name}}" - register: win_service_name - -- name: check win_service result with short name - assert: - that: - - win_service_name is not changed - - win_service_name.name == test_win_service_name - - win_service_name.can_pause_and_continue == False - - win_service_name.display_name == test_win_service_display_name - - win_service_name.start_mode == 'auto' - - win_service_name.state == 'stopped' - - win_service_name.description == test_win_service_description - - win_service_name.exists == True - - win_service_name.path == test_win_service_path - - win_service_name.username == 'LocalSystem' - - win_service_name.desktop_interact == False - - win_service_name.dependencies == [] - - win_service_name.depended_by == [] - -- name: test win_service module with display name - win_service: - name: "{{test_win_service_display_name}}" - register: win_service_display_name - -- name: check win_service result with display name - assert: - that: - - win_service_display_name is not changed - - win_service_display_name.name == test_win_service_name - - win_service_display_name.can_pause_and_continue == False - - win_service_display_name.display_name == test_win_service_display_name - - win_service_display_name.start_mode == 'auto' - - win_service_display_name.state == 'stopped' - - win_service_display_name.description == test_win_service_description - - win_service_display_name.exists == True - - win_service_display_name.path == test_win_service_path - - win_service_display_name.username == 'LocalSystem' - - win_service_display_name.desktop_interact == False - - win_service_display_name.dependencies == [] - - win_service_display_name.depended_by == [] - -- name: test win_service module with invalid name - win_service: - name: iamnotaservice - register: win_service_invalid - -- name: check win_service result with invalid name - assert: - that: - - win_service_invalid is not changed - - win_service_invalid.exists == False - -- name: test win_service module with invalid name and absent state - win_service: - name: iamnotaservice - state: absent - register: win_service_invalid_with_absent - -- name: check win_service result with invalid name and absent state - assert: - that: - - win_service_invalid_with_absent is not changed - - win_service_invalid_with_absent.exists == False - -- name: test win_service module with invalid name and startup - win_service: - name: iamnotaservice - state: started - register: win_service_invalid_with_action - failed_when: win_service_invalid_with_action.msg != "Service \'iamnotaservice\' is not installed, need to set \'path\' to create a new service" - -- name: make sure the service is stopped and disabled for next tests - win_service: - name: "{{test_win_service_name}}" - state: stopped - start_mode: disabled - register: win_service_stopped_disabled - -- name: try to start the disabled service - win_service: - name: "{{test_win_service_name}}" - state: started - register: win_service_start_disabled - failed_when: "'Cannot start service ' + test_win_service_name + ' on computer' not in win_service_start_disabled.msg" - -- name: enable the service for manual startup - win_service: - name: "{{test_win_service_name}}" - start_mode: manual - register: win_service_manual_start_mode - -- name: check that enabling the service for manual startup succeeded - assert: - that: - - win_service_manual_start_mode is changed - - win_service_manual_start_mode.start_mode == 'manual' - - win_service_manual_start_mode.state == 'stopped' - -- name: enable the service for manual startup again - win_service: - name: "{{test_win_service_name}}" - start_mode: manual - register: win_service_manual_start_mode_again - -- name: check that enabling service for manual startup again didn't change anything - assert: - that: - - win_service_manual_start_mode_again is not changed - - win_service_manual_start_mode_again.start_mode == 'manual' - - win_service_manual_start_mode_again.state == 'stopped' - -- name: enable the service for delayed startup from non automatic - win_service: - name: "{{test_win_service_name}}" - start_mode: delayed - register: win_service_delayed_start_mode - -- name: check that that enabling the service for delayed startup succeeded - assert: - that: - - win_service_delayed_start_mode is changed - - win_service_delayed_start_mode.start_mode == 'delayed' - - win_service_delayed_start_mode.state == 'stopped' - -- name: enable the service for delayed startup from non automatic again - win_service: - name: "{{test_win_service_name}}" - start_mode: delayed - register: win_service_delayed_start_mode_again - -- name: check that enabling the service for delayed startup again no changes - assert: - that: - - win_service_delayed_start_mode_again is not changed - - win_service_delayed_start_mode_again.start_mode == 'delayed' - - win_service_delayed_start_mode_again.state == 'stopped' - -- name: enable the service for automatic startup - win_service: - name: "{{test_win_service_name}}" - start_mode: auto - register: win_service_auto_start_mode - -- name: check that enabling the service for auto startup succeeded - assert: - that: - - win_service_auto_start_mode is changed - - win_service_auto_start_mode.start_mode == 'auto' - - win_service_auto_start_mode.state == 'stopped' - -- name: enable the service for automatic startup again - win_service: - name: "{{test_win_service_name}}" - start_mode: auto - register: win_service_auto_start_mode_again - -- name: check that enabling the service for auto startup again no changes - assert: - that: - - win_service_auto_start_mode_again is not changed - - win_service_auto_start_mode_again.start_mode == 'auto' - - win_service_auto_start_mode_again.state == 'stopped' - -- name: enable the service for delayed startup from automatic - win_service: - name: "{{test_win_service_name}}" - start_mode: delayed - register: win_service_delayed_start_mode_from_auto - -- name: check that enabling the service for delayed startup from auto succeeded - assert: - that: - - win_service_delayed_start_mode_from_auto is changed - - win_service_delayed_start_mode_from_auto.start_mode == 'delayed' - - win_service_delayed_start_mode_from_auto.state == 'stopped' - -- name: enable the service for delayed startup from automatic again - win_service: - name: "{{test_win_service_name}}" - start_mode: delayed - register: win_service_delayed_start_mode_from_auto_again - -- name: check that enabling the service for delayed startup from auto succeeded again no change - assert: - that: - - win_service_delayed_start_mode_from_auto_again is not changed - - win_service_delayed_start_mode_from_auto_again.start_mode == 'delayed' - - win_service_delayed_start_mode_from_auto_again.state == 'stopped' - -- name: start the service - win_service: - name: "{{test_win_service_name}}" - state: started - register: win_service_start - -- name: check that starting the service succeeds with changes - assert: - that: - - win_service_start is changed - - win_service_start.state == 'running' - -- name: start the service again - win_service: - name: "{{test_win_service_name}}" - state: started - register: win_service_start_again - -- name: check that starting the service succeeds again with no changes - assert: - that: - - win_service_start_again is not changed - - win_service_start_again.state == 'running' - -- name: restart the service - win_service: - name: "{{test_win_service_name}}" - state: restarted - register: win_service_restart - -- name: check that restarting the service succeeds with changes - assert: - that: - - win_service_restart is changed - - win_service_restart.state =='running' - -- name: restart the service again - win_service: - name: "{{test_win_service_name}}" - state: restarted - register: win_service_restart_again - -- name: check that restarting the service again succeeds with changes - assert: - that: - - win_service_restart_again is changed - - win_service_restart_again.state =='running' - -- name: disable the service while running - win_service: - name: "{{test_win_service_name}}" - start_mode: disabled - register: win_service_disabled_while_running - -- name: check that disabling the service succeeds, service is still running - assert: - that: - - win_service_disabled_while_running is changed - - win_service_disabled_while_running.start_mode == 'disabled' - - win_service_disabled_while_running.state == 'running' - -- name: disable the service while running again - win_service: - name: "{{test_win_service_name}}" - start_mode: disabled - register: win_service_disabled_while_running_again - -- name: check that disabling the service again succeeds, service is still running but with no changes - assert: - that: - - win_service_disabled_while_running_again is not changed - - win_service_disabled_while_running_again.start_mode == 'disabled' - - win_service_disabled_while_running_again.state == 'running' - -- name: stop the service - win_service: - name: "{{test_win_service_name}}" - state: stopped - register: win_service_stopped - -- name: check that stopping the service succeeds with changes - assert: - that: - - win_service_stopped is changed - - win_service_stopped.state == 'stopped' - -- name: stop the service again - win_service: - name: "{{test_win_service_name}}" - state: stopped - register: win_service_stopped_again - -- name: check that stopping the service again succeeds with no changes - assert: - that: - - win_service_stopped_again is not changed - - win_service_stopped_again.state == 'stopped' - -- name: set password without username - win_service: - name: "{{test_win_service_name}}" - password: password - register: win_service_change_password_without_user - failed_when: win_service_change_password_without_user.msg != "The argument 'username' must be supplied with 'password'" - -- name: set service username to Network Service and desktop interact fail - win_service: - name: "{{test_win_service_name}}" - username: NT AUTHORITY\NetworkService - desktop_interact: True - register: win_desktop_interact_not_local_system - failed_when: win_desktop_interact_not_local_system.msg != "Can only set 'desktop_interact' to true when 'username' equals 'LocalSystem'" - -- name: set service username to Network Service - win_service: - name: "{{test_win_service_name}}" - username: NT AUTHORITY\NetworkService - register: win_service_change_password_network_service - -- name: check that the service user has been set to Network Service - assert: - that: - - win_service_change_password_network_service is changed - - win_service_change_password_network_service.username == 'NT AUTHORITY\\NETWORK SERVICE' - - win_service_change_password_network_service.desktop_interact == False - -- name: set service username to Network Service again - win_service: - name: "{{test_win_service_name}}" - username: NT AUTHORITY\NetworkService - register: win_service_change_password_network_service_again - -- name: check that the service user has been set to Network Service and nothing changed - assert: - that: - - win_service_change_password_network_service_again is not changed - - win_service_change_password_network_service_again.username == 'NT AUTHORITY\\NETWORK SERVICE' - - win_service_change_password_network_service_again.desktop_interact == False - -- name: set service username to interact with desktop with existing user to fail - win_service: - name: "{{test_win_service_name}}" - desktop_interact: True - register: win_service_desktop_interact_current_user_fail - failed_when: win_service_desktop_interact_current_user_fail.msg != "Can only set desktop_interact to true when service is run with/or 'username' equals 'LocalSystem'" - -- name: set service username to Local Service - win_service: - name: "{{test_win_service_name}}" - username: NT AUTHORITY\LocalService - register: win_service_change_password_local_service - -- name: check that the service user has been set to Local Service - assert: - that: - - win_service_change_password_local_service is changed - - win_service_change_password_local_service.username == 'NT AUTHORITY\\LOCAL SERVICE' - - win_service_change_password_local_service.desktop_interact == False - -- name: set service username to Local Service again - win_service: - name: "{{test_win_service_name}}" - username: NT AUTHORITY\LocalService - register: win_service_change_password_local_service_again - -- name: check that the service user has been set to Local Service and nothing changed - assert: - that: - - win_service_change_password_local_service_again is not changed - - win_service_change_password_local_service_again.username == 'NT AUTHORITY\\LOCAL SERVICE' - - win_service_change_password_local_service_again.desktop_interact == False - -- name: set service username to Local System - win_service: - name: "{{test_win_service_name}}" - username: LocalSystem - register: win_service_change_password_local_system - -- name: check that the service user has been set to Local System - assert: - that: - - win_service_change_password_local_system is changed - - win_service_change_password_local_system.username == 'LocalSystem' - - win_service_change_password_local_system.desktop_interact == False - -- name: set service username to Local System again - win_service: - name: "{{test_win_service_name}}" - username: LocalSystem - register: win_service_change_password_local_system_again - -- name: check that the service user has been set to Local System and nothing changed - assert: - that: - - win_service_change_password_local_system_again is not changed - - win_service_change_password_local_system_again.username == 'LocalSystem' - - win_service_change_password_local_system_again.desktop_interact == False - -- name: set service username to Local System with desktop interaction - win_service: - name: "{{test_win_service_name}}" - username: SYSTEM # tests that you can also set it this way - desktop_interact: True - register: win_service_local_system_desktop - -- name: check that the service has been set to Local System with desktop interaction - assert: - that: - - win_service_local_system_desktop is changed - - win_service_local_system_desktop.username == 'LocalSystem' - - win_service_local_system_desktop.desktop_interact == True - -- name: set service username to Local System with desktop interaction again - win_service: - name: "{{test_win_service_name}}" - username: SYSTEM - desktop_interact: True - register: win_service_local_system_desktop_again - -- name: check that the service has been set to Local System with desktop interaction again - assert: - that: - - win_service_local_system_desktop_again is not changed - - win_service_local_system_desktop_again.username == 'LocalSystem' - - win_service_local_system_desktop_again.desktop_interact == True - -- name: set desktop interaction to disabled - win_service: - name: "{{test_win_service_name}}" - desktop_interact: False - register: win_service_desktop_disable - -- name: check that desktop interaction has been disabled - assert: - that: - - win_service_desktop_disable is changed - - win_service_desktop_disable.username == 'LocalSystem' - - win_service_desktop_disable.desktop_interact == False - -- name: set desktop interaction to disabled again - win_service: - name: "{{test_win_service_name}}" - desktop_interact: False - register: win_service_desktop_disable_again - -- name: check that desktop interaction has been disabled again - assert: - that: - - win_service_desktop_disable_again is not changed - - win_service_desktop_disable_again.username == 'LocalSystem' - - win_service_desktop_disable_again.desktop_interact == False - -- name: set desktop interaction to enabled with current user as LocalSystem - win_service: - name: "{{test_win_service_name}}" - desktop_interact: True - register: win_service_desktop_enable - -- name: check that desktop iteraction has been enabled - assert: - that: - - win_service_desktop_enable is changed - - win_service_desktop_enable.username == 'LocalSystem' - - win_service_desktop_enable.desktop_interact == True - -- name: set desktop interaction to enabled with current user as LocalSystem again - win_service: - name: "{{test_win_service_name}}" - desktop_interact: True - register: win_service_desktop_enable_again - -- name: check that desktop iteraction has been enabled again - assert: - that: - - win_service_desktop_enable_again is not changed - - win_service_desktop_enable_again.username == 'LocalSystem' - - win_service_desktop_enable_again.desktop_interact == True - -- name: set service username to current user - win_service: - name: "{{test_win_service_name}}" - username: "{{ansible_user}}" - password: "{{ansible_password}}" - register: win_service_change_password_current_user - -- name: check that the service user has been set to current user - assert: - that: - - win_service_change_password_current_user is changed - - win_service_change_password_current_user.username|lower == '.\\{{ansible_user|lower}}' - - win_service_change_password_current_user.desktop_interact == False - -- name: set service username to current user again - win_service: - name: "{{test_win_service_name}}" - username: "{{ansible_user}}" - password: "{{ansible_password}}" - register: win_service_change_password_current_user_again - -- name: check that the service user has been set to current user and nothing changed - assert: - that: - - win_service_change_password_current_user_again is not changed - - win_service_change_password_current_user_again.username|lower == '.\\{{ansible_user|lower}}' - - win_service_change_password_current_user_again.desktop_interact == False - -- name: set service display name - win_service: - name: "{{test_win_service_name}}" - display_name: Test Service New - register: win_service_display_name - -- name: check that the service display name has been changed - assert: - that: - - win_service_display_name is changed - - win_service_display_name.display_name == 'Test Service New' - -- name: set service display name again - win_service: - name: "{{test_win_service_name}}" - display_name: Test Service New - register: win_service_display_name_again - -- name: check that the service display name has been changed again - assert: - that: - - win_service_display_name_again is not changed - - win_service_display_name_again.display_name == 'Test Service New' - -- name: set service description - win_service: - name: "{{test_win_service_name}}" - description: New Description - register: win_service_description - -- name: check that the service description has been changed - assert: - that: - - win_service_description is changed - - win_service_description.description == 'New Description' - -- name: set service description again - win_service: - name: "{{test_win_service_name}}" - description: New Description - register: win_service_description_again - -- name: check that the service description has been changed again - assert: - that: - - win_service_description_again is not changed - - win_service_description_again.description == 'New Description' - -- name: set service path - win_service: - name: "{{test_win_service_name}}" - path: C:\temp\test.exe - register: win_service_path - -- name: check that the service path has been changed - assert: - that: - - win_service_path is changed - - win_service_path.path == 'C:\\temp\\test.exe' - -- name: set service path again - win_service: - name: "{{test_win_service_name}}" - path: C:\temp\test.exe - register: win_service_path_again - -- name: check that the service path has been changed again - assert: - that: - - win_service_path_again is not changed - - win_service_path_again.path == 'C:\\temp\\test.exe' - -- name: set service path with quotes and env var - win_service: - name: "{{test_win_service_name}}" - path: '"%TEST_SERVICE_PATH%\test.exe"' - register: win_service_env_quote_path - environment: - TEST_SERVICE_PATH: C:\temp - -- name: check that the quoted service path has been changed - assert: - that: - - win_service_env_quote_path is changed - - win_service_env_quote_path.path == '"C:\\temp\\test.exe"' - -- name: set service path with quotes and env var again - win_service: - name: "{{test_win_service_name}}" - path: '"%TEST_SERVICE_PATH%\test.exe"' - register: win_service_env_quote_path_again - environment: - TEST_SERVICE_PATH: C:\temp - -- name: check that the quoted service path has been changed again - assert: - that: - - win_service_env_quote_path_again is not changed - - win_service_env_quote_path_again.path == '"C:\\temp\\test.exe"' - -- name: revert original service path back to normal - win_service: - name: "{{test_win_service_name}}" - path: "{{test_win_service_path}}" - -- name: create new second dependency parent service - win_service: - name: TestServiceParent2 - display_name: Test Service Parent 2 - path: "{{test_win_service_path}}" - -- name: create new dependency service - win_service: - name: TestServiceDependency - display_name: Test Service Dependency - path: "{{test_win_service_path}}" - dependencies: "{{test_win_service_name}}" - register: win_service_dependency_string - -- name: check that the service with a dependency has been created - assert: - that: - - win_service_dependency_string is changed - - win_service_dependency_string.dependencies == ['{{test_win_service_name}}'] - -- name: create new dependencys service again - win_service: - name: TestServiceDependency - dependencies: "{{test_win_service_name}}" - register: win_service_dependency_string_again - -- name: check that the service with a dependency has been created again - assert: - that: - - win_service_dependency_string_again is not changed - - win_service_dependency_string_again.dependencies == ['{{test_win_service_name}}'] - -- name: add another dependency to service - win_service: - name: TestServiceDependency - dependencies: ['TestServiceParent2'] - dependency_action: add - register: win_service_dependency_add - -- name: check that the service with a dependency has been added - assert: - that: - - win_service_dependency_add is changed - - win_service_dependency_add.dependencies == ['TestServiceParent2', '{{test_win_service_name}}'] - -- name: add another dependency to service again - win_service: - name: TestServiceDependency - dependencies: ['TestServiceParent2'] - dependency_action: add - register: win_service_dependency_add_again - -- name: check that the service with a dependency has been added again - assert: - that: - - win_service_dependency_add_again is not changed - - win_service_dependency_add_again.dependencies == ['TestServiceParent2', '{{test_win_service_name}}'] - -- name: remove another dependency to service - win_service: - name: TestServiceDependency - dependencies: ['TestServiceParent2'] - dependency_action: remove - register: win_service_dependency_add - -- name: check that the service with a dependency has been remove - assert: - that: - - win_service_dependency_add is changed - - win_service_dependency_add.dependencies == ['{{test_win_service_name}}'] - -- name: remove another dependency to service again - win_service: - name: TestServiceDependency - dependencies: ['TestServiceParent2'] - dependency_action: remove - register: win_service_dependency_add_again - -- name: check that the service with a dependency has been removed again - assert: - that: - - win_service_dependency_add_again is not changed - - win_service_dependency_add_again.dependencies == ['{{test_win_service_name}}'] - -- name: set dependency with a list - win_service: - name: TestServiceDependency - dependencies: ['{{test_win_service_name}}', 'TestServiceParent2'] - dependency_action: set - register: win_service_dependency_set_list - -- name: check that the service with dependencies has been set - assert: - that: - - win_service_dependency_set_list is changed - - win_service_dependency_set_list.dependencies == ['TestServiceParent2', '{{test_win_service_name}}'] - -- name: make sure all services are stopped, set to LocalSystem and set to auto start before next test - win_service: - name: "{{item}}" - force_dependent_services: True - state: stopped - start_mode: auto - username: LocalSystem - password: "" - with_items: - - '{{test_win_service_name}}' - - TestServiceParent2 - - TestServiceDependency - -- name: start up dependency service - win_service: - name: TestServiceDependency - state: started - -- name: wait 5 seconds for service to propagate service startup - pause: - seconds: 5 - -- name: get stat of 1st parent service - win_service: - name: "{{test_win_service_name}}" - register: win_service_parent1_stat - -- name: get stat of 2nd parent service - win_service: - name: TestServiceParent2 - register: win_service_parent2_stat - -- name: get stat of dependent service - win_service: - name: TestServiceDependency - register: win_service_dependent_stat - -- name: check that the dependency services started correctly and have the correct stats - assert: - that: - - win_service_parent1_stat.state == 'running' - - win_service_parent2_stat.state == 'running' - - win_service_dependent_stat.state == 'running' - - win_service_parent1_stat.depended_by == ['TestServiceDependency'] - - win_service_parent2_stat.depended_by == ['TestServiceDependency'] - -- name: fail to remove service with dependencies - win_service: - name: "{{test_win_service_name}}" - state: absent - register: win_service_removed_failed - failed_when: win_service_removed_failed.msg != "Cannot stop service 'Test Service New (" + test_win_service_name + ")' because it has dependent services. It can only be stopped if the Force flag is set." - -- name: remove the service while ignoring dependencies - win_service: - name: "{{test_win_service_name}}" - force_dependent_services: True - state: absent - register: win_service_removed - -- name: check that removing the service while ignoring dependencies succeeds with changes - assert: - that: - - win_service_removed is changed - - win_service_removed.exists == False - - win_service_removed.description is not defined - - win_service_removed.display_name is not defined - - win_service_removed.name is not defined - - win_service_removed.path is not defined - - win_service_removed.start_mode is not defined - - win_service_removed.state is not defined - - win_service_removed.username is not defined - -- name: create new pausable dummy test service - win_service: - name: "{{test_win_service_name}}" - path: "{{test_win_service_path}}" - display_name: "{{test_win_service_display_name}}" - description: "{{test_win_service_description}}" - state: started - register: stat_pausable_service - -- name: assert get details on a pausable service - assert: - that: - - stat_pausable_service.can_pause_and_continue == True - -- name: pause a service check - win_service: - name: '{{test_win_service_name}}' - state: paused - register: win_service_paused_check - check_mode: yes - -- name: assert pause a service check - assert: - that: - - win_service_paused_check is changed - - win_service_paused_check.state == 'running' - -- name: pause a service - win_service: - name: '{{test_win_service_name}}' - state: paused - register: win_service_paused - -- name: assert pause a service - assert: - that: - - win_service_paused is changed - - win_service_paused.state == 'paused' - -- name: pause a service again - win_service: - name: '{{test_win_service_name}}' - state: paused - register: win_service_paused_again - -- name: assert pause a service again - assert: - that: - - win_service_paused_again is not changed - -- name: start a paused service check - win_service: - name: '{{test_win_service_name}}' - state: started - register: start_paused_service_check - check_mode: yes - -- name: assert start a paused service check - assert: - that: - - start_paused_service_check is changed - - start_paused_service_check.state == 'paused' - -- name: start a paused service - win_service: - name: '{{test_win_service_name}}' - state: started - register: start_paused_service - -- name: assert start a paused service - assert: - that: - - start_paused_service is changed - - start_paused_service.state == 'running' - -- name: pause service for next test - win_service: - name: '{{test_win_service_name}}' - state: paused - -- name: stop a paused service check - win_service: - name: '{{test_win_service_name}}' - state: stopped - force_dependent_services: True - register: stop_paused_service_check - check_mode: yes - -- name: assert stop a paused service check - assert: - that: - - stop_paused_service_check is changed - - stop_paused_service_check.state == 'paused' - -- name: stop a paused service - win_service: - name: '{{test_win_service_name}}' - state: stopped - force_dependent_services: True - register: stop_paused_service - -- name: assert stop a paused service - assert: - that: - - stop_paused_service is changed - - stop_paused_service.state == 'stopped' - -- name: fail to pause a stopped service check - win_service: - name: '{{test_win_service_name}}' - state: paused - register: fail_pause_stopped_service - failed_when: "fail_pause_stopped_service.msg != 'failed to pause service ' + test_win_service_name + ': The service does not support pausing'" diff --git a/test/integration/targets/win_service_info/aliases b/test/integration/targets/win_service_info/aliases deleted file mode 100644 index 71fee86193..0000000000 --- a/test/integration/targets/win_service_info/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group7 -shippable/windows/smoketest diff --git a/test/integration/targets/win_service_info/defaults/main.yml b/test/integration/targets/win_service_info/defaults/main.yml deleted file mode 100644 index 0da553d9b2..0000000000 --- a/test/integration/targets/win_service_info/defaults/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -test_path: '{{ remote_tmp_dir }}\win_service_info .ÅÑŚÌβŁÈ [$!@^&test(;)]' -service_url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_service/SleepService.exe - -service_name1: ansible_service_info_test -service_name2: ansible_service_info_test2 -service_name3: ansible_service_info_other -service_names: -- '{{ service_name1 }}' -- '{{ service_name2 }}' -- '{{ service_name3 }}' diff --git a/test/integration/targets/win_service_info/handlers/main.yml b/test/integration/targets/win_service_info/handlers/main.yml deleted file mode 100644 index ee2d93eb19..0000000000 --- a/test/integration/targets/win_service_info/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: remove test service - win_service: - name: '{{ item }}' - state: absent - loop: '{{ service_names }}' diff --git a/test/integration/targets/win_service_info/meta/main.yml b/test/integration/targets/win_service_info/meta/main.yml deleted file mode 100644 index 9f37e96cd9..0000000000 --- a/test/integration/targets/win_service_info/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- setup_remote_tmp_dir diff --git a/test/integration/targets/win_service_info/tasks/main.yml b/test/integration/targets/win_service_info/tasks/main.yml deleted file mode 100644 index d393322236..0000000000 --- a/test/integration/targets/win_service_info/tasks/main.yml +++ /dev/null @@ -1,206 +0,0 @@ ---- -- name: ensure test directory exists - win_file: - path: '{{ test_path }}' - state: directory - -- name: download test binary for services - win_get_url: - url: '{{ service_url }}' - dest: '{{ test_path }}\SleepService.exe' - -- name: create test service - win_service: - name: '{{ item }}' - path: '"{{ test_path }}\SleepService.exe"' - state: stopped - loop: '{{ service_names }}' - notify: remove test service - -- name: test we can get info for all services - win_service_info: - register: all_actual - check_mode: yes # tests that this will run in check mode - -- name: assert test we can get info for all services - assert: - that: - - not all_actual is changed - - all_actual.exists - - all_actual.services | length > 0 - -- name: test info on a missing service - win_service_info: - name: ansible_service_info_missing - register: missing_service - -- name: assert test info on a missing service - assert: - that: - - not missing_service is changed - - not missing_service.exists - -- name: test info on a single service - win_service_info: - name: '{{ service_name1 }}' - register: specific_service - -- name: assert test info on single service - assert: - that: - - not specific_service is changed - - specific_service.exists - - specific_service.services | length == 1 - - specific_service.services[0].checkpoint == 0 - - specific_service.services[0].controls_accepted == [] - - specific_service.services[0].dependencies == [] - - specific_service.services[0].dependency_of == [] - - specific_service.services[0].description == None - - specific_service.services[0].desktop_interact == False - - specific_service.services[0].display_name == service_name1 - - specific_service.services[0].error_control == 'normal' - - specific_service.services[0].failure_actions == [] - - specific_service.services[0].failure_actions_on_non_crash_failure == False - - specific_service.services[0].failure_command == None - - specific_service.services[0].failure_reboot_msg == None - - specific_service.services[0].failure_reset_period_sec == 0 - - specific_service.services[0].launch_protection == 'none' - - specific_service.services[0].load_order_group == "" - - specific_service.services[0].name == service_name1 - - specific_service.services[0].path == '"' ~ test_path + '\\SleepService.exe"' - - specific_service.services[0].pre_shutdown_timeout_ms is defined # Looks like the default for New-Service differs per OS version - - specific_service.services[0].preferred_node == None - - specific_service.services[0].process_id == 0 - - specific_service.services[0].required_privileges == [] - - specific_service.services[0].service_exit_code == 0 - - specific_service.services[0].service_flags == [] - - specific_service.services[0].service_type == 'win32_own_process' - - specific_service.services[0].sid_info == 'none' - - specific_service.services[0].start_mode == 'auto' - - specific_service.services[0].state == 'stopped' - - specific_service.services[0].triggers == [] - - specific_service.services[0].username == 'NT AUTHORITY\SYSTEM' - - specific_service.services[0].wait_hint_ms == 0 - - specific_service.services[0].win32_exit_code == 1077 - -- name: test info on services matching wildcard - win_service_info: - name: ansible_service_info_t* # should match service_name 1 and 2, but not 3 - register: wildcard_service - -- name: assert test info on services matching wildcard - assert: - that: - - not wildcard_service is changed - - wildcard_service.exists - - wildcard_service.services | length == 2 - - wildcard_service.services[0].name == service_name1 - - wildcard_service.services[1].name == service_name2 - -- name: modify service1 to depend on service 2 - win_service: - name: '{{ service_name1 }}' - state: stopped - dependencies: - - '{{ service_name2 }}' - -- name: edit basic settings for service 2 - win_service: - dependencies: - - '{{ service_name3 }}' - description: Service description - display_name: Ansible Service Display Name - name: '{{ service_name2 }}' - state: stopped - -# TODO: move this back into the above once win_service supports them -- name: edit complex settings for service 2 - win_command: sc.exe {{ item.action }} {{ service_name2 }} {{ item.args }} - with_items: - - action: config - args: type= share type= interact error= ignore group= "My group" start= delayed-auto - - action: failure - args: reset= 86400 reboot= "Reboot msg" command= "Command line" actions= run/500/run/600/restart/700/reboot/800 - - action: failureflag - args: 1 - - action: sidtype - args: unrestricted - - action: privs - args: SeBackupPrivilege/SeRestorePrivilege - - action: triggerinfo - args: start/namedpipe/abc start/namedpipe/def start/custom/0e0682e2-9951-4e6d-a36a-a0047e616f28/11223344/aabbccdd start/strcustom/c2961e88-c1f4-4d97-b581-219c852e1c7d/11223344/aabbccdd start/portopen/1234;tcp;imagepath;servicename - -- name: get info of advanced service using display name - win_service_info: - name: Ansible Service Display Name - register: adv_service - -- name: assert get info of advanced service using display_name - assert: - that: - - not adv_service is changed - - adv_service.exists - - adv_service.services | length == 1 - - adv_service.services[0].dependencies == [service_name3] - - adv_service.services[0].dependency_of == [service_name1] - - adv_service.services[0].description == 'Service description' - - adv_service.services[0].desktop_interact == True - - adv_service.services[0].error_control == 'ignore' - - adv_service.services[0].failure_actions | length == 4 - - adv_service.services[0].failure_actions[0].delay_ms == 500 - - adv_service.services[0].failure_actions[0].type == 'run_command' - - adv_service.services[0].failure_actions[1].delay_ms == 600 - - adv_service.services[0].failure_actions[1].type == 'run_command' - - adv_service.services[0].failure_actions[2].delay_ms == 700 - - adv_service.services[0].failure_actions[2].type == 'restart' - - adv_service.services[0].failure_actions[3].delay_ms == 800 - - adv_service.services[0].failure_actions[3].type == 'reboot' - - adv_service.services[0].failure_actions_on_non_crash_failure == True - - adv_service.services[0].failure_command == 'Command line' - - adv_service.services[0].failure_reboot_msg == 'Reboot msg' - - adv_service.services[0].failure_reset_period_sec == 86400 - - adv_service.services[0].load_order_group == 'My group' - - adv_service.services[0].required_privileges == ['SeBackupPrivilege', 'SeRestorePrivilege'] - - adv_service.services[0].service_type == 'win32_share_process' - - adv_service.services[0].sid_info == 'unrestricted' - - adv_service.services[0].start_mode == 'delayed' - - adv_service.services[0].triggers | length == 5 - - adv_service.services[0].triggers[0].action == 'start_service' - - adv_service.services[0].triggers[0].data_items | length == 1 - - adv_service.services[0].triggers[0].data_items[0].data == 'abc' - - adv_service.services[0].triggers[0].data_items[0].type == 'string' - - adv_service.services[0].triggers[0].sub_type == 'named_pipe_event' - - adv_service.services[0].triggers[0].sub_type_guid == '1f81d131-3fac-4537-9e0c-7e7b0c2f4b55' - - adv_service.services[0].triggers[0].type == 'network_endpoint' - - adv_service.services[0].triggers[1].action == 'start_service' - - adv_service.services[0].triggers[1].data_items | length == 1 - - adv_service.services[0].triggers[1].data_items[0].data == 'def' - - adv_service.services[0].triggers[1].data_items[0].type == 'string' - - adv_service.services[0].triggers[1].sub_type == 'named_pipe_event' - - adv_service.services[0].triggers[1].sub_type_guid == '1f81d131-3fac-4537-9e0c-7e7b0c2f4b55' - - adv_service.services[0].triggers[1].type == 'network_endpoint' - - adv_service.services[0].triggers[2].action == 'start_service' - - adv_service.services[0].triggers[2].data_items | length == 2 - - adv_service.services[0].triggers[2].data_items[0].data == 'ESIzRA==' - - adv_service.services[0].triggers[2].data_items[0].type == 'binary' - - adv_service.services[0].triggers[2].data_items[1].data == 'qrvM3Q==' - - adv_service.services[0].triggers[2].data_items[1].type == 'binary' - - adv_service.services[0].triggers[2].sub_type == 'custom' - - adv_service.services[0].triggers[2].sub_type_guid == '0e0682e2-9951-4e6d-a36a-a0047e616f28' - - adv_service.services[0].triggers[2].type == 'custom' - - adv_service.services[0].triggers[3].action == 'start_service' - - adv_service.services[0].triggers[3].data_items | length == 2 - - adv_service.services[0].triggers[3].data_items[0].data == '11223344' - - adv_service.services[0].triggers[3].data_items[0].type == 'string' - - adv_service.services[0].triggers[3].data_items[1].data == 'aabbccdd' - - adv_service.services[0].triggers[3].data_items[1].type == 'string' - - adv_service.services[0].triggers[3].sub_type == 'custom' - - adv_service.services[0].triggers[3].sub_type_guid == 'c2961e88-c1f4-4d97-b581-219c852e1c7d' - - adv_service.services[0].triggers[3].type == 'custom' - - adv_service.services[0].triggers[4].action == 'start_service' - - adv_service.services[0].triggers[4].data_items | length == 1 - - adv_service.services[0].triggers[4].data_items[0].data == ['1234', 'tcp', 'imagepath', 'servicename'] - - adv_service.services[0].triggers[4].data_items[0].type == 'string' - - adv_service.services[0].triggers[4].sub_type == 'firewall_port_open' - - adv_service.services[0].triggers[4].sub_type_guid == 'b7569e07-8421-4ee0-ad10-86915afdad09' - - adv_service.services[0].triggers[4].type == 'firewall_port_event' diff --git a/test/integration/targets/win_setup/aliases b/test/integration/targets/win_setup/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_setup/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_setup/tasks/main.yml b/test/integration/targets/win_setup/tasks/main.yml deleted file mode 100644 index a81a00f1ae..0000000000 --- a/test/integration/targets/win_setup/tasks/main.yml +++ /dev/null @@ -1,141 +0,0 @@ -# test code for the setup module when using winrm connection -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: test setup module - action: setup - register: setup_result - -- name: check windows setup result - assert: - that: - - setup_result is not failed - - setup_result is not changed - - setup_result.ansible_facts - - setup_result.ansible_facts.ansible_os_family == 'Windows' - - setup_result.ansible_facts.ansible_date_time - - setup_result.ansible_facts.ansible_date_time.date - - setup_result.ansible_facts.ansible_date_time.year - - setup_result.ansible_facts.ansible_date_time.month - - setup_result.ansible_facts.ansible_date_time.day - - setup_result.ansible_facts.ansible_date_time.hour is defined - - setup_result.ansible_facts.ansible_date_time.minute is defined - - setup_result.ansible_facts.ansible_date_time.iso8601 - - setup_result.ansible_facts.ansible_distribution - - setup_result.ansible_facts.ansible_distribution_version - - setup_result.ansible_facts.ansible_fqdn - - setup_result.ansible_facts.ansible_hostname - - setup_result.ansible_facts.ansible_ip_addresses - - setup_result.ansible_facts.ansible_system - - setup_result.ansible_facts.ansible_memtotal_mb - - setup_result.ansible_facts.ansible_interfaces - - setup_result.ansible_facts.ansible_interfaces[0] - - setup_result.ansible_facts.ansible_interfaces[0].interface_name - - setup_result.ansible_facts.ansible_interfaces[0].connection_name - - setup_result.ansible_facts.ansible_interfaces[0].interface_index - - setup_result.ansible_facts.ansible_architecture - - setup_result.ansible_facts.ansible_os_name - - setup_result.ansible_facts.ansible_powershell_version - - setup_result.ansible_facts.gather_subset is defined - - setup_result.ansible_facts.gather_subset[0] == 'all' - - setup_result.ansible_facts.module_setup == true - -- name: check setup result only when using https - assert: - that: - - "setup_result.ansible_facts.ansible_win_rm_certificate_expires" - when: ansible_ssh_port|default(5986) != 5985 - -- name: test gather_subset "!all" - setup: - gather_subset: '!all' - register: setup_result - -- name: verify that some known "all" keys are missing (should just be "min" subset) - assert: - that: - - setup_result is not failed - - setup_result is not changed - - setup_result.ansible_facts is defined - - setup_result.ansible_facts.gather_subset[0] == '!all' - - setup_result.ansible_facts.gather_subset is defined - - setup_result.ansible_facts.ansible_ip_addresses is not defined - - setup_result.ansible_facts.ansible_interfaces is not defined - -- name: test gather_subset "!all,!min" with list - setup: - gather_subset: - - '!all' - - '!min' - register: setup_result - -- name: verify that only status keys are returned - assert: - that: - - setup_result is not failed - - setup_result is not changed - - setup_result.ansible_facts is defined - - setup_result.ansible_facts.gather_subset is defined - - setup_result.ansible_facts.gather_subset[0] == '!all' - - setup_result.ansible_facts.gather_subset[1] == '!min' - - setup_result.ansible_facts.keys() | list | union(['gather_subset','module_setup']) | length == 2 - -- name: test gather_subset "!all,!min,interfaces" with list - setup: - gather_subset: - - '!all' - - '!min' - - interfaces - register: setup_result - -- name: verify that only status keys and ansible_interfaces are returned - assert: - that: - - setup_result is not failed - - setup_result is not changed - - setup_result.ansible_facts is defined - - setup_result.ansible_facts.gather_subset is defined - - setup_result.ansible_facts.gather_subset[0] == '!all' - - setup_result.ansible_facts.gather_subset[1] == '!min' - - setup_result.ansible_facts.gather_subset[2] == 'interfaces' - - setup_result.ansible_facts.ansible_interfaces - - setup_result.ansible_facts.ansible_interfaces[0] - - setup_result.ansible_facts.ansible_interfaces[0].interface_name - - setup_result.ansible_facts.ansible_interfaces[0].connection_name - - setup_result.ansible_facts.ansible_interfaces[0].interface_index - - setup_result.ansible_facts.keys() | list | union(['ansible_interfaces','gather_subset','module_setup']) | length == 3 - -- name: test gather_subset "!all,!min,bogus" with list - setup: - gather_subset: - - '!all' - - '!min' - - bogus - register: setup_result - -- name: verify that only status keys are returned and that we got a warning - assert: - that: - - setup_result is not failed - - setup_result is not changed - - setup_result.ansible_facts is defined - - setup_result.ansible_facts.gather_subset is defined - - setup_result.ansible_facts.gather_subset[0] == '!all' - - setup_result.ansible_facts.gather_subset[1] == '!min' - - setup_result.ansible_facts.keys() | list | union(['gather_subset','module_setup']) | length == 2 - - setup_result.warnings | length == 1 - - setup_result.warnings[0] | regex_search('bogus') diff --git a/test/integration/targets/win_share/aliases b/test/integration/targets/win_share/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_share/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_share/defaults/main.yml b/test/integration/targets/win_share/defaults/main.yml deleted file mode 100644 index 0b6c59a3dd..0000000000 --- a/test/integration/targets/win_share/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -test_win_share_path: C:\ansible\win_share -test_win_share_name: test share diff --git a/test/integration/targets/win_share/tasks/main.yml b/test/integration/targets/win_share/tasks/main.yml deleted file mode 100644 index 12aef5ece0..0000000000 --- a/test/integration/targets/win_share/tasks/main.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -- name: check if -SmbShare cmdlets are available - win_command: powershell.exe "Get-Command -Name Get-SmbShare" - register: module_available - failed_when: False - -- name: check that module fails with helpful message on older hosts - win_share: - name: test - register: module_not_supported - when: module_available.rc == 1 - failed_when: module_not_supported.msg != 'The current host does not support the -SmbShare cmdlets required by this module. Please run on Server 2012 or Windows 8 and later' - check_mode: yes - -# Run the actual tests -- block: - # setup for tests - - name: create testing folder - win_file: - path: "{{test_win_share_path}}" - state: directory - - - name: ensure testing folder isn't shared as a baseline - win_share: - name: "{{test_win_share_name}}" - state: absent - - - name: run tests on hosts that support it - include_tasks: tests.yml - when: module_available.rc == 0 - - always: - # cleanup - - name: ensure testing folder isn't shared anymore - win_share: - name: "{{test_win_share_name}}" - state: absent - - - name: remove testing folder - win_file: - path: "{{test_win_share_path}}" - state: absent - when: module_available.rc == 0 diff --git a/test/integration/targets/win_share/tasks/tests.yml b/test/integration/targets/win_share/tasks/tests.yml deleted file mode 100644 index 543f7bae89..0000000000 --- a/test/integration/targets/win_share/tasks/tests.yml +++ /dev/null @@ -1,486 +0,0 @@ ---- -- name: create share check - win_share: - name: "{{test_win_share_name}}" - path: "{{test_win_share_path}}" - state: present - register: create_share_check - check_mode: yes - -- name: check if share exists check - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: create_share_actual_check - -- name: assert create share check - assert: - that: - - create_share_check is changed - - create_share_actual_check.stdout_lines == [] - -- name: create share - win_share: - name: "{{test_win_share_name}}" - path: "{{test_win_share_path}}" - state: present - register: create_share - -- name: check if share exists - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: create_share_actual - -- name: assert create share - assert: - that: - - create_share is changed - - create_share_actual.stdout_lines != [] - -- name: create share again - win_share: - name: "{{test_win_share_name}}" - path: "{{test_win_share_path}}" - state: present - register: create_share_again - -- name: check if share exists again - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: create_share_actual_again - -- name: assert create share again - assert: - that: - - create_share_again is not changed - - create_share_actual_again.stdout_lines == create_share_actual.stdout_lines - -- name: set caching mode to Programs check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - caching_mode: Programs - register: caching_mode_programs_check - check_mode: yes - -- name: get actual caching mode check - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').CachingMode" - register: caching_mode_programs_actual_check - -- name: assert caching mode to Programs check - assert: - that: - - caching_mode_programs_check is changed - - caching_mode_programs_actual_check.stdout == "Manual\r\n" - -- name: set caching mode to Programs - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - caching_mode: Programs - register: caching_mode_programs - -- name: get actual caching mode - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').CachingMode" - register: caching_mode_programs_actual - -- name: assert caching mode to Programs - assert: - that: - - caching_mode_programs is changed - - caching_mode_programs_actual.stdout == "Programs\r\n" - -- name: set caching mode to Programs again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - caching_mode: Programs - register: caching_mode_programs_again - -- name: get actual caching mode again - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').CachingMode" - register: caching_mode_programs_actual_again - -- name: assert caching mode to Programs again - assert: - that: - - caching_mode_programs_again is not changed - - caching_mode_programs_actual_again.stdout == "Programs\r\n" - -- name: set encryption on share check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - encrypt: True - register: encrypt_on_check - check_mode: yes - -- name: get actual encrypt mode check - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').EncryptData" - register: encrypt_on_actual_check - -- name: assert set encryption on check - assert: - that: - - encrypt_on_check is changed - - encrypt_on_actual_check.stdout == "False\r\n" - -- name: set encryption on share - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - encrypt: True - register: encrypt_on - -- name: get actual encrypt mode - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').EncryptData" - register: encrypt_on_actual - -- name: assert set encryption on - assert: - that: - - encrypt_on is changed - - encrypt_on_actual.stdout == "True\r\n" - -- name: set encryption on share again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - encrypt: True - register: encrypt_on_again - -- name: get actual encrypt mode again - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').EncryptData" - register: encrypt_on_actual - -- name: assert set encryption on again - assert: - that: - - encrypt_on_again is not changed - - encrypt_on_actual.stdout == "True\r\n" - -- name: set description check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - description: description - register: change_decription_check - check_mode: yes - -- name: get actual description check - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').Description" - register: change_description_actual_check - -- name: assert change description check - assert: - that: - - change_decription_check is changed - - change_description_actual_check.stdout == "\r\n" - -- name: set description - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - description: description - register: change_decription - -- name: get actual description - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').Description" - register: change_description_actual - -- name: assert change description - assert: - that: - - change_decription is changed - - change_description_actual.stdout == "description\r\n" - -- name: set description again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - description: description - register: change_decription_again - -- name: get actual description again - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').Description" - register: change_description_actual_again - -- name: assert change description again - assert: - that: - - change_decription_again is not changed - - change_description_actual_again.stdout == "description\r\n" - -- name: set allow list check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: True - register: allow_list_check - check_mode: yes - -- name: get actual allow listing check - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: allow_list_actual_check - -- name: assert allow list check - assert: - that: - - allow_list_check is changed - - allow_list_actual_check.stdout == "AccessBased\r\n" - -- name: set allow list - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: True - register: allow_list - -- name: get actual allow listing - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: allow_list_actual - -- name: assert allow list - assert: - that: - - allow_list is changed - - allow_list_actual.stdout == "Unrestricted\r\n" - -- name: set allow list again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: True - register: allow_list_again - -- name: get actual allow listing again - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: allow_list_actual_again - -- name: assert allow list check again - assert: - that: - - allow_list_again is not changed - - allow_list_actual_again.stdout == "Unrestricted\r\n" - -- name: set deny list check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: False - register: deny_list_check - check_mode: yes - -- name: get actual deny listing check - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: deny_list_actual_check - -- name: assert deny list check - assert: - that: - - deny_list_check is changed - - deny_list_actual_check.stdout == "Unrestricted\r\n" - -- name: set deny list - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: False - register: deny_list - -- name: get actual deny listing - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: deny_list_actual - -- name: assert deny list - assert: - that: - - deny_list is changed - - deny_list_actual.stdout == "AccessBased\r\n" - -- name: set deny list again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - list: False - register: deny_list_again - -- name: get actual deny listing again - win_command: powershell.exe "(Get-SmbShare -Name '{{test_win_share_name}}').FolderEnumerationMode" - register: deny_list_actual_again - -- name: assert deny list again - assert: - that: - - deny_list_again is not changed - - deny_list_actual_again.stdout == "AccessBased\r\n" - -- name: set ACLs on share check - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - full: Administrators - change: Users - read: Guests - deny: Remote Desktop Users - register: set_acl_check - check_mode: yes - -- name: get actual share ACLs check - win_shell: foreach ($acl in Get-SmbShareAccess -Name '{{test_win_share_name}}') { Write-Host "$($acl.AccessRight)|$($acl.AccessControlType)|$($acl.AccountName)" } - register: set_acl_actual_check - -- name: assert set ACLs on share check - assert: - that: - - set_acl_check is changed - - set_acl_actual_check.stdout == "Full|Deny|Everyone\n" - -- name: set ACLs on share - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - full: Administrators - change: Users - read: Guests - deny: Remote Desktop Users - register: set_acl - -- name: get actual share ACLs - win_shell: foreach ($acl in Get-SmbShareAccess -Name '{{test_win_share_name}}') { Write-Host "$($acl.AccessRight)|$($acl.AccessControlType)|$($acl.AccountName)" } - register: set_acl_actual - -- name: assert set ACLs on share - assert: - that: - - set_acl is changed - - set_acl_actual.stdout_lines|length == 4 - - set_acl_actual.stdout_lines[0] == 'Full|Deny|BUILTIN\\Remote Desktop Users' - - set_acl_actual.stdout_lines[1] == 'Read|Allow|BUILTIN\\Guests' - - set_acl_actual.stdout_lines[2] == 'Change|Allow|BUILTIN\\Users' - - set_acl_actual.stdout_lines[3] == 'Full|Allow|BUILTIN\\Administrators' - -- name: set ACLs on share again - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - full: Administrators - change: Users - read: Guests - deny: Remote Desktop Users - register: set_acl_again - -- name: get actual share ACLs again - win_shell: foreach ($acl in Get-SmbShareAccess -Name '{{test_win_share_name}}') { Write-Host "$($acl.AccessRight)|$($acl.AccessControlType)|$($acl.AccountName)" } - register: set_acl_actual_again - -- name: assert set ACLs on share again - assert: - that: - - set_acl_again is not changed - - set_acl_actual_again.stdout_lines|length == 4 - - set_acl_actual_again.stdout_lines[0] == 'Full|Deny|BUILTIN\\Remote Desktop Users' - - set_acl_actual_again.stdout_lines[1] == 'Read|Allow|BUILTIN\\Guests' - - set_acl_actual_again.stdout_lines[2] == 'Change|Allow|BUILTIN\\Users' - - set_acl_actual_again.stdout_lines[3] == 'Full|Allow|BUILTIN\\Administrators' - -- name: Append ACLs on share - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - change: Remote Desktop Users - rule_action: add - register: append_acl - -- name: get actual share ACLs - win_shell: foreach ($acl in Get-SmbShareAccess -Name '{{test_win_share_name}}') { Write-Host "$($acl.AccessRight)|$($acl.AccessControlType)|$($acl.AccountName)" } - register: append_acl_actual - -- name: assert Append ACLs on share - assert: - that: - - append_acl is changed - - append_acl_actual.stdout_lines|length == 5 - - append_acl_actual.stdout_lines[0] == 'Full|Deny|BUILTIN\Remote Desktop Users' - - append_acl_actual.stdout_lines[1] == 'Read|Allow|BUILTIN\\Guests' - - append_acl_actual.stdout_lines[2] == 'Change|Allow|BUILTIN\\Users' - - append_acl_actual.stdout_lines[3] == 'Full|Allow|BUILTIN\\Administrators' - - append_acl_actual.stdout_lines[4] == 'Change|Allow|BUILTIN\\Remote Desktop Users' - -- name: Append ACLs on share (idempotent) - win_share: - name: "{{test_win_share_name}}" - state: present - path: "{{test_win_share_path}}" - change: Remote Desktop Users - rule_action: add - register: append_acl_again - -- name: assert Append ACLs on share (idempotent) - assert: - that: - - not append_acl_again is changed - -- name: remove share check - win_share: - name: "{{test_win_share_name}}" - state: absent - register: remove_share_check - check_mode: yes - -- name: check if share is removed check - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: remove_share_actual_check - -- name: assert remove share check - assert: - that: - - remove_share_check is changed - - remove_share_actual_check.stdout_lines != [] - -- name: remove share - win_share: - name: "{{test_win_share_name}}" - state: absent - register: remove_share - -- name: check if share is removed - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: remove_share_actual - -- name: assert remove share - assert: - that: - - remove_share is changed - - remove_share_actual.stdout_lines == [] - -- name: remove share again - win_share: - name: "{{test_win_share_name}}" - state: absent - register: remove_share_again - -- name: check if share is removed again - win_shell: Get-SmbShare | Where-Object { $_.Name -eq '{{test_win_share_name}}' } - register: remove_share_actual_again - -- name: assert remove share again - assert: - that: - - remove_share_again is not changed - - remove_share_actual_again.stdout_lines == [] diff --git a/test/integration/targets/win_shell/aliases b/test/integration/targets/win_shell/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_shell/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_shell/tasks/main.yml b/test/integration/targets/win_shell/tasks/main.yml deleted file mode 100644 index 38387a30ab..0000000000 --- a/test/integration/targets/win_shell/tasks/main.yml +++ /dev/null @@ -1,331 +0,0 @@ -- name: execute a powershell cmdlet - win_shell: Write-Output "hello from Ansible" - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - - shellout.cmd == 'Write-Output "hello from Ansible"' - - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.rc == 0 - - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - # assertion disabled since it does not pass on Windows Server 2016 - # - shellout.stderr == "" - - shellout.stdout == "hello from Ansible\r\n" - - shellout.stdout_lines == ["hello from Ansible"] - -- name: execute a powershell cmdlet with multi-line output that uses environment with embedded quotes - win_shell: Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"; Write-Output "envvar was $env:taskvar" - environment: - taskvar: "o'doyle rules" - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - - shellout.cmd == 'Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"; Write-Output "envvar was $env:taskvar"' - - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.rc == 0 - - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - # assertion disabled since it does not pass on Windows Server 2016 - # - shellout.stderr == "" - - shellout.stdout == "hello from Ansible\r\nanother line\r\nyet another line\r\nenvvar was o'doyle rules\r\n" - - shellout.stdout_lines == ["hello from Ansible","another line", "yet another line", "envvar was o'doyle rules"] - -- name: execute something nonexistent - win_shell: bogus_command1234 - register: shellout - ignore_errors: true - -- name: validate result - assert: - that: - - shellout is failed - - shellout.failed == true # check the failure key explicitly, since failed does magic with RC - - shellout is changed - - shellout.cmd == 'bogus_command1234' - - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.rc == 1 - - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.stderr is search('not recognized') - - shellout.stdout == "" - - shellout.stdout_lines == [] - -- name: execute something with error output - win_shell: Write-Error "it broke"; Write-Output "some output" - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - - shellout.cmd == 'Write-Error "it broke"; Write-Output "some output"' - - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.rc == 0 - - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - - shellout.stderr is search('it broke') - - shellout.stdout == "some output\r\n" - - shellout.stdout_lines == ["some output"] - -- name: ensure test file is absent - win_file: - path: c:\testfile.txt - state: absent - -- name: run with creates, should create - win_shell: echo $null >> c:\testfile.txt - args: - creates: c:\testfile.txt - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - -- name: run again with creates, should skip - win_shell: echo $null >> c:\testfile.txt - args: - creates: c:\testfile.txt - register: shellout - -- name: validate result - assert: - that: - - shellout is skipped - - shellout.msg is search('exists') - -- name: get path of pagefile - win_shell: | - $pagefile = $null - $cs = Get-CimInstance -ClassName Win32_ComputerSystem - if ($cs.AutomaticManagedPagefile) { - $pagefile = "$($env:SystemRoot.Substring(0, 1)):\pagefile.sys" - } else { - $pf = Get-CimInstance -ClassName Win32_PageFileSetting - if ($pf -ne $null) { - $pagefile = $pf[0].Name - } - } - $pagefile - register: pagefile_path - -- name: test creates with hidden system file, should skip - win_shell: echo test - args: - creates: '{{pagefile_path.stdout_lines[0]}}' - register: shellout - when: pagefile_path.stdout_lines|count != 0 - -- name: validate result - assert: - that: - - shellout is skipped - - shellout.msg is search('exists') - when: pagefile_path.stdout_lines|count != 0 - -- name: ensure testfile is still present - win_stat: - path: c:\testfile.txt - register: statout - -- name: validate result - assert: - that: - - statout.stat.exists == true - -# https://github.com/ansible/ansible/issues/37967 -- name: test creates with file in missing directory - win_shell: echo hi - args: - creates: c:\fakefolder\fakefolder2\fakefile.txt - register: shellout - -- name: validate result - assert: - that: - - shellout.skipped is not defined - - shellout.changed - -- name: run with removes, should remove - win_shell: Remove-Item c:\testfile.txt - args: - removes: c:\testfile.txt - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - -- name: run again with removes, should skip - win_shell: echo $null >> c:\testfile.txt - args: - removes: c:\testfile.txt - register: shellout - -- name: validate result - assert: - that: - - shellout is skipped - - shellout.msg is search('does not exist') - -- name: run something with known nonzero exit code - win_shell: exit 254 - register: shellout - ignore_errors: true - -- name: validate result - assert: - that: - - shellout is failed - - shellout.failed == True # check the failure key explicitly, since failed does magic with RC - - shellout.rc == 254 - -- name: run something via cmd that will fail in powershell - win_shell: echo line1 & echo.line2 - args: - executable: cmd - register: shellout - -- name: validate result - assert: - that: - - shellout is successful - - shellout is changed - - shellout.rc == 0 - - shellout.stdout == "line1 \r\nline2\r\n" - - shellout.stdout_lines == ["line1 ", "line2"] - - shellout.stderr == "" - -- name: test with job to ensure that preamble-free InputEncoding is working - win_shell: Start-Job { echo yo } | Receive-Job -Wait - register: shellout - -- name: check job result - assert: - that: - - shellout is successful - - shellout.stdout_lines[0] == 'yo' - -- name: interleave large writes between stdout/stderr (check for buffer consumption deadlock) - win_shell: $ba = New-Object byte[] 4096; (New-Object System.Random 32).NextBytes($ba); $text = [Convert]::ToBase64String($ba); Write-Output startout; Write-Error starterror; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Output doneout Write-Error doneerror - register: shellout - -- name: ensure that the entirety of both streams were read - assert: - that: - - shellout.stdout is search("startout") - - shellout.stdout is search("doneout") - - shellout.stderr is search("starterror") - - shellout.stderr is search("doneerror") - -- name: run stdin test - win_shell: '$string = [Console]::In.ReadToEnd(); Write-Output $string.Trim()' - args: - stdin: some input - register: shellout - -- name: assert run stdin test - assert: - that: - - shellout is changed - - shellout.rc == 0 - - shellout.stderr == "" - - shellout.stdout == "some input\r\n" - -- name: echo some non ascii characters - win_shell: Write-Host über den Fußgängerübergang gehen - register: nonascii_output - -- name: assert echo some non ascii characters - assert: - that: - - nonascii_output is changed - - nonascii_output.rc == 0 - - nonascii_output.stdout_lines|count == 1 - - nonascii_output.stdout_lines[0] == 'über den Fußgängerübergang gehen' - - nonascii_output.stderr == '' - -- name: echo some non ascii characters with us-ascii output encoding - win_shell: Write-Host über den Fußgängerübergang gehen - args: - output_encoding_override: us-ascii - register: nonascii_output_us_ascii_encoding - -- name: assert echo some non ascii characters with us-ascii output encoding - assert: - that: - - nonascii_output_us_ascii_encoding is changed - - nonascii_output_us_ascii_encoding.rc == 0 - - nonascii_output_us_ascii_encoding.stdout_lines|count == 1 - - nonascii_output_us_ascii_encoding.stdout_lines[0] == '??ber den Fu??g??nger??bergang gehen' - - nonascii_output_us_ascii_encoding.stderr == '' - -- name: execute powershell without no_profile - win_shell: '[System.Environment]::CommandLine' - register: no_profile - -- name: assert execute powershell with no_profile - assert: - that: - - no_profile is successful - - no_profile is changed - - no_profile.cmd == "[System.Environment]::CommandLine" - - no_profile.rc == 0 - - no_profile.stdout is match ('^"powershell.exe" -noninteractive -encodedcommand') - -- name: execute powershell with no_profile - win_shell: '[System.Environment]::CommandLine' - args: - no_profile: yes - register: no_profile - -- name: assert execute powershell with no_profile - assert: - that: - - no_profile is successful - - no_profile is changed - - no_profile.cmd == "[System.Environment]::CommandLine" - - no_profile.rc == 0 - - no_profile.stdout is match ('^"powershell.exe" -noprofile -noninteractive -encodedcommand') - -- name: create symbolic link with space in the path - win_command: cmd.exe /c mklink /d "C:\ansible test link" C:\Windows\System32\WindowsPowerShell\v1.0 - args: - creates: C:\ansible test link - -- block: - - name: run with space in the executable path - win_shell: '[System.Environment]::CommandLine' - args: - executable: C:\ansible test link\powershell - register: space_exe - - - debug: - var: space_exe.stdout|trim - - - name: assert run with space in the executable path - assert: - that: - - space_exe is successful - - space_exe is changed - - space_exe.cmd == '[System.Environment]::CommandLine' - - space_exe.rc == 0 - - space_exe.stdout|trim == '"C:\\ansible test link\\powershell.exe" /c [System.Environment]::CommandLine' - always: - - name: remove test symbolic link - win_file: - path: C:\ansible test link - state: absent diff --git a/test/integration/targets/win_slurp/aliases b/test/integration/targets/win_slurp/aliases deleted file mode 100644 index 423ce39108..0000000000 --- a/test/integration/targets/win_slurp/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_slurp/defaults/main.yml b/test/integration/targets/win_slurp/defaults/main.yml deleted file mode 100644 index a229fef968..0000000000 --- a/test/integration/targets/win_slurp/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_win_slurp_dir: C:\ansible\win_slurp .ÅÑŚÌβŁÈ [$!@^&test(;)]
\ No newline at end of file diff --git a/test/integration/targets/win_slurp/handlers/main.yml b/test/integration/targets/win_slurp/handlers/main.yml deleted file mode 100644 index ced20a405c..0000000000 --- a/test/integration/targets/win_slurp/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: remove test directory - win_file: - path: '{{ test_win_slurp_dir }}' - state: absent diff --git a/test/integration/targets/win_slurp/tasks/main.yml b/test/integration/targets/win_slurp/tasks/main.yml deleted file mode 100644 index 1956c8a899..0000000000 --- a/test/integration/targets/win_slurp/tasks/main.yml +++ /dev/null @@ -1,97 +0,0 @@ -# test code for the slurp module when using winrm connection -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: create test directory - win_file: - path: '{{ test_win_slurp_dir }}' - state: directory - notify: remove test directory - -# removes reliance on win_copy, set back once win_copy supports glob like chars -- name: create test file - win_shell: | - $file = '{{ test_win_slurp_dir }}\slurp.txt' - if (Test-Path -LiteralPath $file) { - Remove-Item -LiteralPath $file -Force - } - Set-Content -LiteralPath $file -Value 'Slurp this!' - -- name: test slurping an existing file - slurp: - src: '{{ test_win_slurp_dir }}\slurp.txt' - register: slurp_existing - -- name: check slurp existing result - assert: - that: - - "slurp_existing.content == 'U2x1cnAgdGhpcyENCg=='" - - "slurp_existing.encoding == 'base64'" - - "slurp_existing is not changed" - - "slurp_existing is not failed" - -- name: test slurping a large binary file with path param and backslashes - slurp: - path: C:\Windows\explorer.exe - register: slurp_path_backslashes - no_log: true - -- name: check slurp result with path param and backslashes - assert: - that: - - "slurp_path_backslashes.content" - - "slurp_path_backslashes.encoding == 'base64'" - - "slurp_path_backslashes is not changed" - - "slurp_path_backslashes is not failed" - -- name: test slurping a non-existent file - slurp: - src: C:\this_file_should_not_exist.txt - register: slurp_missing - ignore_errors: true - -- name: check slurp missing result - assert: - that: - - "slurp_missing is failed" - - "slurp_missing.msg" - - "slurp_missing is not changed" - -- name: test slurping a directory - slurp: - src: '{{ test_win_slurp_dir }}\missing' - register: slurp_dir - ignore_errors: true - -- name: check slurp directory result - assert: - that: - - "slurp_dir is failed" - - "slurp_dir.msg" - - "slurp_dir is not changed" - -- name: test slurp with missing argument - action: slurp - register: slurp_no_args - ignore_errors: true - -- name: check slurp with missing argument result - assert: - that: - - "slurp_no_args is failed" - - "slurp_no_args.msg" - - "slurp_no_args is not changed" diff --git a/test/integration/targets/win_stat/aliases b/test/integration/targets/win_stat/aliases deleted file mode 100644 index 215e0b0692..0000000000 --- a/test/integration/targets/win_stat/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group4 diff --git a/test/integration/targets/win_stat/defaults/main.yml b/test/integration/targets/win_stat/defaults/main.yml deleted file mode 100644 index 9facc62557..0000000000 --- a/test/integration/targets/win_stat/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -win_stat_dir: '{{win_output_dir}}\win_stat' -win_stat_user: test-stat diff --git a/test/integration/targets/win_stat/library/test_symlink_file.ps1 b/test/integration/targets/win_stat/library/test_symlink_file.ps1 deleted file mode 100644 index 39f1f46afc..0000000000 --- a/test/integration/targets/win_stat/library/test_symlink_file.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -#!powershell - -#Requires -Module Ansible.ModuleUtils.Legacy -#Requires -Module Ansible.ModuleUtils.LinkUtil - -$params = Parse-Args $args - -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" -$src = Get-AnsibleParam -obj $params -name "src" -type "path" -failifempty $true -$target = Get-AnsibleParam -obj $params -name "target" -type "path" -failifempty $($state -eq "present") - -$result = @{ - changed = $false -} - -if ($state -eq "absent") { - if (Test-Path -Path $src) { - Load-LinkUtils - Remove-Link -link_path $src - $result.changed = $true - } -} else { - if (-not (Test-Path -Path $src)) { - Load-LinkUtils - New-Link -link_path $src -link_target $target -link_type "link" - $result.changed = $true - } -} - -Exit-Json -obj $result diff --git a/test/integration/targets/win_stat/tasks/main.yml b/test/integration/targets/win_stat/tasks/main.yml deleted file mode 100644 index a016cde655..0000000000 --- a/test/integration/targets/win_stat/tasks/main.yml +++ /dev/null @@ -1,115 +0,0 @@ -- name: make sure symlink file does not exist - test_symlink_file: - src: '{{win_stat_dir}}\file-link.txt' - state: absent - -- name: remove win_stat testing directories for clean slate - win_file: - path: '{{win_stat_dir}}' - state: absent - -# while most of the setup can be done with modules, it is quicker to do them -# all in bulk than with with_items to save each round trip over WinRM -- name: set test files and folders - win_shell: | - $ErrorActionPreference = "Stop" - $directories = @( - "folder", - "folder space", - "nested\nested", - "shared", - "hidden", - "link-dest", - "junction-dest" - ) - - foreach ($directory in $directories) { - New-Item -Path "{{win_stat_dir}}\$directory" -ItemType Directory - } - - $normal_content = "abc" - $normal_files = @( - "nested\file.ps1", - "nested\hard-target.txt", - "nested\read-only.ps1", - "nested\archive.ps1", - "nested\hidden.ps1", - "nested\nested\file.ps1", - "folder space\file.ps1", - "link-dest\file.txt" - ) - foreach ($file in $normal_files) { - New-Item -Path "{{win_stat_dir}}\$file" -ItemType File - [System.IO.File]::WriteAllText("{{win_stat_dir}}\$file", $normal_content) - } - - $share_stat = Get-WmiObject -Class Win32_Share -Filter "name='folder-share'" - if ($share_stat) { - $share_stat.Delete() - } - $wmi = [wmiClass] 'Win32_Share' - $wmi.Create("{{win_stat_dir}}\shared", "folder-share", 0) - - cmd.exe /c mklink /D "{{win_stat_dir}}\link" "{{win_stat_dir}}\link-dest" - cmd.exe /c mklink /H "{{win_stat_dir}}\nested\hard-link.ps1" "{{win_stat_dir}}\nested\hard-target.txt" - cmd.exe /c mklink /J "{{win_stat_dir}}\junction-link" "{{win_stat_dir}}\junction-dest" - cmd.exe /c mklink /D "{{win_stat_dir}}\nested\nested\link-rel" "..\..\link-dest" - cmd.exe /c mklink /D "{{win_stat_dir}}\outer-link" "{{win_stat_dir}}\nested\nested\link-rel" - - $date = Get-Date -Year 2016 -Month 11 -Day 1 -Hour 7 -Minute 10 -Second 5 -Millisecond 0 - Get-ChildItem -Path "{{win_stat_dir}}" -Recurse | ForEach-Object { - $_.CreationTime = $date - $_.LastAccessTime = $date - $_.LastWriteTime = $date - } - - $attributes = @{ - "hidden" = "Hidden" - "nested\read-only.ps1" = "ReadOnly" - "nested\archive.ps1" = "Archive" - "nested\hidden.ps1" = "Hidden" - } - - foreach ($attribute in $attributes.GetEnumerator()) { - $item = Get-Item -Path "{{win_stat_dir}}\$($attribute.Name)" - $file_attributes = $item.Attributes -split ',' - if ($file_attributes -notcontains $attribute.Value) { - $file_attributes += $attribute.Value - } - $item.Attributes = $file_attributes -join ',' - } - - # weird issue, need to access the file in anyway to get the correct date stats - Test-Path {{win_stat_dir}}\nested\hard-link.ps1 - -# mklink.exe and win_file cannot do this right now so we need a custom module -- name: create file symlink - test_symlink_file: - src: '{{win_stat_dir}}\file-link.txt' - target: '{{win_stat_dir}}\nested\file.ps1' - state: present - -- block: - - include_tasks: tests.yml - - always: - - name: make sure symlink file does not exist - test_symlink_file: - src: '{{win_stat_dir}}\file-link.txt' - state: absent - - - name: remove testing folder - win_file: - path: '{{win_stat_dir}}' - state: absent - - - name: ensure test user is deleted - win_user: - name: '{{win_stat_user}}' - state: absent - - - name: ensure test user profile is deleted - win_shell: rmdir /S /Q {{profile_dir_out.stdout_lines[0]}} - args: - executable: cmd.exe - when: win_stat_user in profile_dir_out.stdout_lines[0] diff --git a/test/integration/targets/win_stat/tasks/tests.yml b/test/integration/targets/win_stat/tasks/tests.yml deleted file mode 100644 index 2d690b9823..0000000000 --- a/test/integration/targets/win_stat/tasks/tests.yml +++ /dev/null @@ -1,646 +0,0 @@ ---- -- name: test win_stat module on file - win_stat: - path: '{{win_stat_dir}}\nested\file.ps1' - register: stat_file - -- name: check actual for file - assert: - that: - - stat_file.stat.attributes == 'Archive' - - stat_file.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_file.stat.creationtime == 1477984205 - - stat_file.stat.exists == True - - stat_file.stat.extension == '.ps1' - - stat_file.stat.filename == 'file.ps1' - - stat_file.stat.hlnk_targets == [] - - stat_file.stat.isarchive == True - - stat_file.stat.isdir == False - - stat_file.stat.ishidden == False - - stat_file.stat.isjunction == False - - stat_file.stat.islnk == False - - stat_file.stat.isreadonly == False - - stat_file.stat.isreg == True - - stat_file.stat.isshared == False - - stat_file.stat.lastaccesstime == 1477984205 - - stat_file.stat.lastwritetime == 1477984205 - - stat_file.stat.nlink == 1 - - stat_file.stat.owner == 'BUILTIN\Administrators' - - stat_file.stat.path == win_stat_dir + '\\nested\\file.ps1' - - stat_file.stat.size == 3 - -- name: test win_stat module on file with sha256 - win_stat: - path: '{{win_stat_dir}}\nested\file.ps1' - checksum_algorithm: sha256 - register: stat_file_sha256 - -- name: check actual for file with sha256 - assert: - that: - - stat_file_sha256.stat.checksum == 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad' - -- name: test win_stat module on file with sha384 - win_stat: - path: '{{win_stat_dir}}\nested\file.ps1' - checksum_algorithm: sha384 - register: stat_file_sha384 - -- name: check actual for file with sha384 - assert: - that: - - stat_file_sha384.stat.checksum == 'cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7' - -- name: test win_stat module on file with sha512 - win_stat: - path: '{{win_stat_dir}}\nested\file.ps1' - checksum_algorithm: sha512 - register: stat_file_sha512 - -- name: check actual for file with sha512 - assert: - that: - - stat_file_sha512.stat.checksum == 'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f' - -- name: test win_stat on hidden file - win_stat: - path: '{{win_stat_dir}}\nested\hidden.ps1' - register: stat_file_hidden - -- name: check actual for hidden file - assert: - that: - - stat_file_hidden.stat.attributes == 'Hidden, Archive' - - stat_file_hidden.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_file_hidden.stat.creationtime == 1477984205 - - stat_file_hidden.stat.exists == True - - stat_file_hidden.stat.extension == '.ps1' - - stat_file_hidden.stat.filename == 'hidden.ps1' - - stat_file_hidden.stat.hlnk_targets == [] - - stat_file_hidden.stat.isarchive == True - - stat_file_hidden.stat.isdir == False - - stat_file_hidden.stat.ishidden == True - - stat_file_hidden.stat.isjunction == False - - stat_file_hidden.stat.islnk == False - - stat_file_hidden.stat.isreadonly == False - - stat_file_hidden.stat.isreg == True - - stat_file_hidden.stat.isshared == False - - stat_file_hidden.stat.lastaccesstime == 1477984205 - - stat_file_hidden.stat.lastwritetime == 1477984205 - - stat_file_hidden.stat.nlink == 1 - - stat_file_hidden.stat.owner == 'BUILTIN\Administrators' - - stat_file_hidden.stat.path == win_stat_dir + '\\nested\\hidden.ps1' - - stat_file_hidden.stat.size == 3 - -- name: test win_stat on readonly file - win_stat: - path: '{{win_stat_dir}}\nested\read-only.ps1' - register: stat_readonly - -- name: check actual for readonly file - assert: - that: - - stat_readonly.stat.attributes == 'ReadOnly, Archive' - - stat_readonly.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_readonly.stat.creationtime == 1477984205 - - stat_readonly.stat.exists == True - - stat_readonly.stat.extension == '.ps1' - - stat_readonly.stat.filename == 'read-only.ps1' - - stat_readonly.stat.hlnk_targets == [] - - stat_readonly.stat.isarchive == True - - stat_readonly.stat.isdir == False - - stat_readonly.stat.ishidden == False - - stat_readonly.stat.isjunction == False - - stat_readonly.stat.islnk == False - - stat_readonly.stat.isreadonly == True - - stat_readonly.stat.isreg == True - - stat_readonly.stat.isshared == False - - stat_readonly.stat.lastaccesstime == 1477984205 - - stat_readonly.stat.lastwritetime == 1477984205 - - stat_readonly.stat.nlink == 1 - - stat_readonly.stat.owner == 'BUILTIN\Administrators' - - stat_readonly.stat.path == win_stat_dir + '\\nested\\read-only.ps1' - - stat_readonly.stat.size == 3 - -- name: test win_stat on hard link file - win_stat: - path: '{{win_stat_dir}}\nested\hard-link.ps1' - follow: True # just verifies we don't do any weird follow logic for hard links - register: stat_hard_link - -- name: check actual for hard link file - assert: - that: - - stat_hard_link.stat.attributes == 'Archive' - - stat_hard_link.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_hard_link.stat.creationtime == 1477984205 - - stat_hard_link.stat.exists == True - - stat_hard_link.stat.extension == '.ps1' - - stat_hard_link.stat.filename == 'hard-link.ps1' - - stat_hard_link.stat.hlnk_targets == [ win_stat_dir + '\\nested\hard-target.txt' ] - - stat_hard_link.stat.isarchive == True - - stat_hard_link.stat.isdir == False - - stat_hard_link.stat.ishidden == False - - stat_hard_link.stat.isjunction == False - - stat_hard_link.stat.islnk == False - - stat_hard_link.stat.isreadonly == False - - stat_hard_link.stat.isshared == False - - stat_hard_link.stat.lastaccesstime == 1477984205 - - stat_hard_link.stat.lastwritetime == 1477984205 - - stat_hard_link.stat.nlink == 2 - - stat_hard_link.stat.owner == 'BUILTIN\Administrators' - - stat_hard_link.stat.path == win_stat_dir + '\\nested\\hard-link.ps1' - - stat_hard_link.stat.size == 3 - -- name: test win_stat on directory - win_stat: - path: '{{win_stat_dir}}\nested' - register: stat_directory - -- name: check actual for directory - assert: - that: - - stat_directory.stat.attributes == 'Directory' - - stat_directory.stat.checksum is not defined - - stat_directory.stat.creationtime == 1477984205 - - stat_directory.stat.exists == True - - stat_directory.stat.extension is not defined - - stat_directory.stat.filename == 'nested' - - stat_directory.stat.hlnk_targets == [] - - stat_directory.stat.isarchive == False - - stat_directory.stat.isdir == True - - stat_directory.stat.ishidden == False - - stat_directory.stat.isjunction == False - - stat_directory.stat.islnk == False - - stat_directory.stat.isreadonly == False - - stat_directory.stat.isreg == False - - stat_directory.stat.isshared == False - - stat_directory.stat.lastaccesstime == 1477984205 - - stat_directory.stat.lastwritetime == 1477984205 - - stat_directory.stat.nlink == 1 - - stat_directory.stat.owner == 'BUILTIN\Administrators' - - stat_directory.stat.path == win_stat_dir + '\\nested' - - stat_directory.stat.size == 24 - -- name: test win_stat on empty directory - win_stat: - path: '{{win_stat_dir}}\folder' - register: stat_directory_empty - -- name: check actual for empty directory - assert: - that: - - stat_directory_empty.stat.attributes == 'Directory' - - stat_directory_empty.stat.checksum is not defined - - stat_directory_empty.stat.creationtime == 1477984205 - - stat_directory_empty.stat.exists == True - - stat_directory_empty.stat.extension is not defined - - stat_directory_empty.stat.filename == 'folder' - - stat_directory_empty.stat.hlnk_targets == [] - - stat_directory_empty.stat.isarchive == False - - stat_directory_empty.stat.isdir == True - - stat_directory_empty.stat.ishidden == False - - stat_directory_empty.stat.isjunction == False - - stat_directory_empty.stat.islnk == False - - stat_directory_empty.stat.isreadonly == False - - stat_directory_empty.stat.isreg == False - - stat_directory_empty.stat.isshared == False - - stat_directory_empty.stat.lastaccesstime == 1477984205 - - stat_directory_empty.stat.lastwritetime == 1477984205 - - stat_directory_empty.stat.nlink == 1 - - stat_directory_empty.stat.owner == 'BUILTIN\Administrators' - - stat_directory_empty.stat.path == win_stat_dir + '\\folder' - - stat_directory_empty.stat.size == 0 - -- name: test win_stat on directory with space in name - win_stat: - path: '{{win_stat_dir}}\folder space' - register: stat_directory_space - -- name: check actual for directory with space in name - assert: - that: - - stat_directory_space.stat.attributes == 'Directory' - - stat_directory_space.stat.checksum is not defined - - stat_directory_space.stat.creationtime == 1477984205 - - stat_directory_space.stat.exists == True - - stat_directory_space.stat.extension is not defined - - stat_directory_space.stat.filename == 'folder space' - - stat_directory_space.stat.hlnk_targets == [] - - stat_directory_space.stat.isarchive == False - - stat_directory_space.stat.isdir == True - - stat_directory_space.stat.ishidden == False - - stat_directory_space.stat.isjunction == False - - stat_directory_space.stat.islnk == False - - stat_directory_space.stat.isreadonly == False - - stat_directory_space.stat.isreg == False - - stat_directory_space.stat.isshared == False - - stat_directory_space.stat.lastaccesstime == 1477984205 - - stat_directory_space.stat.lastwritetime == 1477984205 - - stat_directory_space.stat.nlink == 1 - - stat_directory_space.stat.owner == 'BUILTIN\Administrators' - - stat_directory_space.stat.path == win_stat_dir + '\\folder space' - - stat_directory_space.stat.size == 3 - -- name: test win_stat on hidden directory - win_stat: - path: '{{win_stat_dir}}\hidden' - register: stat_hidden - -- name: check actual for hidden directory - assert: - that: - - stat_hidden.stat.attributes == 'Hidden, Directory' - - stat_hidden.stat.checksum is not defined - - stat_hidden.stat.creationtime == 1477984205 - - stat_hidden.stat.exists == True - - stat_hidden.stat.extension is not defined - - stat_hidden.stat.filename == 'hidden' - - stat_hidden.stat.hlnk_targets == [] - - stat_hidden.stat.isarchive == False - - stat_hidden.stat.isdir == True - - stat_hidden.stat.ishidden == True - - stat_hidden.stat.isjunction == False - - stat_hidden.stat.islnk == False - - stat_hidden.stat.isreadonly == False - - stat_hidden.stat.isreg == False - - stat_hidden.stat.isshared == False - - stat_hidden.stat.lastaccesstime == 1477984205 - - stat_hidden.stat.lastwritetime == 1477984205 - - stat_hidden.stat.nlink == 1 - - stat_hidden.stat.owner == 'BUILTIN\Administrators' - - stat_hidden.stat.path == win_stat_dir + '\\hidden' - - stat_hidden.stat.size == 0 - -- name: test win_stat on shared directory - win_stat: - path: '{{win_stat_dir}}\shared' - register: stat_shared - -- name: check actual for shared directory - assert: - that: - - stat_shared.stat.attributes == 'Directory' - - stat_shared.stat.checksum is not defined - - stat_shared.stat.creationtime == 1477984205 - - stat_shared.stat.exists == True - - stat_shared.stat.extension is not defined - - stat_shared.stat.filename == 'shared' - - stat_shared.stat.hlnk_targets == [] - - stat_shared.stat.isarchive == False - - stat_shared.stat.isdir == True - - stat_shared.stat.ishidden == False - - stat_shared.stat.isjunction == False - - stat_shared.stat.islnk == False - - stat_shared.stat.isreadonly == False - - stat_shared.stat.isreg == False - - stat_shared.stat.isshared == True - - stat_shared.stat.lastaccesstime == 1477984205 - - stat_shared.stat.lastwritetime == 1477984205 - - stat_shared.stat.nlink == 1 - - stat_shared.stat.owner == 'BUILTIN\Administrators' - - stat_shared.stat.path == win_stat_dir + '\\shared' - - stat_shared.stat.sharename == 'folder-share' - - stat_shared.stat.size == 0 - -- name: test win_stat on directory symlink - win_stat: - path: '{{win_stat_dir}}\link' - register: stat_symlink - -- name: assert directory symlink actual - assert: - that: - - stat_symlink.stat.attributes == 'Directory, ReparsePoint' - - stat_symlink.stat.creationtime is defined - - stat_symlink.stat.exists == True - - stat_symlink.stat.filename == 'link' - - stat_symlink.stat.hlnk_targets == [] - - stat_symlink.stat.isarchive == False - - stat_symlink.stat.isdir == True - - stat_symlink.stat.ishidden == False - - stat_symlink.stat.islnk == True - - stat_symlink.stat.isjunction == False - - stat_symlink.stat.isreadonly == False - - stat_symlink.stat.isreg == False - - stat_symlink.stat.isshared == False - - stat_symlink.stat.lastaccesstime is defined - - stat_symlink.stat.lastwritetime is defined - - stat_symlink.stat.lnk_source == win_stat_dir + '\\link-dest' - - stat_symlink.stat.lnk_target == win_stat_dir + '\\link-dest' - - stat_symlink.stat.nlink == 1 - - stat_symlink.stat.owner == 'BUILTIN\\Administrators' - - stat_symlink.stat.path == win_stat_dir + '\\link' - - stat_symlink.stat.checksum is not defined - -- name: test win_stat on file symlink - win_stat: - path: '{{win_stat_dir}}\file-link.txt' - register: stat_file_symlink - -- name: assert file symlink actual - assert: - that: - - stat_file_symlink.stat.attributes == 'Archive, ReparsePoint' - - stat_file_symlink.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_file_symlink.stat.creationtime is defined - - stat_file_symlink.stat.exists == True - - stat_file_symlink.stat.extension == '.txt' - - stat_file_symlink.stat.filename == 'file-link.txt' - - stat_file_symlink.stat.hlnk_targets == [] - - stat_file_symlink.stat.isarchive == True - - stat_file_symlink.stat.isdir == False - - stat_file_symlink.stat.ishidden == False - - stat_file_symlink.stat.isjunction == False - - stat_file_symlink.stat.islnk == True - - stat_file_symlink.stat.isreadonly == False - - stat_file_symlink.stat.isreg == False - - stat_file_symlink.stat.isshared == False - - stat_file_symlink.stat.lastaccesstime is defined - - stat_file_symlink.stat.lastwritetime is defined - - stat_file_symlink.stat.lnk_source == win_stat_dir + '\\nested\\file.ps1' - - stat_file_symlink.stat.lnk_target == win_stat_dir + '\\nested\\file.ps1' - - stat_file_symlink.stat.nlink == 1 - - stat_file_symlink.stat.owner == 'BUILTIN\\Administrators' - - stat_file_symlink.stat.path == win_stat_dir + '\\file-link.txt' - -- name: test win_stat of file symlink with follow - win_stat: - path: '{{win_stat_dir}}\file-link.txt' - follow: True - register: stat_file_symlink_follow - -- name: assert file system with follow actual - assert: - that: - - stat_file_symlink_follow.stat.attributes == 'Archive' - - stat_file_symlink_follow.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - stat_file_symlink_follow.stat.creationtime is defined - - stat_file_symlink_follow.stat.exists == True - - stat_file_symlink_follow.stat.extension == '.ps1' - - stat_file_symlink_follow.stat.filename == 'file.ps1' - - stat_file_symlink_follow.stat.hlnk_targets == [] - - stat_file_symlink_follow.stat.isarchive == True - - stat_file_symlink_follow.stat.isdir == False - - stat_file_symlink_follow.stat.ishidden == False - - stat_file_symlink_follow.stat.isjunction == False - - stat_file_symlink_follow.stat.islnk == False - - stat_file_symlink_follow.stat.isreadonly == False - - stat_file_symlink_follow.stat.isreg == True - - stat_file_symlink_follow.stat.isshared == False - - stat_file_symlink_follow.stat.lastaccesstime is defined - - stat_file_symlink_follow.stat.lastwritetime is defined - - stat_file_symlink_follow.stat.nlink == 1 - - stat_file_symlink_follow.stat.owner == 'BUILTIN\\Administrators' - - stat_file_symlink_follow.stat.path == win_stat_dir + '\\nested\\file.ps1' - -- name: test win_stat on relative symlink - win_stat: - path: '{{win_stat_dir}}\nested\nested\link-rel' - register: stat_rel_symlink - -- name: assert directory relative symlink actual - assert: - that: - - stat_rel_symlink.stat.attributes == 'Directory, ReparsePoint' - - stat_rel_symlink.stat.creationtime is defined - - stat_rel_symlink.stat.exists == True - - stat_rel_symlink.stat.filename == 'link-rel' - - stat_rel_symlink.stat.hlnk_targets == [] - - stat_rel_symlink.stat.isarchive == False - - stat_rel_symlink.stat.isdir == True - - stat_rel_symlink.stat.ishidden == False - - stat_rel_symlink.stat.isjunction == False - - stat_rel_symlink.stat.islnk == True - - stat_rel_symlink.stat.isreadonly == False - - stat_rel_symlink.stat.isreg == False - - stat_rel_symlink.stat.isshared == False - - stat_rel_symlink.stat.lastaccesstime is defined - - stat_rel_symlink.stat.lastwritetime is defined - - stat_rel_symlink.stat.lnk_source == win_stat_dir + '\\link-dest' - - stat_rel_symlink.stat.lnk_target == '..\\..\\link-dest' - - stat_rel_symlink.stat.nlink == 1 - - stat_rel_symlink.stat.owner == 'BUILTIN\\Administrators' - - stat_rel_symlink.stat.path == win_stat_dir + '\\nested\\nested\\link-rel' - - stat_rel_symlink.stat.checksum is not defined - -- name: test win_stat on relative multiple symlink with follow - win_stat: - path: '{{win_stat_dir}}\outer-link' - follow: True - register: stat_symlink_follow - -- name: assert directory relative symlink actual - assert: - that: - - stat_symlink_follow.stat.attributes == 'Directory' - - stat_symlink_follow.stat.creationtime is defined - - stat_symlink_follow.stat.exists == True - - stat_symlink_follow.stat.filename == 'link-dest' - - stat_symlink_follow.stat.hlnk_targets == [] - - stat_symlink_follow.stat.isarchive == False - - stat_symlink_follow.stat.isdir == True - - stat_symlink_follow.stat.ishidden == False - - stat_symlink_follow.stat.isjunction == False - - stat_symlink_follow.stat.islnk == False - - stat_symlink_follow.stat.isreadonly == False - - stat_symlink_follow.stat.isreg == False - - stat_symlink_follow.stat.isshared == False - - stat_symlink_follow.stat.lastaccesstime is defined - - stat_symlink_follow.stat.lastwritetime is defined - - stat_symlink_follow.stat.nlink == 1 - - stat_symlink_follow.stat.owner == 'BUILTIN\\Administrators' - - stat_symlink_follow.stat.path == win_stat_dir + '\\link-dest' - - stat_symlink_follow.stat.checksum is not defined - -- name: test win_stat on junction - win_stat: - path: '{{win_stat_dir}}\junction-link' - register: stat_junction_point - -- name: assert junction actual - assert: - that: - - stat_junction_point.stat.attributes == 'Directory, ReparsePoint' - - stat_junction_point.stat.creationtime is defined - - stat_junction_point.stat.exists == True - - stat_junction_point.stat.filename == 'junction-link' - - stat_junction_point.stat.hlnk_targets == [] - - stat_junction_point.stat.isarchive == False - - stat_junction_point.stat.isdir == True - - stat_junction_point.stat.ishidden == False - - stat_junction_point.stat.isjunction == True - - stat_junction_point.stat.islnk == False - - stat_junction_point.stat.isreadonly == False - - stat_junction_point.stat.isreg == False - - stat_junction_point.stat.isshared == False - - stat_junction_point.stat.lastaccesstime is defined - - stat_junction_point.stat.lastwritetime is defined - - stat_junction_point.stat.lnk_source == win_stat_dir + '\\junction-dest' - - stat_junction_point.stat.lnk_target == win_stat_dir + '\\junction-dest' - - stat_junction_point.stat.nlink == 1 - - stat_junction_point.stat.owner == 'BUILTIN\\Administrators' - - stat_junction_point.stat.path == win_stat_dir + '\\junction-link' - - stat_junction_point.stat.size == 0 - -- name: test win_stat on junction with follow - win_stat: - path: '{{win_stat_dir}}\junction-link' - follow: True - register: stat_junction_point_follow - -- name: assert junction with follow actual - assert: - that: - - stat_junction_point_follow.stat.attributes == 'Directory' - - stat_junction_point_follow.stat.creationtime is defined - - stat_junction_point_follow.stat.exists == True - - stat_junction_point_follow.stat.filename == 'junction-dest' - - stat_junction_point_follow.stat.hlnk_targets == [] - - stat_junction_point_follow.stat.isarchive == False - - stat_junction_point_follow.stat.isdir == True - - stat_junction_point_follow.stat.ishidden == False - - stat_junction_point_follow.stat.isjunction == False - - stat_junction_point_follow.stat.islnk == False - - stat_junction_point_follow.stat.isreadonly == False - - stat_junction_point_follow.stat.isreg == False - - stat_junction_point_follow.stat.isshared == False - - stat_junction_point_follow.stat.lastaccesstime is defined - - stat_junction_point_follow.stat.lastwritetime is defined - - stat_junction_point_follow.stat.nlink == 1 - - stat_junction_point_follow.stat.owner == 'BUILTIN\\Administrators' - - stat_junction_point_follow.stat.path == win_stat_dir + '\\junction-dest' - - stat_junction_point_follow.stat.size == 0 - -- name: test win_stat module non-existent path - win_stat: - path: '{{win_stat_dir}}\this_file_should_not_exist' - register: win_stat_missing - -- name: check win_stat missing result - assert: - that: - - not win_stat_missing.stat.exists - - win_stat_missing is not failed - - win_stat_missing is not changed - -- name: test win_stat module without path argument - win_stat: - register: win_stat_no_args - failed_when: "win_stat_no_args.msg != 'missing required arguments: path'" - -# https://github.com/ansible/ansible/issues/30258 -- name: get path of pagefile - win_shell: | - $pagefile = $null - $cs = Get-CimInstance -ClassName Win32_ComputerSystem - if ($cs.AutomaticManagedPagefile) { - $pagefile = "$($env:SystemRoot.Substring(0, 1)):\pagefile.sys" - } else { - $pf = Get-CimInstance -ClassName Win32_PageFileSetting - if ($pf -ne $null) { - $pagefile = $pf[0].Name - } - } - $pagefile - register: pagefile_path - -- name: get stat of pagefile - win_stat: - path: '{{pagefile_path.stdout_lines[0]}}' - get_checksum: no - register: pagefile_stat - when: pagefile_path.stdout_lines|count != 0 - -- name: assert get stat of pagefile - assert: - that: - - pagefile_stat.stat.exists == True - when: pagefile_path.stdout_lines|count != 0 - -# Tests with normal user -- set_fact: - gen_pw: password123! + {{ lookup('password', '/dev/null chars=ascii_letters,digits length=8') }} - -- name: create test user - win_user: - name: '{{win_stat_user}}' - password: '{{gen_pw}}' - update_password: always - groups: Users - -- name: get become user profile dir so we can clean it up later - vars: &become_vars - ansible_become_user: '{{win_stat_user}}' - ansible_become_password: '{{gen_pw}}' - ansible_become_method: runas - ansible_become: yes - win_shell: $env:USERPROFILE - register: profile_dir_out - -- name: ensure profile dir contains test username (eg, if become fails silently, prevent deletion of real user profile) - assert: - that: - - win_stat_user in profile_dir_out.stdout_lines[0] - -- name: test stat with non admin user on a normal file - vars: *become_vars - win_stat: - path: '{{win_stat_dir}}\nested\file.ps1' - register: user_file - -- name: asert test stat with non admin user on a normal file - assert: - that: - - user_file.stat.attributes == 'Archive' - - user_file.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d' - - user_file.stat.creationtime == 1477984205 - - user_file.stat.exists == True - - user_file.stat.extension == '.ps1' - - user_file.stat.filename == 'file.ps1' - - user_file.stat.hlnk_targets == [] - - user_file.stat.isarchive == True - - user_file.stat.isdir == False - - user_file.stat.ishidden == False - - user_file.stat.isjunction == False - - user_file.stat.islnk == False - - user_file.stat.isreadonly == False - - user_file.stat.isreg == True - - user_file.stat.isshared == False - - user_file.stat.lastaccesstime == 1477984205 - - user_file.stat.lastwritetime == 1477984205 - - user_file.stat.nlink == 1 - - user_file.stat.owner == 'BUILTIN\\Administrators' - - user_file.stat.path == win_stat_dir + '\\nested\\file.ps1' - - user_file.stat.size == 3 - -- name: test stat on a symbolic link as normal user - vars: *become_vars - win_stat: - path: '{{win_stat_dir}}\link' - register: user_symlink - -- name: assert test stat on a symbolic link as normal user - assert: - that: - - user_symlink.stat.attributes == 'Directory, ReparsePoint' - - user_symlink.stat.creationtime is defined - - user_symlink.stat.exists == True - - user_symlink.stat.filename == 'link' - - user_symlink.stat.hlnk_targets == [] - - user_symlink.stat.isarchive == False - - user_symlink.stat.isdir == True - - user_symlink.stat.ishidden == False - - user_symlink.stat.islnk == True - - user_symlink.stat.isjunction == False - - user_symlink.stat.isreadonly == False - - user_symlink.stat.isreg == False - - user_symlink.stat.isshared == False - - user_symlink.stat.lastaccesstime is defined - - user_symlink.stat.lastwritetime is defined - - user_symlink.stat.lnk_source == win_stat_dir + '\\link-dest' - - user_symlink.stat.lnk_target == win_stat_dir + '\\link-dest' - - user_symlink.stat.nlink == 1 - - user_symlink.stat.owner == 'BUILTIN\\Administrators' - - user_symlink.stat.path == win_stat_dir + '\\link' - - user_symlink.stat.checksum is not defined diff --git a/test/integration/targets/win_tempfile/aliases b/test/integration/targets/win_tempfile/aliases deleted file mode 100644 index 423ce39108..0000000000 --- a/test/integration/targets/win_tempfile/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group2 diff --git a/test/integration/targets/win_tempfile/defaults/main.yml b/test/integration/targets/win_tempfile/defaults/main.yml deleted file mode 100644 index 824fe00bb1..0000000000 --- a/test/integration/targets/win_tempfile/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_tempfile_path: 'C:\ansible\win_tempfile .ÅÑŚÌβŁÈ [$!@^&test(;)]' diff --git a/test/integration/targets/win_tempfile/tasks/main.yml b/test/integration/targets/win_tempfile/tasks/main.yml deleted file mode 100644 index e989d1ada7..0000000000 --- a/test/integration/targets/win_tempfile/tasks/main.yml +++ /dev/null @@ -1,231 +0,0 @@ ---- -- name: get the current %TEMP% value - win_shell: '[System.IO.Path]::GetFullPath($env:TEMP)' - register: temp_value - -- name: register temp path value - set_fact: - temp_value: '{{ temp_value.stdout | trim }}' - - -- name: get raw %TEMP% value - win_shell: '$env:TEMP' - register: raw_temp_value - -- name: create temp file defaults check - win_tempfile: - register: create_tmp_file_defaults_check - check_mode: True - -- name: get stat of temp file defaults check - win_stat: - path: "{{create_tmp_file_defaults_check.path}}" - register: actual_create_tmp_file_defaults_check - -- name: assert create temp file defaults check - assert: - that: - - create_tmp_file_defaults_check is changed - - create_tmp_file_defaults_check.state == 'file' - - create_tmp_file_defaults_check.path.startswith(temp_value + '\\ansible.') - - actual_create_tmp_file_defaults_check.stat.exists == False - -- name: create temp file defaults - win_tempfile: - register: create_tmp_file_defaults - -- name: get stat of temp file defaults - win_stat: - path: "{{create_tmp_file_defaults.path}}" - register: actual_create_tmp_file_defaults - -- name: assert create temp file defaults - assert: - that: - - create_tmp_file_defaults is changed - - create_tmp_file_defaults.state == 'file' - - create_tmp_file_defaults.path.startswith(temp_value + '\\ansible.') - - actual_create_tmp_file_defaults.stat.exists == True - - actual_create_tmp_file_defaults.stat.isdir == False - -- name: create temp file defaults again - win_tempfile: - register: create_tmp_file_defaults_again - -- name: get stat of temp file defaults again - win_stat: - path: "{{create_tmp_file_defaults_again.path}}" - register: actual_create_tmp_file_defaults_again - -- name: assert create temp file defaults - assert: - that: - - create_tmp_file_defaults_again is changed - - create_tmp_file_defaults_again.state == 'file' - - create_tmp_file_defaults_again.path.startswith(temp_value + '\\ansible.') - - create_tmp_file_defaults_again.path != create_tmp_file_defaults.path - - actual_create_tmp_file_defaults_again.stat.exists == True - - actual_create_tmp_file_defaults_again.stat.isdir == False - -- name: create temp folder check - win_tempfile: - state: directory - register: create_tmp_folder_check - check_mode: True - -- name: get stat of temp folder check - win_stat: - path: "{{create_tmp_folder_check.path}}" - register: actual_create_tmp_folder_check - -- name: assert create temp folder check - assert: - that: - - create_tmp_folder_check is changed - - create_tmp_folder_check.state == 'directory' - - create_tmp_folder_check.path.startswith(temp_value + '\\ansible.') - - actual_create_tmp_folder_check.stat.exists == False - -- name: create temp folder - win_tempfile: - state: directory - register: create_tmp_folder - -- name: get stat of temp folder - win_stat: - path: "{{create_tmp_folder.path}}" - register: actual_create_tmp_folder - -- name: assert create temp folder - assert: - that: - - create_tmp_folder is changed - - create_tmp_folder.state == 'directory' - - create_tmp_folder.path.startswith(temp_value + '\\ansible.') - - actual_create_tmp_folder.stat.exists == True - - actual_create_tmp_folder.stat.isdir == True - -- name: create temp file with suffix - win_tempfile: - suffix: test-suffix - register: create_tmp_file_suffix - -- name: get stat of temp file with suffix - win_stat: - path: "{{create_tmp_file_suffix.path}}" - register: actual_creat_tmp_file_suffix - -- name: assert create temp file with suffix - assert: - that: - - create_tmp_file_suffix is changed - - create_tmp_file_suffix.state == 'file' - - create_tmp_file_suffix.path.startswith(temp_value + '\\ansible.') - - create_tmp_file_suffix.path.endswith('test-suffix') - - actual_creat_tmp_file_suffix.stat.exists == True - - actual_creat_tmp_file_suffix.stat.isdir == False - -- name: create temp file with different prefix - win_tempfile: - prefix: test-prefix - register: create_tmp_file_prefix - -- name: get stat of temp file with prefix - win_stat: - path: "{{create_tmp_file_prefix.path}}" - register: actual_creat_tmp_file_prefix - -- name: assert create temp file with prefix - assert: - that: - - create_tmp_file_prefix is changed - - create_tmp_file_prefix.state == 'file' - - create_tmp_file_prefix.path.startswith(temp_value + '\\test-prefix') - - actual_creat_tmp_file_prefix.stat.exists == True - - actual_creat_tmp_file_prefix.stat.isdir == False - -- name: create new temp file folder - win_file: - path: '{{test_tempfile_path}}\testing folder' - state: directory - -- block: - - name: create temp file with different path - win_tempfile: - path: '{{test_tempfile_path}}\testing folder' - register: create_tmp_file_difference_path - - - name: get stat of temp file with different path - win_stat: - path: "{{create_tmp_file_difference_path.path}}" - register: actual_creat_tmp_file_different_path - - - name: assert create temp file with different path - assert: - that: - - create_tmp_file_difference_path is changed - - create_tmp_file_difference_path.state == 'file' - - create_tmp_file_difference_path.path.startswith(test_tempfile_path + '\\testing folder\\ansible.') - - actual_creat_tmp_file_different_path.stat.exists == True - - actual_creat_tmp_file_different_path.stat.isdir == False - - - name: create temp file with DOS 8.3 short name - win_tempfile: - path: '{{ test_tempfile_path }}\TESTIN~1' - register: create_tmp_file_dos_path - - - name: get stat of temp file with different path - win_stat: - path: '{{ create_tmp_file_dos_path.path }}' - register: actual_create_tmp_file_dos_path - - - name: assert create temp file with different path - assert: - that: - - create_tmp_file_dos_path is changed - - create_tmp_file_dos_path.state == 'file' - - create_tmp_file_dos_path.path.startswith(test_tempfile_path + '\\testing folder\\ansible.') - - actual_create_tmp_file_dos_path.stat.exists == True - - actual_create_tmp_file_dos_path.stat.isdir == False - - always: - - name: delete temp file folder - win_file: - path: "{{test_tempfile_path}}" - state: absent - -- name: get current working directory - win_shell: $pwd.Path - register: current_dir - -- name: create directory for relative dir tests - win_file: - path: '{{ current_dir.stdout | trim }}\win_tempfile' - state: directory - -- block: - - name: create temp folder with relative path - win_tempfile: - path: win_tempfile - state: directory - register: create_relative - - - name: get stat of temp folder with relative path - win_stat: - path: '{{ create_relative.path }}' - register: actual_create_relative - - - name: assert create temp folder with relative path - assert: - that: - - create_relative is changed - - create_relative.state == 'directory' - - create_relative.path.startswith((current_dir.stdout | trim) + '\\win_tempfile\\ansible.') - - actual_create_relative.stat.exists == True - - actual_create_relative.stat.isdir == True - - always: - - name: remove relative directory tests - win_file: - path: '{{ current_dir.stdout | trim }}\win_tempfile' - state: absent diff --git a/test/integration/targets/win_template/aliases b/test/integration/targets/win_template/aliases deleted file mode 100644 index 1eed2ecfaf..0000000000 --- a/test/integration/targets/win_template/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group1 -shippable/windows/smoketest diff --git a/test/integration/targets/win_template/files/foo.dos.txt b/test/integration/targets/win_template/files/foo.dos.txt deleted file mode 100644 index b716eca026..0000000000 --- a/test/integration/targets/win_template/files/foo.dos.txt +++ /dev/null @@ -1,3 +0,0 @@ -BEGIN
-templated_var_loaded
-END
diff --git a/test/integration/targets/win_template/files/foo.unix.txt b/test/integration/targets/win_template/files/foo.unix.txt deleted file mode 100644 index d33849f2b5..0000000000 --- a/test/integration/targets/win_template/files/foo.unix.txt +++ /dev/null @@ -1,3 +0,0 @@ -BEGIN -templated_var_loaded -END diff --git a/test/integration/targets/win_template/meta/main.yml b/test/integration/targets/win_template/meta/main.yml deleted file mode 100644 index d328716dfa..0000000000 --- a/test/integration/targets/win_template/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_win_tests diff --git a/test/integration/targets/win_template/tasks/main.yml b/test/integration/targets/win_template/tasks/main.yml deleted file mode 100644 index 417aa89ab9..0000000000 --- a/test/integration/targets/win_template/tasks/main.yml +++ /dev/null @@ -1,291 +0,0 @@ -# test code for the template module -# (c) 2014, Michael DeHaan <michael.dehaan@gmail.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -# DOS TEMPLATE -- name: fill in a basic template (DOS) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.dos.templated' - register: template_result - -- name: verify that the file was marked as changed (DOS) - assert: - that: - - 'template_result is changed' - -- name: fill in a basic template again (DOS) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.dos.templated' - register: template_result2 - -- name: verify that the template was not changed (DOS) - assert: - that: - - 'template_result2 is not changed' - -# VERIFY DOS CONTENTS -- name: copy known good into place (DOS) - win_copy: - src: foo.dos.txt - dest: '{{ win_output_dir }}\\foo.dos.txt' - -- name: compare templated file to known good (DOS) - raw: fc.exe {{ win_output_dir }}\\foo.dos.templated {{ win_output_dir }}\\foo.dos.txt - register: diff_result - -- debug: - var: diff_result - -- name: verify templated file matches known good (DOS) - assert: - that: - - '"FC: no differences encountered" in diff_result.stdout' - - "diff_result.rc == 0" - -# UNIX TEMPLATE -- name: fill in a basic template (Unix) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.unix.templated' - newline_sequence: '\n' - register: template_result - -- name: verify that the file was marked as changed (Unix) - assert: - that: - - 'template_result is changed' - -- name: fill in a basic template again (Unix) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.unix.templated' - newline_sequence: '\n' - register: template_result2 - -- name: verify that the template was not changed (Unix) - assert: - that: - - 'template_result2 is not changed' - -# VERIFY UNIX CONTENTS -- name: copy known good into place (Unix) - win_copy: - src: foo.unix.txt - dest: '{{ win_output_dir }}\\foo.unix.txt' - -- name: compare templated file to known good (Unix) - raw: fc.exe {{ win_output_dir }}\\foo.unix.templated {{ win_output_dir }}\\foo.unix.txt - register: diff_result - -- debug: - var: diff_result - -- name: verify templated file matches known good (Unix) - assert: - that: - - '"FC: no differences encountered" in diff_result.stdout' - -# VERIFY DOS CONTENTS -- name: copy known good into place (DOS) - win_copy: - src: foo.dos.txt - dest: '{{ win_output_dir }}\\foo.dos.txt' - -- name: compare templated file to known good (DOS) - raw: fc.exe {{ win_output_dir }}\\foo.dos.templated {{ win_output_dir }}\\foo.dos.txt - register: diff_result - -- debug: - var: diff_result - -- name: verify templated file matches known good (DOS) - assert: - that: - - '"FC: no differences encountered" in diff_result.stdout' - -# TEST BACKUP -- name: test backup (check_mode) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.unix.templated' - backup: yes - register: cm_backup_result - check_mode: yes - -- name: verify that a backup_file was returned - assert: - that: - - cm_backup_result is changed - - cm_backup_result.backup_file is not none - -- name: test backup (normal mode) - win_template: - src: foo.j2 - dest: '{{ win_output_dir }}/foo.unix.templated' - backup: yes - register: nm_backup_result - -- name: check backup_file - win_stat: - path: '{{ nm_backup_result.backup_file }}' - register: backup_file - -- name: verify that a backup_file was returned - assert: - that: - - nm_backup_result is changed - - backup_file.stat.exists == true - -- name: create template dest directory - win_file: - path: '{{win_output_dir}}\directory' - state: directory - -- name: template src file to directory with backslash (check mode) - win_template: - src: foo.j2 - dest: '{{win_output_dir}}\directory\' - check_mode: yes - register: template_to_dir_backslash_check - -- name: get result of template src file to directory with backslash (check_mode) - win_stat: - path: '{{win_output_dir}}\directory\foo.j2' - register: template_to_dir_backslash_result_check - -- name: assert template src file to directory with backslash (check mode) - assert: - that: - - template_to_dir_backslash_check is changed - - not template_to_dir_backslash_result_check.stat.exists - -- name: template src file to directory with backslash - win_template: - src: foo.j2 - dest: '{{win_output_dir}}\directory\' - register: template_to_dir_backslash - -- name: get result of template src file to directory with backslash - win_stat: - path: '{{win_output_dir}}\directory\foo.j2' - register: template_to_dir_backslash_result - -- name: assert template src file to directory with backslash - assert: - that: - - template_to_dir_backslash is changed - - template_to_dir_backslash_result.stat.exists - - template_to_dir_backslash_result.stat.checksum == 'ed4f166b2937875ecad39c06648551f5af0b56d3' - -- name: template src file to directory with backslash (idempotent) - win_template: - src: foo.j2 - dest: '{{win_output_dir}}\directory\' - register: template_to_dir_backslash_again - -- name: assert template src file to directory with backslash (idempotent) - assert: - that: - - not template_to_dir_backslash_again is changed - -- name: template src file to directory (check mode) - win_template: - src: another_foo.j2 - dest: '{{win_output_dir}}\directory' - check_mode: yes - register: template_to_dir_check - -- name: get result of template src file to directory (check_mode) - win_stat: - path: '{{win_output_dir}}\directory\another_foo.j2' - register: template_to_dir_result_check - -- name: assert template src file to directory (check mode) - assert: - that: - - template_to_dir_check is changed - - not template_to_dir_result_check.stat.exists - -- name: template src file to directory - win_template: - src: another_foo.j2 - dest: '{{win_output_dir}}\directory' - register: template_to_dir - -- name: get result of template src file to directory - win_stat: - path: '{{win_output_dir}}\directory\another_foo.j2' - register: template_to_dir_result - -- name: assert template src file to directory with - assert: - that: - - template_to_dir is changed - - template_to_dir_result.stat.exists - - template_to_dir_result.stat.checksum == 'b10b6f27290d554a77da2457b2ccd7d6de86b920' - -- name: template src file to directory (idempotent) - win_template: - src: another_foo.j2 - dest: '{{win_output_dir}}\directory' - register: template_to_dir_again - -- name: assert template src file to directory (idempotent) - assert: - that: - - not template_to_dir_again is changed - -- name: template a file with utf-8 encoding - win_template: - src: foo.utf-8.j2 - dest: '{{ win_output_dir }}\foo.encoding.txt' - register: template_utf8 - -- name: slurp utf-8 templated file - slurp: - path: '{{ win_output_dir }}\foo.encoding.txt' - register: template_utf8_actual - -- name: get expected templated contents - set_fact: - expected_content: '{{ lookup("template", "foo.utf-8.j2") | trim }}' - -- name: assert template a file with utf-8 encoding - assert: - that: - - template_utf8 is changed - - template_utf8_actual.content | b64decode(encoding='utf-8') == expected_content + "\r\n" - -- name: template a file with windows-1252 encoding - win_template: - src: foo.utf-8.j2 - dest: '{{ win_output_dir }}\foo.encoding.txt' - output_encoding: windows-1252 - register: template_windows_1252 - -- name: slurp windows-1252 encoding - slurp: - path: '{{ win_output_dir }}\foo.encoding.txt' - register: template_windows_1252_actual - -- name: assert template a file with windows-1252 encoding - assert: - that: - - template_windows_1252 is changed - - template_windows_1252_actual.content | b64decode(encoding='windows-1252') == expected_content + "\r\n" diff --git a/test/integration/targets/win_template/templates/another_foo.j2 b/test/integration/targets/win_template/templates/another_foo.j2 deleted file mode 100644 index 4ee9bca2d7..0000000000 --- a/test/integration/targets/win_template/templates/another_foo.j2 +++ /dev/null @@ -1,3 +0,0 @@ -ABC -{{ templated_var }} -DEF diff --git a/test/integration/targets/win_template/templates/foo.j2 b/test/integration/targets/win_template/templates/foo.j2 deleted file mode 100644 index e6e3485216..0000000000 --- a/test/integration/targets/win_template/templates/foo.j2 +++ /dev/null @@ -1,3 +0,0 @@ -BEGIN -{{ templated_var }} -END diff --git a/test/integration/targets/win_template/templates/foo.utf-8.j2 b/test/integration/targets/win_template/templates/foo.utf-8.j2 deleted file mode 100644 index 65b95669b8..0000000000 --- a/test/integration/targets/win_template/templates/foo.utf-8.j2 +++ /dev/null @@ -1 +0,0 @@ -—café— - {{ templated_var }} diff --git a/test/integration/targets/win_template/templates/foo2.j2 b/test/integration/targets/win_template/templates/foo2.j2 deleted file mode 100644 index 710d55a736..0000000000 --- a/test/integration/targets/win_template/templates/foo2.j2 +++ /dev/null @@ -1,3 +0,0 @@ -BEGIN -[% templated_var %] -END diff --git a/test/integration/targets/win_template/vars/main.yml b/test/integration/targets/win_template/vars/main.yml deleted file mode 100644 index 1e8f64ccf4..0000000000 --- a/test/integration/targets/win_template/vars/main.yml +++ /dev/null @@ -1 +0,0 @@ -templated_var: templated_var_loaded diff --git a/test/integration/targets/win_updates/aliases b/test/integration/targets/win_updates/aliases deleted file mode 100644 index 98b74ac987..0000000000 --- a/test/integration/targets/win_updates/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group2 -unstable diff --git a/test/integration/targets/win_updates/defaults/main.yml b/test/integration/targets/win_updates/defaults/main.yml deleted file mode 100644 index 4946ccb037..0000000000 --- a/test/integration/targets/win_updates/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -win_updates_dir: '{{win_output_dir}}\win_updates' diff --git a/test/integration/targets/win_updates/tasks/main.yml b/test/integration/targets/win_updates/tasks/main.yml deleted file mode 100644 index 182090e98a..0000000000 --- a/test/integration/targets/win_updates/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- name: ensure test folder exists - win_file: - path: '{{win_updates_dir}}' - state: directory - -- name: ensure WUA service is running - win_service: - name: wuauserv - state: started - start_mode: manual - -- block: - - include_tasks: tests.yml - - always: - - name: ensure test folder is deleted - win_file: - path: '{{win_updates_dir}}' - state: absent - - - name: ensure WUA service is running - win_service: - name: wuauserv - state: started - start_mode: manual diff --git a/test/integration/targets/win_updates/tasks/tests.yml b/test/integration/targets/win_updates/tasks/tests.yml deleted file mode 100644 index fe54a4b9c8..0000000000 --- a/test/integration/targets/win_updates/tasks/tests.yml +++ /dev/null @@ -1,96 +0,0 @@ ---- -- name: expect failure when state is not a valid option - win_updates: - state: invalid - register: invalid_state - failed_when: invalid_state.msg != 'state must be either installed, searched or downloaded' - -- name: ensure log file not present before tests - win_file: - path: '{{win_updates_dir}}/update.log' - state: absent - -- name: search for updates without log output - win_updates: - state: searched - category_names: - - CriticalUpdates - register: update_search_without_log - -- name: get stat of update without log file - win_stat: - path: '{{win_updates_dir}}/update.log' - register: update_search_without_log_actual - -- name: assert search for updates without log output - assert: - that: - - not update_search_without_log is changed - - update_search_without_log.reboot_required == False - - update_search_without_log.updates is defined - - update_search_without_log.installed_update_count is defined - - update_search_without_log.found_update_count is defined - - update_search_without_log_actual.stat.exists == False - -- name: search for updates with log output (check) - win_updates: - state: searched - category_names: CriticalUpdates - log_path: '{{win_updates_dir}}/update.log' - register: update_search_with_log_check - check_mode: yes - -- name: get stat of update log file (check) - win_stat: - path: '{{win_updates_dir}}/update.log' - register: update_search_with_log_check_actual - -- name: assert search for updates with log output - assert: - that: - - not update_search_with_log_check is changed - - update_search_with_log_check.reboot_required == False - - update_search_with_log_check.updates is defined - - update_search_with_log_check.installed_update_count is defined - - update_search_with_log_check.found_update_count is defined - - update_search_with_log_check_actual.stat.exists == False - -- name: search for updates with log output and use scheduled task - win_updates: - state: searched - category_names: - - CriticalUpdates - log_path: '{{win_updates_dir}}/update.log' - use_scheduled_task: yes - register: update_search_with_log - -- name: get stat of update log file - win_stat: - path: '{{win_updates_dir}}/update.log' - register: update_search_with_log_actual - -- name: assert search for updates with log output - assert: - that: - - not update_search_with_log is changed - - update_search_with_log.reboot_required == False - - update_search_with_log.updates is defined - - update_search_with_log.installed_update_count is defined - - update_search_with_log.found_update_count is defined - - update_search_with_log_actual.stat.exists - -- name: ensure WUA service is stopped for tests - win_service: - name: wuauserv - state: stopped - start_mode: disabled - -- name: expect failed when running with stopped WUA service - win_updates: - state: searched - category_names: - - CriticalUpdates - register: update_service_stopped_failed - failed_when: - - "'Failed to search for updates with criteria' not in update_service_stopped_failed.msg" - - "'The service cannot be started' not in update_service_stopped_failed.msg" diff --git a/test/integration/targets/win_uri/aliases b/test/integration/targets/win_uri/aliases deleted file mode 100644 index ab5e3056cb..0000000000 --- a/test/integration/targets/win_uri/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/windows/group6 -needs/httptester -skip/windows/2008 # httptester requires SSH which doesn't work with 2008 diff --git a/test/integration/targets/win_uri/meta/main.yml b/test/integration/targets/win_uri/meta/main.yml deleted file mode 100644 index 8b53e81a07..0000000000 --- a/test/integration/targets/win_uri/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: -- prepare_http_tests diff --git a/test/integration/targets/win_uri/tasks/main.yml b/test/integration/targets/win_uri/tasks/main.yml deleted file mode 100644 index d2ea71e994..0000000000 --- a/test/integration/targets/win_uri/tasks/main.yml +++ /dev/null @@ -1,547 +0,0 @@ ---- -# get with mismatch https -# get with mismatch https and ignore validation - -- name: get request without return_content - win_uri: - url: https://{{httpbin_host}}/get - return_content: no - register: get_request_without_content - -- name: assert get request without return_content - assert: - that: - - not get_request_without_content.changed - - get_request_without_content.content is not defined - - get_request_without_content.json is not defined - - get_request_without_content.status_code == 200 - -- name: get request with xml content - win_uri: - url: https://{{httpbin_host}}/xml - return_content: yes - register: get_request_with_xml_content - -- name: assert get request with xml content - assert: - that: - - not get_request_with_xml_content.changed - - get_request_with_xml_content.content is defined - - get_request_with_xml_content.json is not defined - - get_request_with_xml_content.status_code == 200 - -- name: get request with binary content - win_uri: - url: https://{{httpbin_host}}/image/png - return_content: yes - register: get_request_with_binary_content - -- name: assert get request with binary content - assert: - that: - - not get_request_with_binary_content.changed - - get_request_with_binary_content.content is defined - - get_request_with_binary_content.json is not defined - - get_request_with_xml_content.status_code == 200 - -- name: get request with return_content and dest (check mode) - win_uri: - url: https://{{httpbin_host}}/get - return_content: yes - dest: '{{ remote_tmp_dir }}\get.json' - register: get_request_with_dest_check - check_mode: yes - -- name: get stat of downloaded file (check mode) - win_stat: - path: '{{ remote_tmp_dir }}\get.json' - register: get_request_with_dest_actual_check - -- name: assert get request with return_content and dest (check mode) - assert: - that: - - get_request_with_dest_check.changed - - get_request_with_dest_check.content is defined - - get_request_with_dest_check.json is defined - - get_request_with_dest_actual_check.stat.exists == False - -- name: get request with return_content and dest - win_uri: - url: https://{{httpbin_host}}/base64/{{ '{"key":"value"}' | b64encode }} - return_content: yes - dest: '{{ remote_tmp_dir }}\get.json' - register: get_request_with_dest - -- name: get stat of downloaded file - win_stat: - path: '{{ remote_tmp_dir }}\get.json' - checksum_algorithm: sha1 - get_checksum: yes - register: get_request_with_dest_actual - -- name: assert get request with return_content and dest - assert: - that: - - get_request_with_dest.changed - - get_request_with_dest.content is defined - - get_request_with_dest.json is defined - - get_request_with_dest_actual.stat.exists == True - - get_request_with_dest_actual.stat.checksum == get_request_with_dest.content|hash('sha1') - -- name: get request with return_content and dest (idempotent) - win_uri: - url: https://{{httpbin_host}}/base64/{{ '{"key":"value"}' | b64encode }} - return_content: yes - dest: '{{ remote_tmp_dir }}\get.json' - register: get_request_with_dest_again - -- name: assert get request with return_content and dest (idempotent) - assert: - that: - - not get_request_with_dest_again.changed - -- name: test request with creates option should skip - win_uri: - url: https://{{httpbin_host}}/get - creates: '{{ remote_tmp_dir }}\get.json' - register: request_with_creates_skipped - -- name: assert test request with creates option should skip - assert: - that: - - not request_with_creates_skipped.changed - - request_with_creates_skipped.skipped - -- name: test request with creates option should not skip - win_uri: - url: https://{{httpbin_host}}/get - creates: '{{ remote_tmp_dir }}\fake.json' - register: request_with_creates_not_skipped - -- name: assert test request with creates option should not skip - assert: - that: - - not request_with_creates_not_skipped.changed - - request_with_creates_not_skipped.skipped is not defined - -- name: post request with return_content, dest and different content - win_uri: - url: https://{{httpbin_host}}/post - method: POST - content_type: application/json - body: '{"foo": "bar"}' - return_content: yes - dest: '{{ remote_tmp_dir }}\get.json' - register: post_request_with_different_content - -- name: get stat of downloaded file - win_stat: - path: '{{ remote_tmp_dir }}\get.json' - checksum_algorithm: sha1 - get_checksum: yes - register: post_request_with_different_content_actual - -- name: assert post request with return_content, dest and different content - assert: - that: - - post_request_with_different_content.changed - - post_request_with_different_content_actual.stat.exists == True - - post_request_with_different_content_actual.stat.checksum == post_request_with_different_content.content|hash('sha1') - -- name: test safe redirection of get - win_uri: - url: https://{{httpbin_host}}/redirect/2 - register: redirect_safe - -- name: assert safe redirection of get - assert: - that: - - redirect_safe.status_code == 200 - - redirect_safe.response_uri == 'https://' + httpbin_host + '/get' - -- name: test safe redirection of head - win_uri: - url: https://{{httpbin_host}}/redirect/2 - method: HEAD - register: redirect_safe_head - -- name: assert safe redirection of head - assert: - that: - - redirect_safe_head.status_code == 200 - - redirect_safe_head.response_uri == 'https://' + httpbin_host + '/get' - -- name: test safe redirection of put - win_uri: - url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put - body: data - status_code: 302 - method: PUT - register: redirect_safe_put - -- name: assert safe redirection of put - assert: - that: - - redirect_safe_put.status_code == 302 - - redirect_safe_put.response_uri == 'https://' + httpbin_host + '/redirect-to?url=https://' + httpbin_host + '/put' - -- name: test none redirection of get - win_uri: - url: https://{{httpbin_host}}/redirect/2 - status_code: 302 - follow_redirects: none - register: redirect_none - -- name: assert none redirection of get - assert: - that: - - redirect_none.status_code == 302 - - redirect_none.response_uri == 'https://' + httpbin_host + '/redirect/2' - -- name: test none redirection of put - win_uri: - url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put - body: data - status_code: 302 - method: PUT - follow_redirects: none - register: redirect_none_put - -- name: assert none redirection of put - assert: - that: - - redirect_none_put.status_code == 302 - - redirect_none_put.response_uri == 'https://' + httpbin_host + '/redirect-to?url=https://' + httpbin_host + '/put' - -- name: test all redirection of get - win_uri: - url: https://{{httpbin_host}}/redirect/2 - follow_redirects: all - register: redirect_all - -- name: assert all redirection of get - assert: - that: - - redirect_all.status_code == 200 - - redirect_all.response_uri == 'https://' + httpbin_host + '/get' - -- name: test all redirection of put - win_uri: - url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put - body: data - method: PUT - follow_redirects: all - register: redirect_all_put - -- name: assert all redirection of put - assert: - that: - - redirect_all_put.status_code == 200 - - redirect_all_put.response_uri == 'https://' + httpbin_host + '/put' - -- name: test exceeded maximum redirection - win_uri: - url: https://{{httpbin_host}}/redirect/5 - maximum_redirection: 4 - status_code: 302 - register: maximum_redirection - -- name: assert exceeded maximum redirection - assert: - that: - - maximum_redirection.status_code == 302 - - maximum_redirection.response_uri == 'https://' + httpbin_host + '/relative-redirect/1' - -- name: test basic auth - win_uri: - url: https://{{httpbin_host}}/basic-auth/user/passwd - user: user - password: passwd - register: basic_auth - -- name: assert test basic auth - assert: - that: - - not basic_auth.changed - - basic_auth.status_code == 200 - -- name: test basic auth with force auth - win_uri: - url: https://{{httpbin_host}}/hidden-basic-auth/user/passwd - user: user - password: passwd - force_basic_auth: yes - register: basic_auth_forced - -- name: assert test basic auth with forced auth - assert: - that: - - not basic_auth_forced.changed - - basic_auth_forced.status_code == 200 - -- name: test PUT - win_uri: - url: https://{{httpbin_host}}/put - method: PUT - body: foo=bar - return_content: yes - register: put_request - -- name: assert test PUT - assert: - that: - - not put_request.changed - - put_request.status_code == 200 - - put_request.json.data == 'foo=bar' - -- name: test OPTIONS - win_uri: - url: https://{{httpbin_host}}/ - method: OPTIONS - register: option_request - -- name: assert test OPTIONS - assert: - that: - - not option_request.changed - - option_request.status_code == 200 - - 'option_request.allow.split(", ")|sort == ["GET", "HEAD", "OPTIONS"]' - -# SNI Tests - -- name: validate status_codes are correct - win_uri: - url: https://{{httpbin_host}}/status/202 - status_code: - - 202 - - 418 - method: POST - body: foo - register: status_code_check - -- name: assert validate status_codes are correct - assert: - that: - - not status_code_check.changed - - status_code_check.status_code == 202 - -- name: send JSON body with dict type - win_uri: - url: https://{{httpbin_host}}/post - method: POST - body: - foo: bar - list: - - 1 - - 2 - dict: - foo: bar - headers: - 'Content-Type': 'text/json' - return_content: yes - register: json_as_dict - -- name: set fact of expected json dict - set_fact: - json_as_dict_value: - foo: bar - list: - - 1 - - 2 - dict: - foo: bar - -- name: assert send JSON body with dict type - assert: - that: - - not json_as_dict.changed - - json_as_dict.json.json == json_as_dict_value - - json_as_dict.status_code == 200 - -- name: send JSON body with 1 item in list - win_uri: - url: https://{{httpbin_host}}/post - method: POST - body: - - foo: bar - headers: - 'Content-Type': 'text/json' - return_content: yes - register: json_as_oneitemlist - -- name: set fact of expected json 1 item list - set_fact: - json_as_oneitemlist_value: - - foo: bar - -- name: assert send JSON body with 1 item in list - assert: - that: - - not json_as_oneitemlist.changed - - json_as_oneitemlist.json.json == json_as_oneitemlist_value - - json_as_oneitemlist.status_code == 200 - -- name: get request with custom headers - win_uri: - url: https://{{httpbin_host}}/get - headers: - Test-Header: hello - Another-Header: world - return_content: yes - register: get_custom_header - -- name: assert request with custom headers - assert: - that: - - not get_custom_header.changed - - get_custom_header.status_code == 200 - - get_custom_header.json.headers['Test-Header'] == 'hello' - - get_custom_header.json.headers['Another-Header'] == 'world' - -- name: Validate invalid method - win_uri: - url: https://{{ httpbin_host }}/anything - method: UNKNOWN - register: invalid_method - ignore_errors: yes - -- name: Assert invalid method fails - assert: - that: - - invalid_method is failure - - invalid_method.status_code == 405 - - invalid_method.status_description == 'METHOD NOT ALLOWED' - -# client cert auth tests - -- name: get request with timeout - win_uri: - url: https://{{httpbin_host}}/delay/10 - timeout: 5 - register: get_with_timeout_fail - failed_when: '"The operation has timed out" not in get_with_timeout_fail.msg' - -- name: connect to fakepath that does not exist - win_uri: - url: https://{{httpbin_host}}/fakepath - status_code: 404 - return_content: yes - register: invalid_path - -# verifies the return values are still set on a non 200 response -- name: assert connect to fakepath that does not exist - assert: - that: - - not invalid_path.changed - - invalid_path.status_code == 404 - - invalid_path.status_description == 'NOT FOUND' - - invalid_path.content is defined - - invalid_path.method == 'GET' - - invalid_path.connection is defined - -- name: post request with custom headers - win_uri: - url: https://{{httpbin_host}}/post - method: POST - headers: - Test-Header: hello - Another-Header: world - content_type: application/json - body: '{"foo": "bar"}' - return_content: yes - register: post_request_with_custom_headers - -- name: assert post with custom headers - assert: - that: - - not post_request_with_custom_headers.changed - - post_request_with_custom_headers.status_code == 200 - - post_request_with_custom_headers.json.headers['Content-Type'] == "application/json" - - post_request_with_custom_headers.json.headers['Test-Header'] == 'hello' - - post_request_with_custom_headers.json.headers['Another-Header'] == 'world' - -- name: validate status codes as list of strings - win_uri: - url: https://{{httpbin_host}}/status/202 - status_code: - - '202' - - '418' - method: POST - body: foo - return_content: yes - register: request_status_code_string - -- name: assert status codes as list of strings - assert: - that: - - not request_status_code_string.changed - - request_status_code_string.status_code == 202 - -- name: validate status codes as comma separated list - win_uri: - url: https://{{httpbin_host}}/status/202 - status_code: 202, 418 - method: POST - body: foo - return_content: yes - register: request_status_code_comma - -- name: assert status codes as comma separated list - assert: - that: - - not request_status_code_comma.changed - - request_status_code_comma.status_code == 202 - -# https://github.com/ansible/ansible/issues/55294 -- name: get json content that is an array - win_uri: - url: https://{{httpbin_host}}/base64/{{ '[{"abc":"def"}]' | b64encode }} - return_content: yes - register: content_array - -- name: assert content of json array - assert: - that: - - not content_array is changed - - content_array.content == '[{"abc":"def"}]' - - content_array.json == [{"abc":"def"}] - -- name: send request with explicit http_agent - win_uri: - url: https://{{httpbin_host}}/get - http_agent: test-agent - return_content: yes - register: http_agent_option - -- name: assert send request with explicit http_agent - assert: - that: - - http_agent_option.json.headers['User-Agent'] == 'test-agent' - -- name: send request with explicit User-Agent header - win_uri: - url: https://{{httpbin_host}}/get - headers: - User-Agent: test-agent - return_content: yes - register: http_agent_header - -- name: assert send request with explicit User-Agent header - assert: - that: - - http_agent_header.json.headers['User-Agent'] == 'test-agent' - -- name: send request with explicit http_agent and header (http_agent wins) - win_uri: - url: https://{{httpbin_host}}/get - http_agent: test-agent-option - headers: - User-Agent: test-agent-header - return_content: yes - register: http_agent_combo - -- name: assert send request with explicit http_agent and header (http_agent wins) - assert: - that: - - http_agent_combo.json.headers['User-Agent'] == 'test-agent-option' - - http_agent_combo.warnings[0] == "The 'User-Agent' header and the 'http_agent' was set, using the 'http_agent' for web request" diff --git a/test/integration/targets/win_user/aliases b/test/integration/targets/win_user/aliases deleted file mode 100644 index 6036e173f1..0000000000 --- a/test/integration/targets/win_user/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group7 diff --git a/test/integration/targets/win_user/defaults/main.yml b/test/integration/targets/win_user/defaults/main.yml deleted file mode 100644 index c6a18ed3a3..0000000000 --- a/test/integration/targets/win_user/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -test_win_user_name: test_win_user -test_win_user_password: "T35Tus3rP@ssW0rd" -test_win_user_password2: "pa55wOrd4te5tU53R!" diff --git a/test/integration/targets/win_user/files/lockout_user.ps1 b/test/integration/targets/win_user/files/lockout_user.ps1 deleted file mode 100644 index e15f13f3bf..0000000000 --- a/test/integration/targets/win_user/files/lockout_user.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -trap -{ - Write-Error -ErrorRecord $_ - exit 1; -} - -$username = $args[0] -[void][system.reflection.assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement') -$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Machine', $env:COMPUTERNAME -For ($i = 1; $i -le 10; $i++) { - try { - $pc.ValidateCredentials($username, 'b@DP@ssw0rd') - } - catch { - break - } -} diff --git a/test/integration/targets/win_user/tasks/main.yml b/test/integration/targets/win_user/tasks/main.yml deleted file mode 100644 index 072a381c9e..0000000000 --- a/test/integration/targets/win_user/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: create test group that has a network logon denied - win_group: - name: win_user-test - state: present - -- name: add test group to SeDenyNetworkLogonRight - win_user_right: - name: SeDenyNetworkLogonRight - users: - - win_user-test - action: add - -- block: - - name: run tests - include_tasks: tests.yml - - always: - - name: remove SeDenyNetworkLogonRight on test group - win_user_right: - name: SeDenyNetworkLogonRight - users: - - win_user-test - action: remove - - - name: remove test group - win_group: - name: win_user-test - state: absent - - - name: remove the test user - win_user: - name: '{{ test_win_user_name }}' - state: absent diff --git a/test/integration/targets/win_user/tasks/tests.yml b/test/integration/targets/win_user/tasks/tests.yml deleted file mode 100644 index 1c36d32101..0000000000 --- a/test/integration/targets/win_user/tasks/tests.yml +++ /dev/null @@ -1,455 +0,0 @@ -# test code for the win_user module -# (c) 2014, Chris Church <chris@ninemoreminutes.com> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. - -- name: remove existing test user if present - win_user: name="{{ test_win_user_name }}" state="absent" - register: win_user_remove_result - -- name: check user removal result - assert: - that: - - "win_user_remove_result.name" - - "win_user_remove_result.state == 'absent'" - -- name: try to remove test user again - win_user: name="{{ test_win_user_name }}" state="absent" - register: win_user_remove_result_again - -- name: check user removal result again - assert: - that: - - "win_user_remove_result_again is not changed" - - "win_user_remove_result_again.name" - - "win_user_remove_result_again.msg" - - "win_user_remove_result.state == 'absent'" - -- name: test missing user with query state - win_user: name="{{ test_win_user_name }}" state="query" - register: win_user_missing_query_result - -- name: check missing query result - assert: - that: - - "win_user_missing_query_result is not changed" - - "win_user_missing_query_result.name" - - "win_user_missing_query_result.msg" - - "win_user_missing_query_result.state == 'absent'" - -- name: test create user - win_user: name="{{ test_win_user_name }}" password="{{ test_win_user_password }}" fullname="Test User" description="Test user account" groups="Guests" - register: win_user_create_result - -- name: check user creation result - assert: - that: - - "win_user_create_result is changed" - - "win_user_create_result.name == '{{ test_win_user_name }}'" - - "win_user_create_result.fullname == 'Test User'" - - "win_user_create_result.description == 'Test user account'" - - "win_user_create_result.path" - - "win_user_create_result.state == 'present'" - -- name: update user full name and description - win_user: name="{{ test_win_user_name }}" fullname="Test Ansible User" description="Test user account created by Ansible" groups="" - register: win_user_update_result - -- name: check full name and description update result - assert: - that: - - "win_user_update_result is changed" - - "win_user_update_result.fullname == 'Test Ansible User'" - - "win_user_update_result.description == 'Test user account created by Ansible'" - -- name: update user full name and description again with same values - win_user: name="{{ test_win_user_name }}" fullname="Test Ansible User" description="Test user account created by Ansible" - register: win_user_update_result_again - -- name: check full name and description result again - assert: - that: - - "win_user_update_result_again is not changed" - - "win_user_update_result_again.fullname == 'Test Ansible User'" - - "win_user_update_result_again.description == 'Test user account created by Ansible'" - -- name: test again with no options or changes - win_user: name="{{ test_win_user_name }}" - register: win_user_nochange_result - -- name: check no changes result - assert: - that: - - "win_user_nochange_result is not changed" - -- name: test again with query state - win_user: name="{{ test_win_user_name }}" state="query" - register: win_user_query_result - -- name: check query result - assert: - that: - - "win_user_query_result is not changed" - - "win_user_query_result.state == 'present'" - - "win_user_query_result.name == '{{ test_win_user_name }}'" - - "win_user_query_result.fullname == 'Test Ansible User'" - - "win_user_query_result.description == 'Test user account created by Ansible'" - - "win_user_query_result.path" - - "win_user_query_result.sid" - - "win_user_query_result.groups == []" - -- name: change user password - win_user: name="{{ test_win_user_name }}" password="{{ test_win_user_password2 }}" - register: win_user_password_result - -- name: check password change result - assert: - that: - - "win_user_password_result is changed" - -- name: change user password again to same value - win_user: name="{{ test_win_user_name }}" password="{{ test_win_user_password2 }}" - register: win_user_password_result_again - -- name: check password change result again - assert: - that: - - "win_user_password_result_again is not changed" - -- name: check update_password=on_create for existing user - win_user: name="{{ test_win_user_name }}" password="ThisP@ssW0rdShouldNotBeUsed" update_password=on_create - register: win_user_nopasschange_result - -- name: check password change with on_create flag result - assert: - that: - - "win_user_nopasschange_result is not changed" - -- name: set password expired flag - win_user: name="{{ test_win_user_name }}" password_expired=yes - register: win_user_password_expired_result - -- name: check password expired result - assert: - that: - - "win_user_password_expired_result is changed" - - "win_user_password_expired_result.password_expired" - -- name: set password when expired - win_user: name="{{ test_win_user_name }}" password={{ test_win_user_password2 }} update_password=always - register: win_user_can_set_password_on_expired - -- name: check set password on expired result - assert: - that: - - win_user_can_set_password_on_expired is changed - -- name: set password expired flag again - win_user: name="{{ test_win_user_name }}" password_expired=yes - register: win_user_password_expired_result - -- name: check password expired result - assert: - that: - - "win_user_password_expired_result is changed" - - "win_user_password_expired_result.password_expired" - -- name: clear password expired flag - win_user: name="{{ test_win_user_name }}" password_expired=no - register: win_user_clear_password_expired_result - -- name: check clear password expired result - assert: - that: - - "win_user_clear_password_expired_result is changed" - - "not win_user_clear_password_expired_result.password_expired" - -- name: set password never expires flag - win_user: name="{{ test_win_user_name }}" password_never_expires=yes - register: win_user_password_never_expires_result - -- name: check password never expires result - assert: - that: - - "win_user_password_never_expires_result is changed" - - "win_user_password_never_expires_result.password_never_expires" - -- name: clear password never expires flag - win_user: name="{{ test_win_user_name }}" password_never_expires=no - register: win_user_clear_password_never_expires_result - -- name: check clear password never expires result - assert: - that: - - "win_user_clear_password_never_expires_result is changed" - - "not win_user_clear_password_never_expires_result.password_never_expires" - -- name: set user cannot change password flag - win_user: name="{{ test_win_user_name }}" user_cannot_change_password=yes - register: win_user_cannot_change_password_result - -- name: check user cannot change password result - assert: - that: - - "win_user_cannot_change_password_result is changed" - - "win_user_cannot_change_password_result.user_cannot_change_password" - -- name: clear user cannot change password flag - win_user: name="{{ test_win_user_name }}" user_cannot_change_password=no - register: win_user_can_change_password_result - -- name: check clear user cannot change password result - assert: - that: - - "win_user_can_change_password_result is changed" - - "not win_user_can_change_password_result.user_cannot_change_password" - -- name: set account disabled flag - win_user: name="{{ test_win_user_name }}" account_disabled=true - register: win_user_account_disabled_result - -- name: check account disabled result - assert: - that: - - "win_user_account_disabled_result is changed" - - "win_user_account_disabled_result.account_disabled" - -- name: set password on disabled account - win_user: name="{{ test_win_user_name }}" password={{ test_win_user_password2 }} update_password=always - register: win_user_can_set_password_on_disabled - -- name: check set password on disabled result - assert: - that: - - win_user_can_set_password_on_disabled is changed - - win_user_can_set_password_on_disabled.account_disabled - -- name: clear account disabled flag - win_user: name="{{ test_win_user_name }}" account_disabled=false - register: win_user_clear_account_disabled_result - -- name: check clear account disabled result - assert: - that: - - "win_user_clear_account_disabled_result is changed" - - "not win_user_clear_account_disabled_result.account_disabled" - -- name: attempt to set account locked flag - win_user: name="{{ test_win_user_name }}" account_locked=yes - register: win_user_set_account_locked_result - ignore_errors: true - -- name: verify that attempting to set account locked flag fails - assert: - that: - - "win_user_set_account_locked_result is failed" - - "win_user_set_account_locked_result is not changed" - -- name: attempt to lockout test account - script: lockout_user.ps1 "{{ test_win_user_name }}" - -- name: get user to check if account locked flag is set - win_user: name="{{ test_win_user_name }}" state="query" - register: win_user_account_locked_result - -- name: clear account locked flag if set - win_user: name="{{ test_win_user_name }}" account_locked=no - register: win_user_clear_account_locked_result - when: "win_user_account_locked_result.account_locked" - -- name: check clear account lockout result if account was locked - assert: - that: - - "win_user_clear_account_locked_result is changed" - - "not win_user_clear_account_locked_result.account_locked" - when: "win_user_account_locked_result.account_locked" - -- name: assign test user to a group - win_user: name="{{ test_win_user_name }}" groups="Users" - register: win_user_replace_groups_result - -- name: check assign user to group result - assert: - that: - - "win_user_replace_groups_result is changed" - - "win_user_replace_groups_result.groups|length == 1" - - "win_user_replace_groups_result.groups[0]['name'] == 'Users'" - -- name: assign test user to the same group - win_user: - name: "{{ test_win_user_name }}" - groups: ["Users"] - register: win_user_replace_groups_again_result - -- name: check assign user to group again result - assert: - that: - - "win_user_replace_groups_again_result is not changed" - -- name: add user to another group - win_user: name="{{ test_win_user_name }}" groups="Power Users" groups_action="add" - register: win_user_add_groups_result - -- name: check add user to another group result - assert: - that: - - "win_user_add_groups_result is changed" - - "win_user_add_groups_result.groups|length == 2" - - "win_user_add_groups_result.groups[0]['name'] in ('Users', 'Power Users')" - - "win_user_add_groups_result.groups[1]['name'] in ('Users', 'Power Users')" - -- name: add user to another group again - win_user: - name: "{{ test_win_user_name }}" - groups: "Power Users" - groups_action: add - register: win_user_add_groups_again_result - -- name: check add user to another group again result - assert: - that: - - "win_user_add_groups_again_result is not changed" - -- name: remove user from a group - win_user: name="{{ test_win_user_name }}" groups="Users" groups_action="remove" - register: win_user_remove_groups_result - -- name: check remove user from group result - assert: - that: - - "win_user_remove_groups_result is changed" - - "win_user_remove_groups_result.groups|length == 1" - - "win_user_remove_groups_result.groups[0]['name'] == 'Power Users'" - -- name: remove user from a group again - win_user: - name: "{{ test_win_user_name }}" - groups: - - "Users" - groups_action: remove - register: win_user_remove_groups_again_result - -- name: check remove user from group again result - assert: - that: - - "win_user_remove_groups_again_result is not changed" - -- name: reassign test user to multiple groups - win_user: name="{{ test_win_user_name }}" groups="Users, Guests" groups_action="replace" - register: win_user_reassign_groups_result - -- name: check reassign user groups result - assert: - that: - - "win_user_reassign_groups_result is changed" - - "win_user_reassign_groups_result.groups|length == 2" - - "win_user_reassign_groups_result.groups[0]['name'] in ('Users', 'Guests')" - - "win_user_reassign_groups_result.groups[1]['name'] in ('Users', 'Guests')" - -- name: reassign test user to multiple groups again - win_user: - name: "{{ test_win_user_name }}" - groups: - - "Users" - - "Guests" - groups_action: replace - register: win_user_reassign_groups_again_result - -- name: check reassign user groups again result - assert: - that: - - "win_user_reassign_groups_again_result is not changed" - -- name: remove user from all groups - win_user: name="{{ test_win_user_name }}" groups="" - register: win_user_remove_all_groups_result - -- name: check remove user from all groups result - assert: - that: - - "win_user_remove_all_groups_result is changed" - - "win_user_remove_all_groups_result.groups|length == 0" - -- name: remove user from all groups again - win_user: - name: "{{ test_win_user_name }}" - groups: [] - register: win_user_remove_all_groups_again_result - -- name: check remove user from all groups again result - assert: - that: - - "win_user_remove_all_groups_again_result is not changed" - -- name: assign user to invalid group - win_user: name="{{ test_win_user_name }}" groups="Userz" - register: win_user_invalid_group_result - ignore_errors: true - -- name: check invalid group result - assert: - that: - - "win_user_invalid_group_result is failed" - - "win_user_invalid_group_result.msg" - - win_user_invalid_group_result.msg is match("group 'Userz' not found") - -- name: remove test user when finished - win_user: name="{{ test_win_user_name }}" state="absent" - register: win_user_final_remove_result - -- name: check final user removal result - assert: - that: - - "win_user_final_remove_result is changed" - - "win_user_final_remove_result.name" - - "win_user_final_remove_result.msg" - - "win_user_final_remove_result.state == 'absent'" - -- name: test removed user with query state - win_user: name="{{ test_win_user_name }}" state="query" - register: win_user_removed_query_result - -- name: check removed query result - assert: - that: - - "win_user_removed_query_result is not changed" - - "win_user_removed_query_result.name" - - "win_user_removed_query_result.msg" - - "win_user_removed_query_result.state == 'absent'" - -# Tests the Test-Credential path where LogonUser fails if the user does not -# have the right for a network logon -- name: add new user that has the right SeDenyNetworkLogonRight - win_user: - name: '{{ test_win_user_name }}' - password: '{{ test_win_user_password2 }}' - state: present - groups: - - win_user-test - -- name: add new user that has the right SeDenyNetworkLogonRight (idempotent) - win_user: - name: '{{ test_win_user_name }}' - password: '{{ test_win_user_password2 }}' - state: present - groups: - - win_user-test - register: deny_network_idempotent - -- name: assert add new user that has the right SeDenyNetworkLogonRight (idempotent) - assert: - that: - - not deny_network_idempotent is changed diff --git a/test/integration/targets/win_user_right/aliases b/test/integration/targets/win_user_right/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_user_right/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_user_right/defaults/main.yml b/test/integration/targets/win_user_right/defaults/main.yml deleted file mode 100644 index 3db8c4f006..0000000000 --- a/test/integration/targets/win_user_right/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -test_win_user_right_name: SeRelabelPrivilege diff --git a/test/integration/targets/win_user_right/library/test_get_right.ps1 b/test/integration/targets/win_user_right/library/test_get_right.ps1 deleted file mode 100644 index 977022e4db..0000000000 --- a/test/integration/targets/win_user_right/library/test_get_right.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -#!powershell - -#Requires -Module Ansible.ModuleUtils.Legacy - -# basic script to get the lsit of users in a particular right -# this is quite complex to put as a simple script so this is -# just a simple module - -$ErrorActionPreference = 'Stop' - -$params = Parse-Args $args -supports_check_mode $false -$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true - -$result = @{ - changed = $false - users = @() -} - -Function Get-Username($sid) { - $object = New-Object System.Security.Principal.SecurityIdentifier($sid) - $user = $object.Translate([System.Security.Principal.NTAccount]) - $user.Value -} - -$secedit_ini_path = [IO.Path]::GetTempFileName() -&SecEdit.exe /export /cfg $secedit_ini_path /quiet -$secedit_ini = Get-Content -Path $secedit_ini_path -Remove-Item -Path $secedit_ini_path -Force - -foreach ($line in $secedit_ini) { - if ($line.ToLower().StartsWith("$($name.ToLower()) = ")) { - $right_split = $line -split "=" - $existing_users = $right_split[-1].Trim() -split "," - foreach ($user in $existing_users) { - if ($user.StartsWith("*S")) { - $result.users += Get-Username -sid $user.substring(1) - } else { - $result.users += $user - } - } - } -} - -Exit-Json $result diff --git a/test/integration/targets/win_user_right/tasks/main.yml b/test/integration/targets/win_user_right/tasks/main.yml deleted file mode 100644 index 8ab7ba3bb8..0000000000 --- a/test/integration/targets/win_user_right/tasks/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: get current entries for right - test_get_right: - name: '{{test_win_user_right_name}}' - register: actual_users - -- name: get facts - setup: - -- block: - - name: ensure right is empty before test - win_user_right: - name: '{{test_win_user_right_name}}' - users: [] - action: set - - - name: run tests - include_tasks: tests.yml - - always: - - name: reset entries for test right - win_user_right: - name: '{{test_win_user_right_name}}' - users: '{{actual_users.users}}' - action: set diff --git a/test/integration/targets/win_user_right/tasks/tests.yml b/test/integration/targets/win_user_right/tasks/tests.yml deleted file mode 100644 index 649e8fbe35..0000000000 --- a/test/integration/targets/win_user_right/tasks/tests.yml +++ /dev/null @@ -1,390 +0,0 @@ ---- -- name: Look up built-in Administrator account name (-500 user whose domain == computer name) - raw: $machine_sid = (Get-CimInstance Win32_UserAccount -Filter "Domain='$env:COMPUTERNAME'")[0].SID -replace '(S-1-5-21-\d+-\d+-\d+)-\d+', '$1'; (Get-CimInstance Win32_UserAccount -Filter "SID='$machine_sid-500'").Name - check_mode: no - register: admin_account_result - -- set_fact: - admin_account_name: "{{ admin_account_result.stdout_lines[0] }}" - -- name: fail to set invalid right - win_user_right: - name: FailRight - users: '{{ admin_account_name }}' - register: fail_invalid_right - failed_when: fail_invalid_right.msg != 'the specified right FailRight is not a valid right' - -- name: fail with invalid username - win_user_right: - name: '{{test_win_user_right_name}}' - users: FakeUser - register: fail_invalid_user - failed_when: "'account_name FakeUser is not a valid account, cannot get SID' not in fail_invalid_user.msg" - -- name: remove from empty right check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Administrators'] - action: remove - register: remove_empty_right_check - check_mode: yes - -- name: assert remove from empty right check - assert: - that: - - remove_empty_right_check is not changed - - remove_empty_right_check.added == [] - - remove_empty_right_check.removed == [] - -- name: remove from empty right - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Administrators'] - action: remove - register: remove_empty_right - check_mode: yes - -- name: assert remove from empty right - assert: - that: - - remove_empty_right is not changed - - remove_empty_right.added == [] - - remove_empty_right.removed == [] - -- name: set administrator check - win_user_right: - name: '{{test_win_user_right_name}}' - users: '{{ admin_account_name }}' - action: set - register: set_administrator_check - check_mode: yes - -- name: get actual set administrator check - test_get_right: - name: '{{test_win_user_right_name}}' - register: set_administrator_actual_check - -- name: assert set administrator check - assert: - that: - - set_administrator_check is changed - - set_administrator_check.added|count == 1 - - set_administrator_check.added[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - set_administrator_check.removed == [] - - set_administrator_actual_check.users == [] - -- name: set administrator - win_user_right: - name: '{{test_win_user_right_name}}' - users: '{{ admin_account_name }}' - action: set - register: set_administrator - -- name: get actual set administrator - test_get_right: - name: '{{test_win_user_right_name}}' - register: set_administrator_actual - -- name: assert set administrator check - assert: - that: - - set_administrator is changed - - set_administrator.added|count == 1 - - set_administrator.added[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - set_administrator.removed == [] - - set_administrator_actual.users == ['{{ admin_account_name }}'] - -- name: set administrator again - win_user_right: - name: '{{test_win_user_right_name}}' - users: '{{ admin_account_name }}' - action: set - register: set_administrator_again - -- name: assert set administrator check - assert: - that: - - set_administrator_again is not changed - - set_administrator_again.added == [] - - set_administrator_again.removed == [] - -- name: remove from right check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users', '.\Backup Operators'] - action: remove - register: remove_right_check - check_mode: yes - -- name: get actual remove from right check - test_get_right: - name: '{{test_win_user_right_name}}' - register: remove_right_actual_check - -- name: assert remove from right check - assert: - that: - - remove_right_check is changed - - remove_right_check.removed|count == 1 - - remove_right_check.removed[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - remove_right_check.added == [] - - remove_right_actual_check.users == ['{{ admin_account_name }}'] - -- name: remove from right - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users', '.\Backup Operators'] - action: remove - register: remove_right - -- name: get actual remove from right - test_get_right: - name: '{{test_win_user_right_name}}' - register: remove_right_actual - -- name: assert remove from right - assert: - that: - - remove_right is changed - - remove_right.removed|count == 1 - - remove_right.removed[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - remove_right.added == [] - - remove_right_actual.users == [] - -- name: remove from right again - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users', '.\Backup Operators'] - action: remove - register: remove_right_again - -- name: assert remove from right - assert: - that: - - remove_right_again is not changed - - remove_right_again.removed == [] - - remove_right_again.added == [] - -- name: add to empty right check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Administrators'] - action: add - register: add_right_on_empty_check - check_mode: yes - -- name: get actual add to empty right check - test_get_right: - name: '{{test_win_user_right_name}}' - register: add_right_on_empty_actual_check - -- name: assert add to empty right check - assert: - that: - - add_right_on_empty_check is changed - - add_right_on_empty_check.removed == [] - - add_right_on_empty_check.added|count == 2 - - add_right_on_empty_check.added[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - add_right_on_empty_check.added[1] == 'BUILTIN\Administrators' - - add_right_on_empty_actual_check.users == [] - -- name: add to empty right - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Administrators'] - action: add - register: add_right_on_empty - -- name: get actual add to empty right - test_get_right: - name: '{{test_win_user_right_name}}' - register: add_right_on_empty_actual - -- name: assert add to empty right - assert: - that: - - add_right_on_empty is changed - - add_right_on_empty.removed == [] - - add_right_on_empty.added|count == 2 - - add_right_on_empty.added[0]|upper == '{{ansible_hostname|upper}}\{{ admin_account_name|upper }}' - - add_right_on_empty.added[1] == 'BUILTIN\Administrators' - - add_right_on_empty_actual.users == ["{{ admin_account_name }}", "BUILTIN\\Administrators"] - -- name: add to empty right again - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Administrators'] - action: add - register: add_right_on_empty_again - -- name: assert add to empty right - assert: - that: - - add_right_on_empty_again is not changed - - add_right_on_empty_again.removed == [] - - add_right_on_empty_again.added == [] - -- name: add to existing right check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users'] - action: add - register: add_right_on_existing_check - check_mode: yes - -- name: get actual add to existing right check - test_get_right: - name: '{{test_win_user_right_name}}' - register: add_right_on_existing_actual_check - -- name: assert add to existing right check - assert: - that: - - add_right_on_existing_check is changed - - add_right_on_existing_check.removed == [] - - add_right_on_existing_check.added == ["BUILTIN\\Guests", "BUILTIN\\Users"] - - add_right_on_existing_actual_check.users == ["{{ admin_account_name }}", "BUILTIN\\Administrators"] - -- name: add to existing right - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users'] - action: add - register: add_right_on_existing - -- name: get actual add to existing right - test_get_right: - name: '{{test_win_user_right_name}}' - register: add_right_on_existing_actual - -- name: assert add to existing right - assert: - that: - - add_right_on_existing is changed - - add_right_on_existing.removed == [] - - add_right_on_existing.added == ["BUILTIN\\Guests", "BUILTIN\\Users"] - - add_right_on_existing_actual.users == ["{{ admin_account_name }}", "BUILTIN\\Administrators", "BUILTIN\\Users", "BUILTIN\\Guests"] - -- name: add to existing right again - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['{{ admin_account_name }}', 'Guests', '{{ansible_hostname}}\Users'] - action: add - register: add_right_on_existing_again - -- name: assert add to existing right - assert: - that: - - add_right_on_existing_again is not changed - - add_right_on_existing_again.removed == [] - - add_right_on_existing_again.added == [] - -- name: remove from existing check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Guests', '{{ admin_account_name }}'] - action: remove - register: remove_on_existing_check - check_mode: yes - -- name: get actual remove from existing check - test_get_right: - name: '{{test_win_user_right_name}}' - register: remove_on_existing_actual_check - -- name: assert remove from existing check - assert: - that: - - remove_on_existing_check is changed - - remove_on_existing_check.removed == ["BUILTIN\\Guests", "{{ansible_hostname}}\\{{ admin_account_name }}"] - - remove_on_existing_check.added == [] - - remove_on_existing_actual_check.users == ["{{ admin_account_name }}", "BUILTIN\\Administrators", "BUILTIN\\Users", "BUILTIN\\Guests"] - -- name: remove from existing - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Guests', '{{ admin_account_name }}'] - action: remove - register: remove_on_existing - -- name: get actual remove from existing - test_get_right: - name: '{{test_win_user_right_name}}' - register: remove_on_existing_actual - -- name: assert remove from existing - assert: - that: - - remove_on_existing is changed - - remove_on_existing.removed == ["BUILTIN\\Guests", "{{ansible_hostname}}\\{{ admin_account_name }}"] - - remove_on_existing.added == [] - - remove_on_existing_actual.users == ["BUILTIN\\Administrators", "BUILTIN\\Users"] - -- name: remove from existing again - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Guests', '{{ admin_account_name }}'] - action: remove - register: remove_on_existing_again - -- name: assert remove from existing again - assert: - that: - - remove_on_existing_again is not changed - - remove_on_existing_again.removed == [] - - remove_on_existing_again.added == [] - -- name: set to existing check - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Administrators', 'SYSTEM', 'Backup Operators'] - action: set - register: set_on_existing_check - check_mode: yes - -- name: get actual set to existing check - test_get_right: - name: '{{test_win_user_right_name}}' - register: set_on_existing_actual_check - -- name: assert set to existing check - assert: - that: - - set_on_existing_check is changed - - set_on_existing_check.removed == ["BUILTIN\\Users"] - - set_on_existing_check.added == ["NT AUTHORITY\\SYSTEM", "BUILTIN\\Backup Operators"] - - set_on_existing_actual_check.users == ["BUILTIN\\Administrators", "BUILTIN\\Users"] - -- name: set to existing - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Administrators', 'SYSTEM', 'Backup Operators'] - action: set - register: set_on_existing - -- name: get actual set to existing - test_get_right: - name: '{{test_win_user_right_name}}' - register: set_on_existing_actual - -- name: assert set to existing - assert: - that: - - set_on_existing is changed - - set_on_existing.removed == ["BUILTIN\\Users"] - - set_on_existing.added == ["NT AUTHORITY\\SYSTEM", "BUILTIN\\Backup Operators"] - - set_on_existing_actual.users == ["NT AUTHORITY\\SYSTEM", "BUILTIN\\Administrators", "BUILTIN\\Backup Operators"] - -- name: set to existing again - win_user_right: - name: '{{test_win_user_right_name}}' - users: ['Administrators', 'SYSTEM', 'Backup Operators'] - action: set - register: set_on_existing_again - -- name: assert set to existing - assert: - that: - - set_on_existing_again is not changed - - set_on_existing_again.removed == [] - - set_on_existing_again.added == [] diff --git a/test/integration/targets/win_wait_for/aliases b/test/integration/targets/win_wait_for/aliases deleted file mode 100644 index 11addc63ba..0000000000 --- a/test/integration/targets/win_wait_for/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/windows/group4 -unstable diff --git a/test/integration/targets/win_wait_for/defaults/main.yml b/test/integration/targets/win_wait_for/defaults/main.yml deleted file mode 100644 index 9e1155e329..0000000000 --- a/test/integration/targets/win_wait_for/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -test_win_wait_for_path: C:\ansible\win_wait_for -test_win_wait_for_port: 1234 diff --git a/test/integration/targets/win_wait_for/tasks/main.yml b/test/integration/targets/win_wait_for/tasks/main.yml deleted file mode 100644 index e7176e80bb..0000000000 --- a/test/integration/targets/win_wait_for/tasks/main.yml +++ /dev/null @@ -1,322 +0,0 @@ ---- -- name: ensure test folder is deleted for clean slate - win_file: - path: '{{test_win_wait_for_path}}' - state: absent - -- name: ensure test folder exists - win_file: - path: '{{test_win_wait_for_path}}' - state: directory - -- name: template out the test server - win_template: - src: http-server.ps1 - dest: '{{test_win_wait_for_path}}\http-server.ps1' - -# invalid arguments -- name: fail to set port and path - win_wait_for: - path: a - port: 0 - register: fail_port_and_path - failed_when: fail_port_and_path.msg != 'port and path parameter can not both be passed to win_wait_for' - -- name: fail to set exclude_hosts when state isn't drain - win_wait_for: - port: 0 - exclude_hosts: a - state: present - register: fail_exclude_hosts_not_drained - failed_when: fail_exclude_hosts_not_drained.msg != 'exclude_hosts should only be with state=drained' - -- name: fail to set state drained with path - win_wait_for: - path: a - state: drained - register: fail_path_drained - failed_when: fail_path_drained.msg != 'state=drained should only be used for checking a port in the win_wait_for module' - -- name: fail to set exclude_hosts with path - win_wait_for: - path: a - exclude_hosts: a - register: fail_path_exclude_hosts - failed_when: fail_path_exclude_hosts.msg != 'exclude_hosts should only be with state=drained' - -- name: fail to set search_regex with port - win_wait_for: - port: 0 - search_regex: a - register: fail_port_search_regex - failed_when: fail_port_search_regex.msg != 'regex should by used when checking a string in a file in the win_wait_for module' - -- name: fail to set exclude_hosts with port whens tate is not drained - win_wait_for: - port: 0 - exclude_hosts: a - state: present - register: fail_port_exclude_hosts_not_drained - failed_when: fail_port_exclude_hosts_not_drained.msg != 'exclude_hosts should only be with state=drained' - -# path tests -- name: timeout while waiting for file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: present - timeout: 5 - register: fail_timeout_file_present - ignore_errors: True - -- name: assert timeout while waiting for file - assert: - that: - - fail_timeout_file_present.msg == 'timeout while waiting for file ' + test_win_wait_for_path + '\\test.txt to be present' - - fail_timeout_file_present.wait_attempts == 5 - - fail_timeout_file_present.elapsed > 5 - -- name: wait for file to not exist - non existing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - register: wait_remove_no_file - -- name: assert wait for file to not exist - non existing file - assert: - that: - - wait_remove_no_file.wait_attempts == 1 - -- name: create file for next test - win_file: - path: '{{test_win_wait_for_path}}\test.txt' - state: touch - -- name: run async task to remove file after a timeout - win_shell: Start-Sleep -Seconds 5; Remove-Item -Path '{{test_win_wait_for_path}}\test.txt' -Force - async: 30 - poll: 0 - -- name: wait for file to not exist - existing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - register: wait_remove_existing_file - -- name: assert wait for file to not exist - existing file - assert: - that: - - wait_remove_existing_file.wait_attempts > 1 - -- name: run async task to create file after a timeout - win_shell: Start-Sleep -Seconds 5; New-Item -Path '{{test_win_wait_for_path}}\test.txt' -Type File - async: 30 - poll: 0 - -- name: wait for file to exist - non existing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: present - register: wait_new_missing_file - -- name: assert wait for file to exist - non existing file - assert: - that: - - wait_new_missing_file.wait_attempts > 1 - -- name: wait for file to exist - existing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: present - register: wait_new_existing_file - -- name: assert wait for file to exist - existing file - assert: - that: - - wait_new_existing_file.wait_attempts == 1 - -- name: timeout while waiting for file to not exist - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - timeout: 5 - register: fail_timeout_file_absent - ignore_errors: True - -- name: assert timeout while waiting for file to not exist - assert: - that: - - fail_timeout_file_absent.msg == 'timeout while waiting for file ' + test_win_wait_for_path + '\\test.txt to be absent' - - fail_timeout_file_absent.wait_attempts == 5 - - fail_timeout_file_absent.elapsed > 5 - -- name: run async task to populate file contents - win_shell: Start-Sleep -Seconds 5; Set-Content -Path '{{test_win_wait_for_path}}\test.txt' -Value 'hello world`r`nfile contents`r`nEnd line' - async: 30 - poll: 0 - -- name: wait for file contents to match regex - empty file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: present - search_regex: file c.* - register: wait_regex_match_new - -- name: assert wait for file contents to match regex - empty file - assert: - that: - - wait_regex_match_new.wait_attempts > 1 - -- name: wait for file contents to match regex - existing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: present - search_regex: file c.* - register: wait_regex_match_existing - -- name: assert wait for file contents to match regex - existing file - assert: - that: - - wait_regex_match_existing.wait_attempts == 1 - -- name: run async task to clear file contents - win_shell: Start-Sleep -Seconds 5; Set-Content -Path '{{test_win_wait_for_path}}\test.txt' -Value 'hello world`r`nother contents for file`r`nEnd line' - async: 30 - poll: 0 - -- name: wait for file content to not match regex - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - search_regex: file c.* - register: wait_regex_match_absent_remove - -- name: assert wait for file content to not match regex - assert: - that: - - wait_regex_match_absent_remove.wait_attempts > 1 - -- name: wait for file content to not match regex - existing - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - search_regex: file c.* - register: wait_regex_match_absent_existing - -- name: assert wait for file content to not match regex - assert: - that: - - wait_regex_match_absent_existing.wait_attempts == 1 - -- name: remove file to test search_regex works on missing files - win_file: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - -- name: wait for file content to not match regex - missing file - win_wait_for: - path: '{{test_win_wait_for_path}}\test.txt' - state: absent - search_regex: file c.* - register: wait_regex_match_absent_missing - -- name: assert wait for file content to not match regex - missing file - assert: - that: - - wait_regex_match_absent_missing.wait_attempts == 1 - -# port tests -- name: timeout waiting for port to come online - win_wait_for: - port: '{{test_win_wait_for_port}}' - timeout: 5 - state: started - register: fail_timeout_port_online - ignore_errors: True - -- name: assert timeout while waiting for port to come online - assert: - that: - - "fail_timeout_port_online.msg == 'timeout while waiting for 127.0.0.1:' + test_win_wait_for_port|string + ' to start listening'" - - fail_timeout_port_online.wait_attempts > 1 - - fail_timeout_port_online.elapsed > 5 - -- name: run async task to start web server - win_shell: Start-Sleep -Seconds 5; {{test_win_wait_for_path}}\http-server.ps1 - async: 30 - poll: 0 - -- name: wait for port to come online - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: started - register: wait_for_port_to_start - -- name: assert wait for port to come online - assert: - that: - - wait_for_port_to_start.wait_attempts > 1 - -- name: start web server - win_shell: '{{test_win_wait_for_path}}\http-server.ps1' - async: 30 - poll: 0 - -- name: wait for port that is already online - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: started - register: wait_for_port_already_started - -- name: assert wait for port that is already online - assert: - that: - - wait_for_port_already_started.wait_attempts == 1 - -# add a manual wait to make sure the port is truly offline for next test -- name: wait for port to be offline - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: stopped - -- name: wait for port that is already offline - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: stopped - register: wait_for_port_already_stopped - -- name: assert wait for port that is already offline - assert: - that: - - wait_for_port_already_stopped.wait_attempts == 1 - -- name: start web server for offline port test - win_shell: '{{test_win_wait_for_path}}\http-server.ps1' - async: 30 - poll: 0 - -- name: wait for port to go offline - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: stopped - register: wait_for_port_to_be_stopped - -- name: assert wait for port to go offline - assert: - that: - - wait_for_port_to_be_stopped.wait_attempts > 1 - -- name: wait for offline port to be drained - win_wait_for: - port: '{{test_win_wait_for_port}}' - state: drained - register: wait_for_drained_port_no_port - -- name: assert wait for offline port to be drained - assert: - that: - - wait_for_drained_port_no_port.wait_attempts == 1 - -- name: clear testing folder - win_file: - path: '{{test_win_wait_for_path}}' - state: absent diff --git a/test/integration/targets/win_wait_for/templates/http-server.ps1 b/test/integration/targets/win_wait_for/templates/http-server.ps1 deleted file mode 100644 index dd1f981809..0000000000 --- a/test/integration/targets/win_wait_for/templates/http-server.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -$ErrorActionPreference = 'Stop' - -$port = {{test_win_wait_for_port}} - -$endpoint = New-Object -TypeName System.Net.IPEndPoint([System.Net.IPAddress]::Parse("0.0.0.0"), $port) -$listener = New-Object -TypeName System.Net.Sockets.TcpListener($endpoint) -$listener.Server.ReceiveTimeout = 3000 -$listener.Start() - -try { - while ($true) { - if (-not $listener.Pending()) { - Start-Sleep -Seconds 1 - } else { - $client = $listener.AcceptTcpClient() - $client.Close() - break - } - } -} finally { - $listener.Stop() -} diff --git a/test/integration/targets/win_whoami/aliases b/test/integration/targets/win_whoami/aliases deleted file mode 100644 index 3cf5b97e80..0000000000 --- a/test/integration/targets/win_whoami/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/windows/group3 diff --git a/test/integration/targets/win_whoami/tasks/main.yml b/test/integration/targets/win_whoami/tasks/main.yml deleted file mode 100644 index 404523abfa..0000000000 --- a/test/integration/targets/win_whoami/tasks/main.yml +++ /dev/null @@ -1,225 +0,0 @@ ---- -- name: run win_whoami with normal execution - win_whoami: - register: win_whoami_result - -- name: assert win_whoami with normal execution - assert: - that: - - not win_whoami_result is changed - - win_whoami_result.account.account_name is defined - - win_whoami_result.account.domain_name is defined - - win_whoami_result.account.sid is defined - - win_whoami_result.account.type == 'User' - - win_whoami_result.authentication_package is defined - - win_whoami_result.dns_domain_name is defined - - win_whoami_result.groups|count >= 1 - - win_whoami_result.groups[0].account_name is defined - - win_whoami_result.groups[0].attributes is defined - - win_whoami_result.groups[0].domain_name is defined - - win_whoami_result.groups[0].sid is defined - - win_whoami_result.groups[0].type is defined - - win_whoami_result.impersonation_level is defined - - win_whoami_result.label.account_name == 'High Mandatory Level' - - win_whoami_result.label.domain_name == 'Mandatory Label' - - win_whoami_result.label.sid == 'S-1-16-12288' - - win_whoami_result.label.type == 'Label' - - win_whoami_result.login_domain is defined - - win_whoami_result.login_time is defined - - win_whoami_result.logon_id is defined - - win_whoami_result.logon_server is defined - - win_whoami_result.logon_type.startswith('Network') - - win_whoami_result.privileges is defined - - win_whoami_result.rights|count >= 1 - - win_whoami_result.token_type == 'TokenPrimary' - - win_whoami_result.upn is defined - - win_whoami_result.user_flags is defined - -- name: run win_whoami with SYSTEM execution - win_whoami: - become: yes - become_method: runas - become_user: SYSTEM - register: win_whoami_result - -- name: assert win_whoami with SYSTEM execution - assert: - that: - - not win_whoami_result is changed - - win_whoami_result.account.account_name == 'SYSTEM' - - win_whoami_result.account.domain_name == 'NT AUTHORITY' - - win_whoami_result.account.sid == 'S-1-5-18' - - win_whoami_result.account.type == 'User' - - win_whoami_result.authentication_package is defined - - win_whoami_result.dns_domain_name is defined - - win_whoami_result.groups|count >= 1 - - win_whoami_result.groups[0].account_name is defined - - win_whoami_result.groups[0].attributes is defined - - win_whoami_result.groups[0].domain_name is defined - - win_whoami_result.groups[0].sid is defined - - win_whoami_result.groups[0].type is defined - - win_whoami_result.impersonation_level == 'SecurityAnonymous' - - win_whoami_result.label.account_name == 'System Mandatory Level' - - win_whoami_result.label.domain_name == 'Mandatory Label' - - win_whoami_result.label.sid == 'S-1-16-16384' - - win_whoami_result.label.type == 'Label' - - win_whoami_result.login_domain is defined - - win_whoami_result.login_time is defined - - win_whoami_result.logon_id is defined - - win_whoami_result.logon_server is defined - - win_whoami_result.logon_type == 'System' - - win_whoami_result.privileges is defined - - win_whoami_result.rights|count >= 1 - - win_whoami_result.token_type == 'TokenPrimary' - - win_whoami_result.upn is defined - - win_whoami_result.user_flags is defined - -- set_fact: - become_username: ansible_become - become_username_limited: ansible_limited - gen_pw: password123! + {{lookup('password', '/dev/null chars=ascii_letters,digits length=8')}} - -- name: ensure current user is not the become user - win_shell: whoami - register: whoami_out - failed_when: whoami_out.stdout_lines[0].endswith(become_username) or whoami_out.stdout_lines[0].endswith(become_username_limited) - -- name: create user - win_user: - name: '{{become_username}}' - password: '{{gen_pw}}' - update_password: always - groups: Administrators - register: become_user_info - -- name: create user limited - win_user: - name: '{{become_username_limited}}' - password: '{{gen_pw}}' - update_password: always - groups: Users - register: become_user_info_limited - -- block: - - name: get become user profile dir so we can clean it up later - vars: &become_vars - ansible_become_user: '{{become_username}}' - ansible_become_password: '{{gen_pw}}' - ansible_become_method: runas - ansible_become: yes - win_shell: $env:USERPROFILE - register: profile_dir_out - - - name: ensure profile dir contains test username (eg, if become fails silently, prevent deletion of real user profile) - assert: - that: - - become_username in profile_dir_out.stdout_lines[0] - - - name: get become user limited profile dir so we can clean it up later - vars: &become_vars_limited - ansible_become_user: '{{become_username_limited}}' - ansible_become_password: '{{gen_pw}}' - ansible_become_method: runas - ansible_become: yes - win_shell: $env:USERPROFILE - register: profile_dir_out_limited - - - name: ensure limited profile dir contains test username (eg, if become fails silently, prevent deletion of real user profile) - assert: - that: - - become_username_limited in profile_dir_out_limited.stdout_lines[0] - - - name: run win_whoami with become execution - win_whoami: - vars: *become_vars - register: win_whoami_result - - - name: assert win_whoami with become execution - assert: - that: - - not win_whoami_result is changed - - win_whoami_result.account.account_name == "ansible_become" - - win_whoami_result.account.domain_name is defined - - win_whoami_result.account.sid == become_user_info.sid - - win_whoami_result.account.type == 'User' - - win_whoami_result.authentication_package == "NTLM" - - win_whoami_result.dns_domain_name == "" - - win_whoami_result.groups|count >= 1 - - win_whoami_result.groups[0].account_name is defined - - win_whoami_result.groups[0].attributes is defined - - win_whoami_result.groups[0].domain_name is defined - - win_whoami_result.groups[0].sid is defined - - win_whoami_result.groups[0].type is defined - - win_whoami_result.impersonation_level is defined - - win_whoami_result.label.account_name == 'High Mandatory Level' - - win_whoami_result.label.domain_name == 'Mandatory Label' - - win_whoami_result.label.sid == 'S-1-16-12288' - - win_whoami_result.label.type == 'Label' - - win_whoami_result.login_domain is defined - - win_whoami_result.login_time is defined - - win_whoami_result.logon_id is defined - - win_whoami_result.logon_server is defined - - win_whoami_result.logon_type == "Interactive" - - win_whoami_result.privileges is defined - - '"SeInteractiveLogonRight" in win_whoami_result.rights' - - win_whoami_result.token_type == 'TokenPrimary' - - win_whoami_result.upn == '' - - win_whoami_result.user_flags is defined - - - name: run win_whoami with limited become execution - win_whoami: - vars: *become_vars_limited - register: win_whoami_result - - - name: assert win_whoami with limited become execution - assert: - that: - - not win_whoami_result is changed - - win_whoami_result.account.account_name == "ansible_limited" - - win_whoami_result.account.domain_name is defined - - win_whoami_result.account.sid == become_user_info_limited.sid - - win_whoami_result.account.type == 'User' - - win_whoami_result.authentication_package == "NTLM" - - win_whoami_result.dns_domain_name == "" - - win_whoami_result.groups|count >= 1 - - win_whoami_result.groups[0].account_name is defined - - win_whoami_result.groups[0].attributes is defined - - win_whoami_result.groups[0].domain_name is defined - - win_whoami_result.groups[0].sid is defined - - win_whoami_result.groups[0].type is defined - - win_whoami_result.impersonation_level is defined - - win_whoami_result.label.account_name == 'Medium Mandatory Level' - - win_whoami_result.label.domain_name == 'Mandatory Label' - - win_whoami_result.label.sid == 'S-1-16-8192' - - win_whoami_result.label.type == 'Label' - - win_whoami_result.login_domain is defined - - win_whoami_result.login_time is defined - - win_whoami_result.logon_id is defined - - win_whoami_result.logon_server is defined - - win_whoami_result.logon_type == "Interactive" - - win_whoami_result.privileges is defined - - win_whoami_result.rights == [] - - win_whoami_result.token_type == 'TokenPrimary' - - win_whoami_result.upn == '' - - win_whoami_result.user_flags is defined - - always: - - name: ensure test user is deleted - win_user: - name: '{{item}}' - state: absent - with_items: - - '{{become_username}}' - - '{{become_username_limited}}' - - - name: ensure test user profile is deleted - win_shell: rmdir /S /Q {{profile_dir_out.stdout_lines[0]}} - args: - executable: cmd.exe - when: become_username in profile_dir_out.stdout_lines[0] - - - name: ensure limited test user profile is deleted - win_shell: rmdir /S /Q {{profile_dir_out_limited.stdout_lines[0]}} - args: - executable: cmd.exe - when: become_username_limited in profile_dir_out_limited.stdout_lines[0] diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 99383dc96e..46d8e9b4a5 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -3876,32 +3876,6 @@ lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py validate-modu lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py validate-modules:doc-missing-type lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py validate-modules:parameter-type-not-in-doc lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py validate-modules:doc-missing-type -lib/ansible/modules/windows/async_status.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/setup.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_acl_inheritance.ps1 pslint:PSAvoidTrailingWhitespace -lib/ansible/modules/windows/win_certificate_store.ps1 validate-modules:parameter-type-not-in-doc -lib/ansible/modules/windows/win_copy.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_dns_client.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_domain.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_domain.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_domain_controller.ps1 pslint:PSAvoidGlobalVars # New PR -lib/ansible/modules/windows/win_domain_controller.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_domain_controller.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSAvoidGlobalVars # New PR -lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_domain_membership.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_dsc.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_dsc.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_feature.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_find.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_find.ps1 validate-modules:doc-elements-mismatch -lib/ansible/modules/windows/win_optional_feature.ps1 validate-modules:parameter-list-no-elements -lib/ansible/modules/windows/win_regedit.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_share.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_shell.ps1 pslint:PSUseApprovedVerbs -lib/ansible/modules/windows/win_updates.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/modules/windows/win_uri.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep -lib/ansible/modules/windows/win_wait_for.ps1 pslint:PSCustomUseLiteralPath lib/ansible/parsing/vault/__init__.py pylint:blacklisted-name lib/ansible/playbook/base.py pylint:blacklisted-name lib/ansible/playbook/collectionsearch.py required-and-default-attributes # https://github.com/ansible/ansible/issues/61460 @@ -4088,24 +4062,14 @@ test/integration/targets/wait_for/files/testserver.py future-import-boilerplate test/integration/targets/wait_for/files/testserver.py metaclass-boilerplate test/integration/targets/want_json_modules_posix/library/helloworld.py future-import-boilerplate test/integration/targets/want_json_modules_posix/library/helloworld.py metaclass-boilerplate -test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 pslint!skip -test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip -test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 pslint!skip -test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip -test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 pslint!skip test/integration/targets/win_exec_wrapper/library/test_fail.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/win_module_utils/library/legacy_only_new_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings test/integration/targets/win_module_utils/library/legacy_only_old_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings -test/integration/targets/win_ping/library/win_ping_syntax_error.ps1 pslint!skip -test/integration/targets/win_reboot/templates/post_reboot.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/win_script/files/test_script.ps1 pslint:PSAvoidUsingWriteHost # Keep test/integration/targets/win_script/files/test_script_creates_file.ps1 pslint:PSAvoidUsingCmdletAliases test/integration/targets/win_script/files/test_script_removes_file.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/win_script/files/test_script_with_args.ps1 pslint:PSAvoidUsingWriteHost # Keep test/integration/targets/win_script/files/test_script_with_splatting.ps1 pslint:PSAvoidUsingWriteHost # Keep -test/integration/targets/win_stat/library/test_symlink_file.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_template/files/foo.dos.txt line-endings -test/integration/targets/win_user_right/library/test_get_right.ps1 pslint:PSCustomUseLiteralPath test/integration/targets/windows-minimal/library/win_ping_syntax_error.ps1 pslint!skip test/lib/ansible_test/_data/requirements/constraints.txt test-constraints test/lib/ansible_test/_data/requirements/integration.cloud.azure.txt test-constraints diff --git a/test/units/plugins/action/fixtures/synchronize/basic/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic/meta.yaml deleted file mode 100644 index 7608ebfaf3..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic/meta.yaml +++ /dev/null @@ -1,17 +0,0 @@ -fixtures: - taskvars_in: taskvars_in.json - taskvars_out: taskvars_out.json -connection: - transport: 'ssh' -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self._play_context.shell == 'sh'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'" diff --git a/test/units/plugins/action/fixtures/synchronize/basic/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic/task_args_out.json deleted file mode 100644 index 93ae7bbb5d..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic/task_args_out.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dest": "root@el6host:/tmp/deleteme", - "src": "/tmp/deleteme", - "_local_rsync_path": "rsync" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic/taskvars_in.json b/test/units/plugins/action/fixtures/synchronize/basic/taskvars_in.json deleted file mode 100644 index 9eb5d50ad1..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic/taskvars_in.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic/taskvars_out.json b/test/units/plugins/action/fixtures/synchronize/basic/taskvars_out.json deleted file mode 100644 index 01ebee2529..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic/taskvars_out.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic_become/meta.yaml deleted file mode 100644 index 1ba3b4ab9b..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become/meta.yaml +++ /dev/null @@ -1,38 +0,0 @@ -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme - #rsync_path: rsync -_task: - become: True - become_method: None -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -connection: - transport: 'ssh' -_play_context: - become: True - become_method: sudo - remote_addr: el6host - remote_user: root -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - # this is a crucial aspect of this scenario ... - - "self.final_module_args['rsync_path'] == 'sudo rsync'" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'" - - "self.task.become == True" - - "self.task.become_user == None" - - "self._play_context.shell == 'sh'" - - "self._play_context.remote_addr == 'el6host'" - - "self._play_context.remote_user == 'root'" - - "self._play_context.become == False" - - "self._play_context.become_user == 'root'" - - "self._play_context.password == None" diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic_become/task_args_out.json deleted file mode 100644 index 27f8e2581c..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become/task_args_out.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dest": "root@el6host:/tmp/deleteme", - "src": "/tmp/deleteme", - "rsync_path": "sudo rsync", - "_local_rsync_path": "rsync" -} diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_in.json deleted file mode 100644 index 0f1f9784a7..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_in.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_out.json deleted file mode 100644 index 75abced318..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become/task_vars_out.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic_become_cli/meta.yaml deleted file mode 100644 index 5e558012a5..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/meta.yaml +++ /dev/null @@ -1,38 +0,0 @@ -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme - #rsync_path: rsync -_task: - become: None - become_method: None -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -connection: - transport: 'ssh' -_play_context: - become: True - become_method: sudo - remote_addr: el6host - remote_user: root -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - # this is a crucial aspect of this scenario ... - - "self.final_module_args['rsync_path'] == 'sudo rsync'" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'" - - "self.task.become == None" - - "self.task.become_user == None" - - "self._play_context.shell == 'sh'" - - "self._play_context.remote_addr == 'el6host'" - - "self._play_context.remote_user == 'root'" - - "self._play_context.become == False" - - "self._play_context.become_user == 'root'" - - "self._play_context.password == None" diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_args_out.json deleted file mode 100644 index 27f8e2581c..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_args_out.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dest": "root@el6host:/tmp/deleteme", - "src": "/tmp/deleteme", - "rsync_path": "sudo rsync", - "_local_rsync_path": "rsync" -} diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_in.json deleted file mode 100644 index 0f1f9784a7..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_in.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_out.json deleted file mode 100644 index 75abced318..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_become_cli/task_vars_out.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "el6host", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "::1" - ], - "all": [ - "el6host", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host" - ], - "all": [ - "el6host" - ] - }, - "ansible_host": "el6host", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__b3ac1e6ebeed06f4be0c1edca3dca34036cf7f57", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic_vagrant/meta.yaml deleted file mode 100644 index 7654cc6d77..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/meta.yaml +++ /dev/null @@ -1,29 +0,0 @@ -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -connection: - transport: 'ssh' -_play_context: - remote_addr: '127.0.0.1' - remote_user: vagrant -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['dest_port'] == 2202" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'vagrant@127.0.0.1:/tmp/deleteme'" - - "self._play_context.shell == 'sh'" - - "self._play_context.remote_addr == '127.0.0.1'" - - "self._play_context.remote_user == 'vagrant'" - - "self._play_context.become == False" - - "self._play_context.become_user == 'root'" - - "self._play_context.password == None" diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_args_out.json deleted file mode 100644 index 48ea779d06..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_args_out.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "dest": "/tmp/deleteme", - "src": "/tmp/deleteme", - "private_key": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "dest_port": 2202, - "_local_rsync_path": "rsync" -} diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_in.json deleted file mode 100644 index a43a2db4c7..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_in.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_out.json deleted file mode 100644 index 26ea5d46c1..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant/task_vars_out.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__06c4a1b11530cabdf4248804078c1ddacfb88b5e", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/meta.yaml deleted file mode 100644 index 242de9208c..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/meta.yaml +++ /dev/null @@ -1,32 +0,0 @@ -task: - #become: None -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -connection: - transport: 'ssh' -_play_context: - become: True - remote_addr: '127.0.0.1' - remote_user: vagrant -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['dest_port'] == 2202" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'vagrant@127.0.0.1:/tmp/deleteme'" - - "self._play_context.shell == 'sh'" - - "self._play_context.remote_addr == '127.0.0.1'" - - "self._play_context.remote_user == 'vagrant'" - - "self._play_context.become == False" - - "self._play_context.become_user == 'root'" - - "self._play_context.password == None" diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_args_out.json deleted file mode 100644 index 9c77ccf8ae..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_args_out.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "dest": "/tmp/deleteme", - "src": "/tmp/deleteme", - "private_key": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "dest_port": 2202, - "_local_rsync_path": "rsync" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_in.json deleted file mode 100644 index 1ecbda5b60..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_in.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_out.json deleted file mode 100644 index a1cf5f28fc..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_become_cli/task_vars_out.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/meta.yaml b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/meta.yaml deleted file mode 100644 index 7654cc6d77..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/meta.yaml +++ /dev/null @@ -1,29 +0,0 @@ -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -connection: - transport: 'ssh' -_play_context: - remote_addr: '127.0.0.1' - remote_user: vagrant -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'local'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['dest_port'] == 2202" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'vagrant@127.0.0.1:/tmp/deleteme'" - - "self._play_context.shell == 'sh'" - - "self._play_context.remote_addr == '127.0.0.1'" - - "self._play_context.remote_user == 'vagrant'" - - "self._play_context.become == False" - - "self._play_context.become_user == 'root'" - - "self._play_context.password == None" diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_args_out.json deleted file mode 100644 index 9c77ccf8ae..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_args_out.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "dest": "/tmp/deleteme", - "src": "/tmp/deleteme", - "private_key": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "dest_port": 2202, - "_local_rsync_path": "rsync" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_in.json deleted file mode 100644 index 1ecbda5b60..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_in.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_out.json deleted file mode 100644 index a1cf5f28fc..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/basic_vagrant_sudo/task_vars_out.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "vagrant", - "ansible_play_hosts": [ - "default" - ], - "ansible_connection": "ssh", - "ansible_ssh_common_args": "", - "ansible_ssh_host": "127.0.0.1", - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "vars": { - "ansible_check_mode": false, - "environment": [], - "inventory_hostname": "default", - "inventory_file": null, - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "play_hosts": [ - "default" - ], - "ansible_play_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_ssh_port": 2202, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "vagrant" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "environment": [], - "ansible_current_hosts": [ - "default" - ], - "hostvars": { - "default": { - "inventory_file": null, - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "default", - "::1" - ], - "all": [ - "default", - "::1" - ] - }, - "ansible_ssh_port": 2202, - "inventory_hostname": "default", - "ansible_ssh_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "inventory_hostname_short": "default", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "ansible_ssh_host": "127.0.0.1", - "ansible_ssh_user": "vagrant", - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": null, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "ansible_port": 2202, - "ansible_private_key_file": "/home/jtanner/workspace/issues/AP-15905/.vagrant/machines/default/virtualbox/private_key", - "groups": { - "ungrouped": [ - "default" - ], - "all": [ - "default" - ] - }, - "ansible_ssh_port": 2202, - "ansible_host": "127.0.0.1", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "default", - "omit": "__omit_place_holder__c360b80aa60ddd99087425dcd3a2094cdd5b8474", - "ansible_python_interpreter": "/usr/bin/python", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905/.vagrant/provisioners/ansible/inventory", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "vagrant", - "role_names": [], - "play_hosts": [ - "default" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote/meta.yaml b/test/units/plugins/action/fixtures/synchronize/delegate_remote/meta.yaml deleted file mode 100644 index 1c55b2856a..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote/meta.yaml +++ /dev/null @@ -1,26 +0,0 @@ -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme -_task: - delegate_to: u1404 -_play_context: - shell: None - remote_addr: u1404 - remote_user: root -connection: - transport: 'ssh' -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'ssh'" - - "self._play_context.shell == None" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'" diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_args_out.json deleted file mode 100644 index 7b2ac0299d..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_args_out.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dest": "el6host:/tmp/deleteme", - "src": "/tmp/deleteme", - "_local_rsync_path": "rsync" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_in.json deleted file mode 100644 index b8893eef85..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_in.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "inventory_file": "inventory", - "role_names": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "u1404", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "role_names": [] - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_host": "u1404", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_out.json deleted file mode 100644 index 0b551f041d..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote/task_vars_out.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "inventory_file": "inventory", - "role_names": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "u1404", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "role_names": [] - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_host": "u1404", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/meta.yaml b/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/meta.yaml deleted file mode 100644 index 28e35c9e32..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/meta.yaml +++ /dev/null @@ -1,33 +0,0 @@ -fixtures: - taskvars_in: task_vars_in.json - taskvars_out: task_vars_out.json -task_args: - src: /tmp/deleteme - dest: /tmp/deleteme -_task: - delegate_to: u1404 -_play_context: - become: True - become_user: None #if ! None|root, different testcase - become_method: su - shell: None - remote_addr: u1404 - remote_user: root -connection: - transport: 'ssh' -hostvars: - '127.0.0.1': {} - '::1': {} - 'localhost': {} -asserts: - - "hasattr(SAM._connection, 'ismock')" - - "SAM._connection.transport == 'ssh'" - - "self._play_context.shell == None" - - "self._play_context.remote_addr == 'u1404'" - - "self._play_context.remote_user == 'root'" - - "not self._play_context.become" - - "self._play_context.become_method == 'su'" - - "self.execute_called" - - "self.final_module_args['_local_rsync_path'] == 'rsync'" - - "self.final_module_args['src'] == '/tmp/deleteme'" - - "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'" diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_args_out.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_args_out.json deleted file mode 100644 index 57257dbd5b..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_args_out.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dest": "el6host:/tmp/deleteme", - "src": "/tmp/deleteme", - "rsync_path": "sudo rsync", - "_local_rsync_path": "rsync" -} diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_in.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_in.json deleted file mode 100644 index 634bcb3ffe..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_in.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "inventory_file": "inventory", - "role_names": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "u1404", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "role_names": [] - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_host": "u1404", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_out.json b/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_out.json deleted file mode 100644 index 54707ce830..0000000000 --- a/test/units/plugins/action/fixtures/synchronize/delegate_remote_su/task_vars_out.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "ansible_pipelining": false, - "ansible_docker_extra_args": "", - "ansible_scp_extra_args": "", - "ansible_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "ansible_connection": "smart", - "ansible_ssh_common_args": "", - "environment": [], - "inventory_hostname": "el6host", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "el6host", - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "inventory_file": "inventory", - "role_names": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "role_names": [], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "play_hosts": [ - "el6host" - ], - "ansible_play_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - }, - "ansible_accelerate_port": 5099, - "roledir": null, - "ansible_ssh_extra_args": "", - "ansible_ssh_host": "u1404", - "ansible_current_hosts": [ - "el6host" - ], - "hostvars": { - "el6host": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "el6host", - "inventory_hostname_short": "el6host", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - }, - "u1404": { - "inventory_file": "inventory", - "group_names": [ - "ungrouped" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404", - "::1" - ], - "all": [ - "el6host", - "u1404", - "::1" - ] - }, - "inventory_hostname": "u1404", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "ansible_check_mode": false, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - } - } - }, - "group_names": [ - "ungrouped" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_pipelining": false, - "inventory_file": "inventory", - "ansible_delegated_vars": { - "u1404": { - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "vars": { - "ansible_check_mode": false, - "inventory_hostname": "u1404", - "inventory_file": "inventory", - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "environment": [], - "ansible_ssh_user": "root", - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "group_names": [ - "ungrouped" - ], - "play_hosts": [ - "el6host" - ], - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "role_names": [] - }, - "inventory_hostname_short": "u1404", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "group_names": [ - "ungrouped" - ], - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "ansible_host": "u1404", - "environment": [], - "ansible_play_hosts": [ - "el6host" - ], - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_check_mode": false, - "play_hosts": [ - "el6host" - ], - "role_names": [], - "ansible_port": null, - "ansible_version": { - "major": 2, - "full": "2.2.0", - "string": "2.2.0", - "minor": 2, - "revision": 0 - }, - "ansible_ssh_user": "root" - } - }, - "ansible_module_compression": "ZIP_DEFLATED", - "ansible_failed_hosts": [], - "ansible_check_mode": false, - "groups": { - "ungrouped": [ - "el6host", - "u1404" - ], - "all": [ - "el6host", - "u1404" - ] - }, - "ansible_host": "u1404", - "ansible_shell_executable": "/bin/sh", - "inventory_hostname_short": "el6host", - "omit": "__omit_place_holder__32a8706cee222390e0d92197fb49cc967bfafb57", - "inventory_dir": "/home/jtanner/workspace/issues/AP-15905", - "playbook_dir": "/home/jtanner/workspace/issues/AP-15905", - "ansible_ssh_user": "root", - "role_names": [], - "play_hosts": [ - "el6host" - ], - "ansible_sftp_extra_args": "" -}
\ No newline at end of file diff --git a/test/units/plugins/action/test_win_updates.py b/test/units/plugins/action/test_win_updates.py deleted file mode 100644 index 021090c5e9..0000000000 --- a/test/units/plugins/action/test_win_updates.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# (c) 2018, Jordan Borean <jborean@redhat.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os -import pytest - -from units.compat.mock import patch, MagicMock -from ansible.plugins.action.win_updates import ActionModule -from ansible.plugins.become.runas import BecomeModule -from ansible.playbook.task import Task - - -@pytest.fixture() -def test_win_updates(): - task = MagicMock(Task) - task.args = {} - - connection = MagicMock() - connection.module_implementation_preferences = ('.ps1', '.exe', '') - - play_context = MagicMock() - play_context.check_mode = False - - plugin = ActionModule(task, connection, play_context, loader=None, templar=None, shared_loader_obj=None) - return plugin - - -class TestWinUpdatesActionPlugin(object): - - INVALID_OPTIONS = ( - ( - {"state": "invalid"}, - False, - "state must be either installed, searched or downloaded" - ), - ( - {"reboot": "nonsense"}, - False, - "cannot parse reboot as a boolean: The value 'nonsense' is not a " - "valid boolean." - ), - ( - {"reboot_timeout": "string"}, - False, - "reboot_timeout must be an integer" - ), - ( - {"reboot": True}, - True, - "async is not supported for this task when reboot=yes" - ) - ) - - # pylint bug: https://github.com/PyCQA/pylint/issues/511 - # pylint: disable=undefined-variable - @pytest.mark.parametrize('task_args, async_val, expected', - ((t, a, e) for t, a, e in INVALID_OPTIONS)) - def test_invalid_options(self, task_args, async_val, expected): - task = MagicMock(Task) - task.args = task_args - task.async_val = async_val - - connection = MagicMock() - play_context = MagicMock() - play_context.check_mode = False - - plugin = ActionModule(task, connection, play_context, loader=None, - templar=None, shared_loader_obj=None) - res = plugin.run() - assert res['failed'] - assert expected in res['msg'] - - def test_exec_with_become(self, test_win_updates): - test_become = os.urandom(8) - - set_become_mock = MagicMock() - test_win_updates._connection.become = test_become - test_win_updates._connection.set_become_plugin = set_become_mock - - with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): - test_win_updates._execute_module_with_become('win_updates', {}, {}, True, False) - - # Asserts we don't override the become plugin. - assert set_become_mock.call_count == 1 - assert set_become_mock.mock_calls[0][1][0] == test_become - - def test_exec_with_become_no_plugin_set(self, test_win_updates): - set_become_mock = MagicMock() - test_win_updates._connection.become = None - test_win_updates._connection.set_become_plugin = set_become_mock - - with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): - test_win_updates._execute_module_with_become('win_updates', {}, {}, True, False) - - assert set_become_mock.call_count == 2 - assert isinstance(set_become_mock.mock_calls[0][1][0], BecomeModule) - assert set_become_mock.mock_calls[0][1][0].name == 'runas' - assert set_become_mock.mock_calls[0][1][0].get_option('become_user') == 'SYSTEM' - assert set_become_mock.mock_calls[0][1][0].get_option('become_flags') == '' - assert set_become_mock.mock_calls[0][1][0].get_option('become_pass') is None - assert set_become_mock.mock_calls[1][1] == (None,) - - def test_exec_with_become_no_plugin_set_use_task(self, test_win_updates): - set_become_mock = MagicMock() - test_win_updates._connection.become = None - test_win_updates._connection.set_become_plugin = set_become_mock - - with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): - test_win_updates._execute_module_with_become('win_updates', {}, {}, True, True) - - assert set_become_mock.call_count == 1 - assert set_become_mock.mock_calls[0][1][0] is None - - def test_module_exec_async_result(self, monkeypatch): - return_val = { - "ansible_async_watchdog_pid": 7584, - "ansible_job_id": "545519115287.9620", - "changed": True, - "finished": 0, - "results_file": r"C:\.ansible_async\545519115287.9620", - "started": 1 - } - mock_execute = MagicMock(return_value=return_val) - monkeypatch.setattr(ActionModule, '_execute_module', mock_execute) - - task = MagicMock(Task) - task.args = {} - task.async_val = 10 - - connection = MagicMock() - connection.module_implementation_preferences = ('.ps1', '.exe', '') - - play_context = MagicMock() - play_context.check_mode = False - play_context.become = True - play_context.become_method = 'runas' - play_context.become_user = 'SYSTEM' - - plugin = ActionModule(task, connection, play_context, loader=None, - templar=None, shared_loader_obj=None) - actual = plugin.run(None, {}) - - assert actual.get('failed') is None - assert actual['ansible_async_watchdog_pid'] == 7584 - assert actual['ansible_job_id'] == "545519115287.9620" - assert actual['changed'] is True - assert actual['finished'] == 0 - assert actual['results_file'] == r"C:\.ansible_async\545519115287.9620" - assert actual['started'] == 1 |