Merge pull request #384 from jhawkesworth/win_copy_file_template_ansible_modules_core_1

Win copy/file/template modules (for ansible-modules-core)
This commit is contained in:
Brian Coca 2014-12-15 20:10:18 -05:00
commit 58bfebb047
6 changed files with 376 additions and 4 deletions

84
windows/win_copy.ps1 Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
# 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;

60
windows/win_copy.py Normal file
View file

@ -0,0 +1,60 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, 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/>.
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
'''

105
windows/win_file.ps1 Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
# 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;

73
windows/win_file.py Normal file
View file

@ -0,0 +1,73 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, 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/>.
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
'''

View file

@ -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;

52
windows/win_template.py Normal file
View file

@ -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
'''