From 3e72a0657dd082652c479426f9fe6ccadb9852ea Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Fri, 22 May 2015 13:25:05 -0500 Subject: [PATCH] Re-reverting windows modules PR #384 --- lib/ansible/modules/windows/win_copy.ps1 | 84 ++++++++++++++++ lib/ansible/modules/windows/win_copy.py | 60 +++++++++++ lib/ansible/modules/windows/win_file.ps1 | 105 ++++++++++++++++++++ lib/ansible/modules/windows/win_file.py | 73 ++++++++++++++ lib/ansible/modules/windows/win_stat.ps1 | 6 +- lib/ansible/modules/windows/win_template.py | 52 ++++++++++ 6 files changed, 376 insertions(+), 4 deletions(-) create mode 100644 lib/ansible/modules/windows/win_copy.ps1 create mode 100644 lib/ansible/modules/windows/win_copy.py create mode 100644 lib/ansible/modules/windows/win_file.ps1 create mode 100644 lib/ansible/modules/windows/win_file.py create mode 100644 lib/ansible/modules/windows/win_template.py diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1 new file mode 100644 index 00000000000..9ffdab85f03 --- /dev/null +++ b/lib/ansible/modules/windows/win_copy.ps1 @@ -0,0 +1,84 @@ +#!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 . + +# WANT_JSON +# POWERSHELL_COMMON + +$params = Parse-Args $args; + +$src= Get-Attr $params "src" $FALSE; +If ($src -eq $FALSE) +{ + Fail-Json (New-Object psobject) "missing required argument: src"; +} + +$dest= Get-Attr $params "dest" $FALSE; +If ($dest -eq $FALSE) +{ + Fail-Json (New-Object psobject) "missing required argument: dest"; +} + +# seems to be supplied by the calling environment, but +# probably shouldn't be a test for it existing in the params. +# TODO investigate. +$original_basename = Get-Attr $params "original_basename" $FALSE; +If ($original_basename -eq $FALSE) +{ + Fail-Json (New-Object psobject) "missing required argument: original_basename "; +} + +$result = New-Object psobject @{ + changed = $FALSE +}; + +# if $dest is a dir, append $original_basename so the file gets copied with its intended name. +if (Test-Path $dest -PathType Container) +{ + $dest = Join-Path $dest $original_basename; +} + +If (Test-Path $dest) +{ + $dest_checksum = Get-FileChecksum ($dest); + $src_checksum = Get-FileChecksum ($src); + + If (! $src_checksum.CompareTo($dest_checksum)) + { + # New-Item -Force creates subdirs for recursive copies + New-Item -Force $dest -Type file; + Copy-Item -Path $src -Destination $dest -Force; + } + $dest_checksum = Get-FileChecksum ($dest); + If ( $src_checksum.CompareTo($dest_checksum)) + { + $result.changed = $TRUE; + } + Else + { + Fail-Json (New-Object psobject) "Failed to place file"; + } +} +Else +{ + New-Item -Force $dest -Type file; + Copy-Item -Path $src -Destination $dest; + $result.changed = $TRUE; +} + +$dest_checksum = Get-FileChecksum($dest); +$result.checksum = $dest_checksum; + +Exit-Json $result; diff --git a/lib/ansible/modules/windows/win_copy.py b/lib/ansible/modules/windows/win_copy.py new file mode 100644 index 00000000000..7d0b49e5985 --- /dev/null +++ b/lib/ansible/modules/windows/win_copy.py @@ -0,0 +1,60 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Michael DeHaan +# +# 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 . + +import os +import time + +DOCUMENTATION = ''' +--- +module: win_copy +version_added: "1.8" +short_description: Copies files to remote locations on windows hosts. +description: + - The M(win_copy) module copies a file on the local box to remote windows locations. +options: + 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 recursively. In this case, if path ends + with "/", only inside contents of that directory are copied to destination. + Otherwise, if it does not end with "/", the directory itself with all contents + is copied. This behavior is similar to Rsync. + required: false + default: null + aliases: [] + dest: + description: + - Remote absolute path where the file should be copied to. If src is a directory, + this must be a directory too. Use \\ for path separators. + required: true + default: null +author: Michael DeHaan +notes: + - The "win_copy" module recursively copy facility does not scale to lots (>hundreds) of files. + Instead, you may find it better to create files locally, perhaps using win_template, and + then use win_get_url to put them in the correct location. +''' + +EXAMPLES = ''' +# Example from Ansible Playbooks +- win_copy: src=/srv/myfiles/foo.conf dest=c:\\TEMP\\foo.conf + +''' + diff --git a/lib/ansible/modules/windows/win_file.ps1 b/lib/ansible/modules/windows/win_file.ps1 new file mode 100644 index 00000000000..62ac81fc1ee --- /dev/null +++ b/lib/ansible/modules/windows/win_file.ps1 @@ -0,0 +1,105 @@ +#!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 . + +# WANT_JSON +# POWERSHELL_COMMON + +$params = Parse-Args $args; + +# path +$path = Get-Attr $params "path" $FALSE; +If ($path -eq $FALSE) +{ + $path = Get-Attr $params "dest" $FALSE; + If ($path -eq $FALSE) + { + $path = Get-Attr $params "name" $FALSE; + If ($path -eq $FALSE) + { + Fail-Json (New-Object psobject) "missing required argument: path"; + } + } +} + +# JH Following advice from Chris Church, only allow the following states +# in the windows version for now: +# state - file, directory, touch, absent +# (originally was: state - file, link, directory, hard, touch, absent) + +$state = Get-Attr $params "state" "file"; + +#$recurse = Get-Attr $params "recurse" "no"; + +# force - yes, no +# $force = Get-Attr $params "force" "no"; + +# result +$result = New-Object psobject @{ + changed = $FALSE +}; + +If ( $state -eq "touch" ) +{ + If(Test-Path $path) + { + (Get-ChildItem $path).LastWriteTime = Get-Date + } + Else + { + echo $null > $file + } + $result.changed = $TRUE; +} + +If (Test-Path $path) +{ + $fileinfo = Get-Item $path; + If ( $state -eq "absent" ) + { + Remove-Item -Recurse -Force $fileinfo; + $result.changed = $TRUE; + } + Else + { + # Only files have the .Directory attribute. + If ( $state -eq "directory" -and $fileinfo.Directory ) + { + Fail-Json (New-Object psobject) "path is not a directory"; + } + + # Only files have the .Directory attribute. + If ( $state -eq "file" -and -not $fileinfo.Directory ) + { + Fail-Json (New-Object psobject) "path is not a file"; + } + + } +} +Else +{ + If ( $state -eq "directory" ) + { + New-Item -ItemType directory -Path $path + $result.changed = $TRUE; + } + + If ( $state -eq "file" ) + { + Fail-Json (New-Object psobject) "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 new file mode 100644 index 00000000000..6a218216617 --- /dev/null +++ b/lib/ansible/modules/windows/win_file.py @@ -0,0 +1,73 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Michael DeHaan +# +# 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 . + + +DOCUMENTATION = ''' +--- +module: win_file +version_added: "1.8" +short_description: Creates, touches or removes files or directories. +extends_documentation_fragment: files +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. +notes: + - See also M(win_copy), M(win_template), M(copy), M(template), M(assemble) +requirements: [ ] +author: Michael DeHaan +options: + path: + description: + - 'path to the file being managed. Aliases: I(dest), I(name)' + required: true + default: [] + 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 `touch` works from the command line). + required: false + default: file + choices: [ file, directory, touch, absent ] +''' + +EXAMPLES = ''' +# create a file +- win_file: path=C:\\temp\\foo.conf + +# touch a file (creates if not present, updates modification time if present) +- win_file: path=C:\\temp\\foo.conf state=touch + +# remove a file, if present +- win_file: path=C:\\temp\\foo.conf state=absent + +# create directory structure +- win_file: path=C:\\temp\\folder\\subfolder state=directory + +# remove directory structure +- win_file: path=C:\\temp state=absent +''' diff --git a/lib/ansible/modules/windows/win_stat.ps1 b/lib/ansible/modules/windows/win_stat.ps1 index 4e4c55b2aa3..10101a62b30 100644 --- a/lib/ansible/modules/windows/win_stat.ps1 +++ b/lib/ansible/modules/windows/win_stat.ps1 @@ -53,11 +53,9 @@ Else If ($get_md5 -and $result.stat.exists -and -not $result.stat.isdir) { - $sp = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider; - $fp = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read); - $hash = [System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower(); - $fp.Dispose(); + $hash = Get-FileChecksum($path); Set-Attr $result.stat "md5" $hash; + Set-Attr $result.stat "checksum" $hash; } Exit-Json $result; diff --git a/lib/ansible/modules/windows/win_template.py b/lib/ansible/modules/windows/win_template.py new file mode 100644 index 00000000000..402702f93b2 --- /dev/null +++ b/lib/ansible/modules/windows/win_template.py @@ -0,0 +1,52 @@ +# this is a virtual module that is entirely implemented server side + +DOCUMENTATION = ''' +--- +module: win_template +version_added: 1.8 +short_description: Templates a file out to a remote server. +description: + - Templates are processed by the Jinja2 templating language + (U(http://jinja.pocoo.org/docs/)) - documentation on the template + formatting can be found in the Template Designer Documentation + (U(http://jinja.pocoo.org/docs/templates/)). + - "Six additional variables can be used in templates: C(ansible_managed) + (configurable via the C(defaults) section of C(ansible.cfg)) contains a string + which can be used to describe the template name, host, modification time of the + template file and the owner uid, C(template_host) contains the node name of + the template's machine, C(template_uid) the owner, C(template_path) the + absolute path of the template, C(template_fullpath) is the absolute path of the + template, and C(template_run_date) is the date that the template was rendered. Note that including + a string that uses a date in the template will result in the template being marked 'changed' + each time." +options: + src: + description: + - Path of a Jinja2 formatted template on the local server. This can be a relative or absolute path. + required: true + default: null + aliases: [] + dest: + description: + - Location to render the template to on the remote machine. + required: true + default: null + backup: + description: + - Create a backup file including the timestamp information so you can get + the original file back if you somehow clobbered it incorrectly. + required: false + choices: [ "yes", "no" ] + default: "no" +notes: + - "templates are loaded with C(trim_blocks=True)." +requirements: [] +author: Michael DeHaan +''' + +EXAMPLES = ''' +# Example +- win_template: src=/mytemplates/foo.j2 dest=C:\\temp\\file.conf + + +'''