Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ec2 facts module #1886

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Ansible Changes By Release
* SELinux fix for files created by authorized_key module
* "template override" ??
* lots of documentation tweaks
* handle tilde shell character for --private-key

* ...

Expand Down
2 changes: 1 addition & 1 deletion docsite/rst/gettingstarted.rst
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ Set up SSH agent to avoid retyping passwords:
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa

(Depending on your setup, you may wish to ansible's --private-key-file option to specify a pem file instead)
(Depending on your setup, you may wish to ansible's --private-key option to specify a pem file instead)

Now ping all your nodes:

Expand Down
26 changes: 23 additions & 3 deletions docsite/rst/playbooks2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,26 @@ Here are various examples of 'when' in use. 'when' is incompatible with 'only_i
The when_boolean check will look for variables that look to be true as well, such as the string 'True' or
'true', non-zero numbers, and so on.

We also added when_changed and when_failed so users can execute tasks based on the status of previously
registered tasks. As an example::

- name: "register a task that might fail"
action: shell /bin/false
register: result
ignore_errors: True

- name: "do this if the registered task failed"
action: shell /bin/true
when_failed: $result

- name: "register a task that might change"
action: yum pkg=httpd state=latest
register: result

- name: "do this if the registered task changed"
action: shell /bin/true
when_changed: $result

Conditional Imports
```````````````````

Expand Down Expand Up @@ -757,11 +777,11 @@ to determine which place sets the value of the variable.

1. Variables loaded from YAML files mentioned in 'vars_files' in a playbook.

2. 'vars' as defined in the playbook.
2. facts, whether built in or custom, or variables assigned from the 'register' keyword.

3. facts, whether built in or custom, or variables assigned from the 'register' keyword.
3. variables passed to parameterized task include statements.

4. variables passed to parameterized task include statements.
4. 'vars' as defined in the playbook.

5. Host variables from inventory.

Expand Down
4 changes: 3 additions & 1 deletion examples/playbooks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
- name: "some_password"
prompt: "Enter password"
private: yes

- name: "release_version"
prompt: "Product release version"
default: "my_default_version"
private: no

- name: "my_password2"
Expand All @@ -48,7 +50,7 @@
tasks:

- name: imagine this did something interesting with $release_version
action: shell echo foo >> /tmp/$release_version-$alpha
action: shell echo foo >> /tmp/$release_version-alpha

- name: look we crypted a password
action: shell echo my password is $my_password2
Expand Down
2 changes: 1 addition & 1 deletion lib/ansible/callback_plugins/noop.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def on_no_hosts_remaining(self):
def playbook_on_task_start(self, name, is_conditional):
pass

def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None):
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
pass

def playbook_on_setup(self):
Expand Down
11 changes: 9 additions & 2 deletions lib/ansible/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def on_task_start(self, name, is_conditional):
print banner(msg)
call_callback_module('playbook_on_task_start', name, is_conditional)

def on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None):
def on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):

if prompt:
msg = "%s: " % prompt
Expand All @@ -458,10 +458,17 @@ def prompt(prompt, private):
else:
result = prompt(msg, private)

# if result is false and default is not None
if not result and default:
result = default


if encrypt:
result = utils.do_encrypt(result,encrypt,salt_size,salt)

call_callback_module('playbook_on_vars_prompt', varname, private=private, prompt=prompt, encrypt=encrypt, confirm=confirm, salt_size=salt_size, salt=None)
call_callback_module( 'playbook_on_vars_prompt', varname, private=private, prompt=prompt,
encrypt=encrypt, confirm=confirm, salt_size=salt_size, salt=None, default=default
)

return result

Expand Down
12 changes: 9 additions & 3 deletions lib/ansible/playbook/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def _get_vars(self):

vname = var['name']
prompt = var.get("prompt", vname)
default = var.get("default", None)
private = var.get("private", True)

confirm = var.get("confirm", False)
Expand All @@ -197,13 +198,17 @@ def _get_vars(self):
salt = var.get("salt", None)

if vname not in self.playbook.extra_vars:
vars[vname] = self.playbook.callbacks.on_vars_prompt(vname, private, prompt,encrypt, confirm, salt_size, salt)
vars[vname] = self.playbook.callbacks.on_vars_prompt (
vname, private, prompt, encrypt, confirm, salt_size, salt, default
)

elif type(self.vars_prompt) == dict:
for (vname, prompt) in self.vars_prompt.iteritems():
prompt_msg = "%s: " % prompt
if vname not in self.playbook.extra_vars:
vars[vname] = self.playbook.callbacks.on_vars_prompt(varname=vname, private=False, prompt=prompt_msg)
vars[vname] = self.playbook.callbacks.on_vars_prompt(
varname=vname, private=False, prompt=prompt_msg, default=None
)

else:
raise errors.AnsibleError("'vars_prompt' section is malformed, see docs")
Expand Down Expand Up @@ -256,8 +261,9 @@ def _update_vars_files_for_host(self, host):
self.vars_files = [ self.vars_files ]

if host is not None:
inject = self.playbook.SETUP_CACHE[host].copy()
inject = {}
inject.update(self.playbook.inventory.get_variables(host))
inject.update(self.playbook.SETUP_CACHE[host])

for filename in self.vars_files:

Expand Down
6 changes: 5 additions & 1 deletion lib/ansible/runner/connection_plugins/paramiko_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ def _connect_uncached(self):
if self.runner.remote_pass is not None:
allow_agent = False
try:
if self.runner.private_key_file:
key_filename = os.path.expanduser(self.runner.private_key_file)
else:
key_filename = None
ssh.connect(self.host, username=user, allow_agent=allow_agent, look_for_keys=True,
key_filename=self.runner.private_key_file, password=self.runner.remote_pass,
key_filename=key_filename, password=self.runner.remote_pass,
timeout=self.runner.timeout, port=self.port)
except Exception, e:
msg = str(e)
Expand Down
2 changes: 1 addition & 1 deletion lib/ansible/runner/connection_plugins/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def connect(self):
if self.port is not None:
self.common_args += ["-o", "Port=%d" % (self.port)]
if self.runner.private_key_file is not None:
self.common_args += ["-o", "IdentityFile="+self.runner.private_key_file]
self.common_args += ["-o", "IdentityFile="+os.path.expanduser(self.runner.private_key_file)]
if self.runner.remote_pass:
self.common_args += ["-o", "GSSAPIAuthentication=no",
"-o", "PubkeyAuthentication=no"]
Expand Down
2 changes: 1 addition & 1 deletion lib/ansible/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
help='ask for sudo password')
parser.add_option('-M', '--module-path', dest='module_path',
help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
default=constants.DEFAULT_MODULE_PATH)
default=None)

if subset_opts:
parser.add_option('-l', '--limit', default=constants.DEFAULT_SUBSET, dest='subset',
Expand Down
95 changes: 95 additions & 0 deletions library/ec2_facts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/python -tt
# -*- coding: utf-8 -*-

# 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: ec2_facts
short_description: Gathers facts about remote hosts within ec2 (aws)
options: {}
description:
- This module fetches data from the metadata servers in ec2 (aws).
notes:
- The module can add parameters to filter ec2_facts based on it.
Some of the facts are not returned ( like mapping of the devices - but
can be add it on).
examples:
- code: ansible all -m ec2_facts --tree /tmp/facts
description: Obtain facts from ec2 metatdata servers. You will need to
run an instance within ec2.
author: Silviu Dicu
'''

import urllib2
import socket

socket.setdefaulttimeout(5)

class Ec2Metadata(object):

ec2_metadata_server = 'http://169.254.169.254/latest/meta-data/'
ec2_sshdata_server = 'http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key'
ec2_userdata_server = 'http://169.254.169.254/latest/user-data/'

def __init__(self, ec2_metadata_server=None, ec2_sshdata_server=None, ec2_userdata_server=None):
self.url_meta = ec2_metadata_server or self.ec2_metadata_server
self.url_user = ec2_userdata_server or self.ec2_userdata_server
self.url_ssh = ec2_sshdata_server or self.ec2_sshdata_server

def _fetch(self, url):
try:
return urllib2.urlopen(url).read()
except urllib2.HTTPError:
return
except urllib2.URLError:
return

def run(self, field=None):
data = {}
raw_fields = self._fetch(self.url_meta)
if not raw_fields:
return data
fields = raw_fields.split('\n')
for field in fields:
if field.endswith('/'): continue # deal with this later
field_data = self._fetch(self.url_meta + field)
if field == 'security-groups':
sg_fields = ",".join(field_data.split('\n'))
data['ansible_ec2_%s' % field] = sg_fields
else:
data['ansible_ec2_%s' % field] = field_data
data['ansible_ec2_%s' % 'user-data'] = self._fetch(self.url_user)
data['ensible_ec2_%s' % 'public-keys'] = self._fetch(self.url_ssh)
return data


def main():
ec2_facts = Ec2Metadata().run()
ec2_facts_result = {
"changed" : True,
"ansible_facts" : ec2_facts
}
module = AnsibleModule(
argument_spec = dict()
)
module.exit_json(**ec2_facts_result)

# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>

main()
8 changes: 4 additions & 4 deletions library/yum
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def what_provides(module, repoq, req_spec, conf_file, qf=def_qf, en_repos=[], d

return []

def local_nvra(path):
def local_nvra(module, path):
"""return nvra of a local rpm passed in"""

cmd = ['/bin/rpm', '-qp' ,'--qf',
Expand Down Expand Up @@ -297,7 +297,7 @@ def pkg_to_dict(pkgstr):

return d

def repolist(repoq, qf="%{repoid}"):
def repolist(module, repoq, qf="%{repoid}"):

cmd = repoq + ["--qf", qf, "-a"]
rc,out,err = module.run_command(cmd)
Expand All @@ -320,7 +320,7 @@ def list_stuff(module, conf_file, stuff):
elif stuff == 'available':
return [ pkg_to_dict(p) for p in is_available(module, repoq, '-a', conf_file, qf=qf) if p.strip() ]
elif stuff == 'repos':
return [ dict(repoid=name, state='enabled') for name in repolist(repoq) if name.strip() ]
return [ dict(repoid=name, state='enabled') for name in repolist(module, repoq) if name.strip() ]
else:
return [ pkg_to_dict(p) for p in is_installed(module, repoq, stuff, conf_file, qf=qf) + is_available(module, repoq, stuff, conf_file, qf=qf) if p.strip() ]

Expand All @@ -343,7 +343,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
res['msg'] += "No Package file matching '%s' found on system" % spec
module.fail_json(**res)

nvra = local_nvra(spec)
nvra = local_nvra(module, spec)
# look for them in the rpmdb
if is_installed(module, repoq, nvra, conf_file, en_repos=en_repos, dis_repos=dis_repos):
# if they are there, skip it
Expand Down
2 changes: 1 addition & 1 deletion plugins/callbacks/log_plays.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def playbook_on_notify(self, host, handler):
def playbook_on_task_start(self, name, is_conditional):
pass

def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None):
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
pass

def playbook_on_setup(self):
Expand Down
2 changes: 1 addition & 1 deletion plugins/callbacks/osx_say.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def playbook_on_task_start(self, name, is_conditional):
else:
say("Notifying task: %s" % name, REGULAR_VOICE)

def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None):
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
pass

def playbook_on_setup(self):
Expand Down