Example #1
0
    def __init__(self):

        if 'HIPCHAT_TOKEN' in os.environ:
            self.start_time = time.time()
            self.task_report = []
            self.last_task = None
            self.last_task_changed = False
            self.last_task_count = 0
            self.last_task_delta = 0
            self.last_task_start = time.time()
            self.condensed_task_report = (os.getenv('HIPCHAT_CONDENSED',
                                                    True) == True)
            self.room = os.getenv('HIPCHAT_ROOM', 'ansible')
            self.from_name = os.getenv('HIPCHAT_FROM', 'ansible')
            self.allow_notify = (os.getenv('HIPCHAT_NOTIFY') != 'false')
            try:
                self.hipchat_conn = hipchat.HipChat(
                    token=os.getenv('HIPCHAT_TOKEN'))
            except Exception as e:
                utils.warning("Unable to connect to hipchat: {}".format(e))
            self.hipchat_msg_prefix = os.getenv('HIPCHAT_MSG_PREFIX', '')
            self.hipchat_msg_color = os.getenv('HIPCHAT_MSG_COLOR', '')
            self.printed_playbook = False
            self.playbook_name = None
            self.enabled = True
        else:
            self.enabled = False
    def __init__(self):
        self.disabled = truthy_string(os.getenv('ANSIBLE_AUDITLOG_DISABLED', 0))
        self.log_logname = truthy_string(
            os.getenv('ANSIBLE_AUDITLOG_LOGNAME_ENABLED', 1))
        logdir = os.getenv('ANSIBLE_AUDITLOG_LOGDIR', '/var/log/ansible')
        audit_vars = os.getenv('ANSIBLE_AUDITLOG_AUDIT_VARS', None)
        fail_mode = os.getenv('ANSIBLE_AUDITLOG_FAILMODE', 'warn')

        if self.disabled:
            utils.warning('Auditlog has been disabled!')
            return None

        # Example: version,my.nested.var
        if audit_vars:
            # Only allow alphanumeric + _ + .
            pattern = re.compile('[^\w.,]+', re.UNICODE)
            self.audit_vars = pattern.sub('', audit_vars).split(',')
            # convert to dict
            self.audit_vars = dict((el, 0) for el in self.audit_vars)
        else:
            self.audit_vars = {}

        try:
            self.logger = JsonAuditLogger(logdir=logdir)
        except Exception as e:
            msg = 'Unable to initialize audit logging: {}'.format(str(e))
            self.disabled = True
            utils.warning(msg)
            if fail_mode == 'fail':
                print(str(e))
                sys.exit(1)
    def __init__(self):

        if "HIPCHAT_TOKEN" in os.environ:
            self.start_time = time.time()
            self.task_report = []
            self.last_task = None
            self.last_task_changed = False
            self.last_task_count = 0
            self.last_task_delta = 0
            self.last_task_start = time.time()
            self.condensed_task_report = os.getenv("HIPCHAT_CONDENSED", True) == True
            self.room = os.getenv("HIPCHAT_ROOM", "ansible")
            self.from_name = os.getenv("HIPCHAT_FROM", "ansible")
            self.allow_notify = os.getenv("HIPCHAT_NOTIFY") != "false"
            try:
                self.hipchat_conn = hipchat.HipChat(token=os.getenv("HIPCHAT_TOKEN"))
            except Exception as e:
                utils.warning("Unable to connect to hipchat: {}".format(e))
            self.hipchat_msg_prefix = os.getenv("HIPCHAT_MSG_PREFIX", "")
            self.hipchat_msg_color = os.getenv("HIPCHAT_MSG_COLOR", "")
            self.printed_playbook = False
            self.playbook_name = None
            self.enabled = True
        else:
            self.enabled = False
Example #4
0
    def __init__(self):
        self.enabled = "HIPCHAT_TOKEN" in os.environ
        if not self.enabled:
            return

        # make sure we got our imports
        if not hipchat:
            raise ImportError(
                "The hipchat plugin requires the hipchat Python module, "
                "which is not installed or was not found.")
        if not prettytable:
            raise ImportError(
                "The hipchat plugin requires the prettytable Python module, "
                "which is not installed or was not found.")
        self.start_time = time.time()
        self.task_report = []
        self.last_task = None
        self.last_task_changed = False
        self.last_task_count = 0
        self.last_task_delta = 0
        self.last_task_start = time.time()
        self.condensed_task_report = (os.getenv('HIPCHAT_CONDENSED',
                                                True) == True)
        self.room = os.getenv('HIPCHAT_ROOM', 'ansible')
        self.from_name = os.getenv('HIPCHAT_FROM', 'ansible')
        self.allow_notify = (os.getenv('HIPCHAT_NOTIFY') != 'false')
        try:
            self.hipchat_conn = hipchat.HipChat(
                token=os.getenv('HIPCHAT_TOKEN'))
        except Exception as e:
            utils.warning("Unable to connect to hipchat: {}".format(e))
        self.hipchat_msg_prefix = os.getenv('HIPCHAT_MSG_PREFIX', '')
        self.hipchat_msg_color = os.getenv('HIPCHAT_MSG_COLOR', '')
        self.printed_playbook = False
        self.playbook_name = None
Example #5
0
    def __init__(self):
        self.enabled = "HIPCHAT_TOKEN" in os.environ
        if not self.enabled:
            return

        # make sure we got our imports
        if not hipchat:
            raise ImportError(
                "The hipchat plugin requires the hipchat Python module, " "which is not installed or was not found."
            )
        if not prettytable:
            raise ImportError(
                "The hipchat plugin requires the prettytable Python module, " "which is not installed or was not found."
            )
        self.start_time = time.time()
        self.task_report = []
        self.last_task = None
        self.last_task_changed = False
        self.last_task_count = 0
        self.last_task_delta = 0
        self.last_task_start = time.time()
        self.condensed_task_report = os.getenv("HIPCHAT_CONDENSED", True) == True
        self.room = os.getenv("HIPCHAT_ROOM", "ansible")
        self.from_name = os.getenv("HIPCHAT_FROM", "ansible")
        self.allow_notify = os.getenv("HIPCHAT_NOTIFY") != "false"
        try:
            self.hipchat_conn = hipchat.HipChat(token=os.getenv("HIPCHAT_TOKEN"))
        except Exception as e:
            utils.warning("Unable to connect to hipchat: {}".format(e))
        self.hipchat_msg_prefix = os.getenv("HIPCHAT_MSG_PREFIX", "")
        self.hipchat_msg_color = os.getenv("HIPCHAT_MSG_COLOR", "")
        self.printed_playbook = False
        self.playbook_name = None
	def __init__(self):
		self.opsmatic_http = get_config(p, "opsmatic", "opsmatic_http", "OPSMATIC_API_HTTP", "https://api.opsmatic.com")
		self.token = get_config(p, "opsmatic", "integration_token", "OPSMATIC_INTEGRATION_TOKEN", "")
		self.have_creds = self.token != ""
		if not self.have_creds:
			utils.warning("Opsmatic token is not set, so no events will be sent."
					  "It can be set via the `integration_token` varibale in the [opsmatic] section of ansible.cfg"
					  "OR via the OPSMATIC_INTEGRATION_TOKEN environment variable")
Example #7
0
    def set(self, key, value):

        self._cache[key] = value

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = codecs.open(cachefile, 'w', encoding='utf-8')
        except (OSError,IOError), e:
            utils.warning("error while trying to write to %s : %s" % (cachefile, str(e)))
Example #8
0
    def set(self, key, value):

        self._cache[key] = value

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = codecs.open(cachefile, 'w', encoding='utf-8')
        except (OSError,IOError), e:
            utils.warning("error while trying to write to %s : %s" % (cachefile, str(e)))
Example #9
0
    def has_expired(self, key):

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            st = os.stat(cachefile)
        except (OSError,IOError), e:
            if e.errno == errno.ENOENT:
                return False
            else:
                utils.warning("error while trying to stat %s : %s" % (cachefile, str(e)))
Example #10
0
    def set(self, key, value):

        self._cache[key] = value

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            #TODO: check if valid keys can have invalid FS chars, base32?
            f = open(cachefile, 'w')
        except (OSError,IOError), e:
            utils.warning("error while trying to read %s : %s" % (cachefile, str(e)))
Example #11
0
    def has_expired(self, key):

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            st = os.stat(cachefile)
        except (OSError,IOError), e:
            if e.errno == errno.ENOENT:
                return False
            else:
                utils.warning("error while trying to stat %s : %s" % (cachefile, str(e)))
Example #12
0
    def __init__(self):
        
        self.insights_token = os.getenv('NR_INSIGHTS_TOKEN')
        self.post_uri = os.getenv('NR_INSIGHTS_URI')
        self.user = getpass.getuser()

        if self.insights_token is None or self.post_uri is None:
            self.disabled = True
            utils.warning('New Relic Insights token or Post URI could not be loaded. The NR Insights '
                          'token and URI can be provided using the `NR_INSIGHTS_TOKEN` and `NR_INSIGHTS_URI`'
                          'environment variables.')
Example #13
0
    def set(self, key, value):

        self._cache[key] = value

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            #TODO: check if valid keys can have invalid FS chars, base32?
            f = open(cachefile, 'w')
        except (OSError, IOError), e:
            utils.warning("error while trying to read %s : %s" %
                          (cachefile, str(e)))
    def _send_hipchat(self, message, room=None, from_name=None, color=None, message_format="text"):

        if not room:
            room = self.room
        if not from_name:
            from_name = self.from_name
        if not color:
            color = self.hipchat_msg_color
        try:
            self.hipchat_conn.message_room(room, from_name, message, color=color, message_format=message_format)
        except Exception as e:
            utils.warning("Could not submit message to hipchat: {}".format(e))
Example #15
0
    def __init__(self, *args, **kwargs):

        self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
        self._cache = {}
        self._cache_dir = C.CACHE_PLUGIN_CONNECTION # expects a dir path

        if not os.path.exists(self._cache_dir):
            try:
                os.makedirs(self._cache_dir)
            except (OSError,IOError), e:
                utils.warning("error while trying to create cache dir %s : %s" % (self._cache_dir, str(e)))
                return None
Example #16
0
    def get(self, key):

        if key in self._cache:
            return self._cache.get(key)

        if self.has_expired(key):
           raise KeyError

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = codecs.open(cachefile, 'r', encoding='utf-8')
        except (OSError,IOError), e:
            utils.warning("error while trying to read %s : %s" % (cachefile, str(e)))
Example #17
0
    def get(self, key):

        if key in self._cache:
            return self._cache.get(key)

        if self.has_expired(key):
           raise KeyError

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = open( cachefile, 'r')
        except (OSError,IOError), e:
            utils.warning("error while trying to write to %s : %s" % (cachefile, str(e)))
Example #18
0
    def get(self, key):

        if key in self._cache:
            return self._cache.get(key)

        if self.has_expired(key):
           raise KeyError

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = codecs.open(cachefile, 'r', encoding='utf-8')
        except (OSError,IOError), e:
            utils.warning("error while trying to read %s : %s" % (cachefile, str(e)))
Example #19
0
    def get(self, key):

        if key in self._cache:
            return self._cache.get(key)

        if self.has_expired(key):
            raise KeyError

        cachefile = "%s/%s" % (self._cache_dir, key)
        try:
            f = open(cachefile, 'r')
        except (OSError, IOError), e:
            utils.warning("error while trying to write to %s : %s" %
                          (cachefile, str(e)))
Example #20
0
    def __init__(self, *args, **kwargs):

        self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
        self._cache = {}
        self._cache_dir = C.CACHE_PLUGIN_CONNECTION  # expects a dir path

        if not os.path.exists(self._cache_dir):
            try:
                os.makedirs(self._cache_dir)
            except (OSError, IOError), e:
                utils.warning(
                    "error while trying to create cache dir %s : %s" %
                    (self._cache_dir, str(e)))
                return None
Example #21
0
    def __init__(self, *args, **kwargs):

        self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
        self._cache = {}
        self._cache_dir = os.path.expandvars(os.path.expanduser(C.CACHE_PLUGIN_CONNECTION)) # expects a dir path
        if not self._cache_dir:
            utils.exit("error, fact_caching_connection is not set, cannot use fact cache")

        if not os.path.exists(self._cache_dir):
            try:
                os.makedirs(self._cache_dir)
            except (OSError,IOError), e:
                utils.warning("error while trying to create cache dir %s : %s" % (self._cache_dir, str(e)))
                return None
Example #22
0
    def run(self, terms, inject=None, **kwargs):

        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)

        if isinstance(terms, basestring):
            terms = [terms]

        validate_certs = kwargs.get('validate_certs', True)

        ret = []
        for term in terms:
            try:
                response = open_url(term, validate_certs=validate_certs)
            except urllib2.URLError as e:
                utils.warning("Failed lookup url for %s : %s" % (term, str(e)))
                continue
            except urllib2.HTTPError as e:
                utils.warning("Received HTTP error for %s : %s" %
                              (term, str(e)))
                continue
            except SSLValidationError as e:
                utils.warning(
                    "Error validating the server's certificate for %s: %s" %
                    (term, str(e)))
                continue
            except ConnectionError as e:
                utils.warning("Error connecting to %s: %s" % (term, str(e)))
                continue

            for line in response.read().splitlines():
                ret.append(to_unicode(line))
        return ret
Example #23
0
    def run(self, terms, inject=None, **kwargs):

        terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)

        if isinstance(terms, basestring):
            terms = [ terms ]

        validate_certs = kwargs.get('validate_certs', True)

        ret = []
        for term in terms:
            try:
                response = open_url(term, validate_certs=validate_certs)
            except urllib2.URLError as e:
                utils.warning("Failed lookup url for %s : %s" % (term, str(e)))
                continue
            except urllib2.HTTPError as e:
                utils.warning("Received HTTP error for %s : %s" % (term, str(e)))
                continue
            except SSLValidationError as e:
                utils.warning("Error validating the server's certificate for %s: %s" % (term, str(e)))
                continue
            except ConnectionError as e:
                utils.warning("Error connecting to %s: %s" % (term, str(e)))
                continue

            for line in response.read().splitlines():
                ret.append(to_unicode(line))
        return ret
Example #24
0
    def send_msg(self, msg):
        if not self.disabled:
            # JSON headers
            headers = {
                'Content-type': 'application/json',
                'Accept': 'text/plain'
            }

            # Send message to Slack endpoint
            try:
                response = requests.post(self.slack_endpoint,
                                         data=json.dumps(msg),
                                         headers=headers)
            except:
                utils.warning('Could not submit message to slack')
Example #25
0
    def contains(self, key):

        if key in self._cache:
            return True

        if self.has_expired(key):
            return False
        try:
            st = os.stat("%s/%s" % (self._cache_dir, key))
            return True
        except (OSError,IOError), e:
            if e.errno == errno.ENOENT:
                return False
            else:
                utils.warning("error while trying to stat %s : %s" % (cachefile, str(e)))
Example #26
0
    def send_msg(self, msg):
        if not self.disabled:
            # JSON headers
            headers = {
                'Content-type': 'application/json',
                'Accept': 'text/plain'
            }

            # Send message to Slack endpoint
            try:
                response = requests.post(self.slack_endpoint,
                                         data=json.dumps(msg),
                                         headers=headers)
            except:
                utils.warning('Could not submit message to slack')
Example #27
0
    def contains(self, key):

        if key in self._cache:
            return True

        if self.has_expired(key):
            return False
        try:
            st = os.stat("%s/%s" % (self._cache_dir, key))
            return True
        except (OSError, IOError), e:
            if e.errno == errno.ENOENT:
                return False
            else:
                utils.warning("error while trying to stat %s : %s" %
                              (cachefile, str(e)))
    def send_msg(self, msg, notify=False):
        """Method for sending a message to Slack"""

        params = {}
        params['channel'] = self.channel
        params['username'] = self.username[:15]  # max length is 15
        params['text'] = msg

        url = ('%s%s' % (self.msg_uri, self.token))
        try:
            data = json.dumps(params)
            req = urllib2.Request(url, data)
            response = urllib2.urlopen(req)
            return response.read()
        except:
            utils.warning('Could not submit message to Slack')
Example #29
0
    def send_msg(self, msg, msg_format='text', color='yellow', notify=False):
        """Method for sending a message to HipChat"""

        params = {}
        params['room_id'] = self.room
        params['from'] = self.from_name[:15]  # max length is 15
        params['message'] = msg
        params['message_format'] = msg_format
        params['color'] = color
        params['notify'] = int(notify)

        url = ('%s?auth_token=%s' % (self.msg_uri, self.token))
        try:
            response = urllib2.urlopen(url, urllib.urlencode(params))
            return response.read()
        except:
            utils.warning('Could not submit message to hipchat')
Example #30
0
    def send_msg(self, msg, msg_format='text', color='yellow', notify=False):
        """Method for sending a message to HipChat"""

        params = {}
        params['room_id'] = self.room
        params['from'] = self.from_name[:15]  # max length is 15
        params['message'] = msg
        params['message_format'] = msg_format
        params['color'] = color
        params['notify'] = int(self.allow_notify and notify)

        url = ('%s?auth_token=%s' % (self.msg_uri, self.token))
        try:
            response = open_url(url, data=urllib.urlencode(params))
            return response.read()
        except:
            utils.warning('Could not submit message to hipchat')
Example #31
0
    def __init__(self):
        if not HAS_PRETTYTABLE:
            self.disabled = True
            utils.warning('The `prettytable` python module is not installed. '
                          'Disabling the HipChat callback plugin.')

        self.msg_uri = 'https://api.hipchat.com/v1/rooms/message'
        self.token = os.getenv('HIPCHAT_TOKEN')
        self.room = os.getenv('HIPCHAT_ROOM', 'ansible')
        self.from_name = os.getenv('HIPCHAT_FROM', 'ansible')

        if self.token is None:
            self.disabled = True
            utils.warning('HipChat token could not be loaded. The HipChat '
                          'token can be provided using the `HIPCHAT_TOKEN` '
                          'environment variable.')

        self.printed_playbook = False
        self.playbook_name = None
Example #32
0
    def __init__(self):
        if not HAS_PRETTYTABLE:
            self.disabled = True
            utils.warning('The `prettytable` python module is not installed. '
                          'Disabling the HipChat callback plugin.')

        self.msg_uri = 'https://api.hipchat.com/v1/rooms/message'
        self.token = os.getenv('HIPCHAT_TOKEN')
        self.room = os.getenv('HIPCHAT_ROOM', 'ansible')
        self.from_name = os.getenv('HIPCHAT_FROM', 'ansible')
        self.allow_notify = (os.getenv('HIPCHAT_NOTIFY') != 'false')

        if self.token is None:
            self.disabled = True
            utils.warning('HipChat token could not be loaded. The HipChat '
                          'token can be provided using the `HIPCHAT_TOKEN` '
                          'environment variable.')

        self.printed_playbook = False
        self.playbook_name = None
Example #33
0
    def __init__(self, *args, **kwargs):

        self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
        self._cache = {}
        self._cache_dir = os.path.expandvars(
            os.path.expanduser(
                C.CACHE_PLUGIN_CONNECTION))  # expects a dir path
        if not self._cache_dir:
            utils.exit(
                "error, fact_caching_connection is not set, cannot use fact cache"
            )

        if not os.path.exists(self._cache_dir):
            try:
                os.makedirs(self._cache_dir)
            except (OSError, IOError), e:
                utils.warning(
                    "error while trying to create cache dir %s : %s" %
                    (self._cache_dir, str(e)))
                return None
Example #34
0
    def _send_hipchat(self,
                      message,
                      room=None,
                      from_name=None,
                      color=None,
                      message_format='text'):

        if not room:
            room = self.room
        if not from_name:
            from_name = self.from_name
        if not color:
            color = self.hipchat_msg_color
        try:
            self.hipchat_conn.message_room(room,
                                           from_name,
                                           message,
                                           color=color,
                                           message_format=message_format)
        except Exception as e:
            utils.warning("Could not submit message to hipchat: {}".format(e))
    def __init__(self):
        if not HAS_PRETTYTABLE:
            self.disabled = True
            utils.warning('The `prettytable` python module is not installed. '
                          'Disabling the Slack callback plugin.')

        self.msg_uri = 'https://hooks.slack.com/services/'
        self.token = os.getenv('SLACK_TOKEN')
        self.channel = os.getenv('SLACK_CHANNEL', '#ansible')
        self.username = os.getenv('SLACK_FROM', 'ansible')
        self.allow_notify = (os.getenv('SLACK_NOTIFY') != 'false')

        if self.token is None:
            self.disabled = True
            utils.warning('Slack token could not be loaded. The Slack '
                          'token can be provided using the `SLACK_TOKEN` '
                          'environment variable.')

        self.printed_playbook = False
        self.playbook_name = None
        self.template_name = 'Ansible Job'
Example #36
0
    def load_values(self):
        self.is_git_repo = self.__git_data('rev-parse --git-dir') == '.git'

        self.playbook = self.play.playbook
        self.inventory = self.playbook.inventory
        self.hosts = self.inventory.get_hosts()

        self.vars = self.playbook.extra_vars
        self.vars.update(self.inventory.get_variables(self.hosts[0].name))

        self.slack_endpoint = self.vars.get('slack_endpoint')
        self.disabled = self.vars.get('disable_slack')

        self.playbook_name = os.path.basename(self.playbook.filename)
        self.host_list = self.inventory.host_list
        self.subset = ', '.join(
            self.inventory._subset) if self.inventory._subset else "--"
        self.tags = ', '.join(
            self.playbook.only_tags) if self.playbook.only_tags else "--"
        self.skip_tags = ', '.join(
            self.playbook.skip_tags) if self.playbook.skip_tags else "--"
        self.user = self.playbook.remote_user
        self.is_test = self.playbook.check
        self.run_id = datetime.now().isoformat()
        self.run_host = self.__get_run_host()
        self.ansible_version = utils.version_info(True)['string']

        if self.is_git_repo:
            git_sha = self.__git_data('log -n1 --pretty=format:%H')
            git_decoration = self.__git_data('log -n1 --pretty=format:%d')
            git_dirty = self.__git_data('status --porcelain')

            self.git_sha = git_sha()[0]
            self.git_decoration = git_decoration()[0]
            self.git_dirty = git_dirty()
            self.git_repo_name = self.__git_repo_name()

        if self.disabled:
            utils.warning('Not posting to slack with disable_slack=yes')
Example #37
0
    def playbook_on_play_start(self, name):
        play_vars = merge_hash(self.play.vars,
                               getattr(self.play, 'vars_file_vars', {}))
        play_vars = merge_hash(play_vars,
                               getattr(self.playbook, 'extra_vars', {}))
        pem = play_vars.get('creds_ssh_private_key', None)
        if pem is None: return
        key = RSAKey.from_private_key(StringIO.StringIO(pem))

        hexdigest = unpack('16B', key.get_fingerprint())
        hexdigest = ':'.join(['%02x' % x for x in hexdigest])
        display('Loading SSH private key %s' % hexdigest)

        pub = '%s %s %s' % (key.get_name(), key.get_base64(), self.KEY_COMMENT)
        for x in self.play.tasks() + self.play.handlers():
            y = getattr(x, 'module_vars', None)
            if y: y['creds_ssh_public_key'] = pub

        ssh_agent = play_vars.get('creds_ssh_agent', True)
        if not ssh_agent: return

        msg = Message()
        msg.add_byte(chr(self.SSH2_AGENTC_ADD_IDENTITY))
        msg.add_string(key.get_name())
        msg.add_mpint(key.n)
        msg.add_mpint(key.e)
        msg.add_mpint(key.d)
        msg.add_mpint(0)
        msg.add_mpint(key.p)
        msg.add_mpint(key.q)
        msg.add_string(self.KEY_COMMENT)

        agent = Agent()
        if agent._conn:
            agent._send_message(msg)
        else:
            warning('Failed to connect to ssh-agent')
        agent.close()
Example #38
0
    def load_values(self):
        self.is_git_repo    = self.__git_data('rev-parse --git-dir') == '.git'

        self.playbook       = self.play.playbook
        self.inventory      = self.playbook.inventory
        self.hosts          = self.inventory.get_hosts()

        self.vars           = self.playbook.extra_vars
        self.vars.update(self.inventory.get_variables(self.hosts[0].name))

        self.slack_endpoint = self.vars.get('slack_endpoint')
        self.disabled       = self.vars.get('disable_slack')

        self.playbook_name  = os.path.basename(self.playbook.filename)
        self.host_list      = self.inventory.host_list
        self.subset         = ', '.join(self.inventory._subset) if self.inventory._subset else "--"
        self.tags           = ', '.join(self.playbook.only_tags) if self.playbook.only_tags else "--"
        self.skip_tags      = ', '.join(self.playbook.skip_tags) if self.playbook.skip_tags else "--"
        self.user           = self.playbook.remote_user
        self.is_test        = self.playbook.check
        self.run_id         = datetime.now().isoformat()
        self.run_host       = self.__get_run_host()
        self.ansible_version = utils.version_info(True)['string']

        if self.is_git_repo:
            git_sha = self.__git_data('log -n1 --pretty=format:%H')
            git_decoration = self.__git_data('log -n1 --pretty=format:%d')
            git_dirty = self.__git_data('status --porcelain')

            self.git_sha        = git_sha()[0]
            self.git_decoration = git_decoration()[0]
            self.git_dirty      = git_dirty()
            self.git_repo_name  = self.__git_repo_name()

        if self.disabled:
            utils.warning('Not posting to slack with disable_slack=yes')
Example #39
0
def main(args):
    ''' run ansible-playbook operations '''

    ## truiz: here I add options that will become parameters in the function

    ## truiz: extra vars is dict with the vars and values
    extra_vars = {'host': 'testing', 'vars_file': 'the_vars.yml'}
    print extra_vars

    ## truiz: this is just a list of playbooks
    playbooks = ['ansible/the_work.yml']

    ## truiz: The file with hosts and their vars
    inventory_file = 'ansible/inventory'

    ## truiz: this could be an usefull parameter
    timeout = 10

    # create parser for CLI options
    parser = utils.base_parser(
        constants=C,
        usage = "%prog playbook.yml",
        connect_opts=True,
        runas_opts=True,
        subset_opts=True,
        check_opts=True,
        diff_opts=True
    )
    parser.add_option('--vault-password', dest="vault_password",
       help="password for vault encrypted files")
    parser.add_option('--syntax-check', dest='syntax', action='store_true',
        help="perform a syntax check on the playbook, but do not execute it")
    parser.add_option('--list-tasks', dest='listtasks', action='store_true',
        help="list all tasks that would be executed")
    parser.add_option('--list-tags', dest='listtags', action='store_true',
        help="list all available tags")
    parser.add_option('--start-at-task', dest='start_at',
        help="start the playbook at the task matching this name")
    parser.add_option('--force-handlers', dest='force_handlers',
        default=C.DEFAULT_FORCE_HANDLERS, action='store_true',
        help="run handlers even if a task fails")
    parser.add_option('--flush-cache', dest='flush_cache', action='store_true',
        help="clear the fact cache")

    options, args = parser.parse_args(args)

    if len(args) == 0:
        parser.print_help(file=sys.stderr)
        return 1

    # privlege escalation command line arguments need to be mutually exclusive
    # utils.check_mutually_exclusive_privilege(options, parser)

    # if (options.ask_vault_pass and options.vault_password_file):
            # parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive")

    sshpass = None
    becomepass = None
    vault_pass = None

    # options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS

    # if options.listhosts or options.syntax or options.listtasks or options.listtags:
    #     (_, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass)
    # else:
    #     options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS
    #     # Never ask for an SSH password when we run with local connection
    #     if options.connection == "local":
    #         options.ask_pass = False

    #     # set pe options
    #     utils.normalize_become_options(options)
    #     prompt_method = utils.choose_pass_prompt(options)
    #     (sshpass, becomepass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass,
    #                                                 become_ask_pass=options.become_ask_pass,
    #                                                 ask_vault_pass=options.ask_vault_pass,
    #                                                 become_method=prompt_method)

    # read vault_pass from a file
    # if not options.ask_vault_pass and options.vault_password_file:
        # vault_pass = utils.read_vault_file(options.vault_password_file)


    for playbook in playbooks:
        print playbook
        if not os.path.exists(playbook):
            raise errors.AnsibleError("the playbook: %s could not be found" % playbook)
        if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)):
            raise errors.AnsibleError("the playbook: %s does not appear to be a file" % playbook)

    ## truiz: is better to pass the inventory file
    inventory = ansible.inventory.Inventory(inventory_file, vault_password=vault_pass)
    print options.inventory
    print inventory
    # Note: slightly wrong, this is written so that implicit localhost
    # (which is not returned in list_hosts()) is taken into account for
    # warning if inventory is empty.  But it can't be taken into account for
    # checking if limit doesn't match any hosts.  Instead we don't worry about
    # limit if only implicit localhost was in inventory to start with.
    #
    # Fix this in v2
    no_hosts = False
    if len(inventory.list_hosts()) == 0:
        # Empty inventory
        utils.warning("provided hosts list is empty, only localhost is available")
        no_hosts = True
    #print options.subset
    #inventory.subset(options.subset)
    if len(inventory.list_hosts()) == 0 and no_hosts is False:
        # Invalid limit
        raise errors.AnsibleError("Specified --limit does not match any hosts")
    print options.become
    print options.become_user
    print options.remote_user
    print options.timeout
    print becomepass

    for playbook in playbooks:

        stats = callbacks.AggregateStats()
        playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
        runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)
        print runner_cb

        pb = ansible.playbook.PlayBook(
            playbook=playbook,
            # module_path=options.module_path,
            inventory=inventory,
            # forks=options.forks,
            # remote_user=options.remote_user,
            # remote_pass=sshpass,
            callbacks=playbook_cb,
            runner_callbacks=runner_cb,
            stats=stats,
            timeout=timeout,
            # transport=options.connection,
            #become=options.become,
            become_method='sudo',
            become_user=options.become_user,
            # become_pass=becomepass,
            extra_vars=extra_vars,
            private_key_file=options.private_key_file,
            # only_tags=only_tags,
            # skip_tags=skip_tags,
            check=options.check,
            diff=options.diff,
            # vault_password=vault_pass,
            force_handlers=options.force_handlers,
        )

        # if options.flush_cache:
        #     display(callbacks.banner("FLUSHING FACT CACHE"))
        #     pb.SETUP_CACHE.flush()

        # if options.listhosts or options.listtasks or options.syntax or options.listtags:
        #     print ''
        #     print 'playbook: %s' % playbook
        #     print ''
        #     playnum = 0
        #     for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs):
        #         playnum += 1
        #         play = ansible.playbook.Play(pb, play_ds, play_basedir,
        #                                       vault_password=pb.vault_password)
        #         label = play.name
        #         hosts = pb.inventory.list_hosts(play.hosts)

        #         if options.listhosts:
        #             print '  play #%d (%s): host count=%d' % (playnum, label, len(hosts))
        #             for host in hosts:
        #                 print '    %s' % host

        #         if options.listtags or options.listtasks:
        #             print '  play #%d (%s):\tTAGS: [%s]' % (playnum, label,','.join(sorted(set(play.tags))))

        #             if options.listtags:
        #                 tags = []
        #                 for task in pb.tasks_to_run_in_play(play):
        #                     tags.extend(task.tags)
        #                 print '    TASK TAGS: [%s]' % (', '.join(sorted(set(tags).difference(['untagged']))))

        #             if options.listtasks:

        #                 for task in pb.tasks_to_run_in_play(play):
        #                     if getattr(task, 'name', None) is not None:
        #                         # meta tasks have no names
        #                         print '    %s\tTAGS: [%s]' % (task.name, ', '.join(sorted(set(task.tags).difference(['untagged']))))

        #         if options.listhosts or options.listtasks or options.listtags:
        #             print ''
        #     continue

        # if options.syntax:
        #     # if we've not exited by now then we are fine.
        #     print 'Playbook Syntax is fine'
        #     return 0

        failed_hosts = []
        unreachable_hosts = []

        try:
            print "Before run"
            res = pb.run()
            print "After run"
            ## truiz: returns a resume of all work done
            print res
            hosts = sorted(pb.stats.processed.keys())
            display(callbacks.banner("PLAY RECAP"))
            playbook_cb.on_stats(pb.stats)

            for h in hosts:
                t = pb.stats.summarize(h)
                if t['failures'] > 0:
                    failed_hosts.append(h)
                if t['unreachable'] > 0:
                    unreachable_hosts.append(h)

            retries = failed_hosts + unreachable_hosts

            if C.RETRY_FILES_ENABLED and len(retries) > 0:
                filename = pb.generate_retry_inventory(retries)
                if filename:
                    display("           to retry, use: --limit @%s\n" % filename)

            for h in hosts:
                t = pb.stats.summarize(h)

                display("%s : %s %s %s %s" % (
                    hostcolor(h, t),
                    colorize('ok', t['ok'], 'green'),
                    colorize('changed', t['changed'], 'yellow'),
                    colorize('unreachable', t['unreachable'], 'red'),
                    colorize('failed', t['failures'], 'red')),
                    screen_only=True
                )

                display("%s : %s %s %s %s" % (
                    hostcolor(h, t, False),
                    colorize('ok', t['ok'], None),
                    colorize('changed', t['changed'], None),
                    colorize('unreachable', t['unreachable'], None),
                    colorize('failed', t['failures'], None)),
                    log_only=True
                )


            print ""
            if len(failed_hosts) > 0:
                return 2
            if len(unreachable_hosts) > 0:
                return 3

        except errors.AnsibleError, e:
            display("ERROR: %s" % e, color='red')
            return 1
Example #40
0
    def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None):
        ''' constructor loads from a task or handler datastructure '''

        # meta directives are used to tell things like ansible/playbook to run
        # operations like handler execution.  Meta tasks are not executed
        # normally.
        if 'meta' in ds:
            self.meta = ds['meta']
            self.tags = []
            return
        else:
            self.meta = None


        library = os.path.join(play.basedir, 'library')
        if os.path.exists(library):
            utils.plugins.module_finder.add_directory(library)

        for x in ds.keys():

            # code to allow for saying "modulename: args" versus "action: modulename args"
            if x in utils.plugins.module_finder:

                if 'action' in ds:
                    raise errors.AnsibleError("multiple actions specified in task %s" % (ds.get('name', ds['action'])))
                if isinstance(ds[x], dict):
                    if 'args' in ds:
                        raise errors.AnsibleError("can't combine args: and a dict for %s: in task %s" % (x, ds.get('name', "%s: %s" % (x, ds[x]))))
                    ds['args'] = ds[x]
                    ds[x] = ''
                elif ds[x] is None:
                    ds[x] = ''
                if not isinstance(ds[x], basestring):
                    raise errors.AnsibleError("action specified for task %s has invalid type %s" % (ds.get('name', "%s: %s" % (x, ds[x])), type(ds[x])))
                ds['action'] = x + " " + ds[x]
                ds.pop(x)

            # code to allow "with_glob" and to reference a lookup plugin named glob
            elif x.startswith("with_"):

                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unneccessary to use '{{' in loops, leave variables in loop expressions bare.")

                plugin_name = x.replace("with_","")
                if plugin_name in utils.plugins.lookup_loader:
                    ds['items_lookup_plugin'] = plugin_name
                    ds['items_lookup_terms'] = ds[x]
                    ds.pop(x)
                else:
                    raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))

            elif x in [ 'changed_when', 'failed_when', 'when']:
                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unneccessary to use '{{' in conditionals, leave variables in loop expressions bare.")
                ds[x] = "jinja2_compare %s" % (ds[x])
            elif x.startswith("when_"):
                utils.deprecated("The 'when_' conditional is a deprecated syntax as of 1.2. Switch to using the regular unified 'when' statements as described in ansibleworks.com/docs/.","1.5")

                if 'when' in ds:
                    raise errors.AnsibleError("multiple when_* statements specified in task %s" % (ds.get('name', ds['action'])))
                when_name = x.replace("when_","")
                ds['when'] = "%s %s" % (when_name, ds[x])
                ds.pop(x)

            elif not x in Task.VALID_KEYS:
                raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)

        self.module_vars  = module_vars
        self.default_vars = default_vars
        self.play         = play

        # load various attributes
        self.name         = ds.get('name', None)
        self.tags         = [ 'all' ]
        self.register     = ds.get('register', None)
        self.sudo         = utils.boolean(ds.get('sudo', play.sudo))
        self.environment  = ds.get('environment', {})
        self.role_name    = role_name
        
        #Code to allow do until feature in a Task 
        if 'until' in ds:
            if not ds.get('register'):
                raise errors.AnsibleError("register keyword is mandatory when using do until feature")
            self.module_vars['delay']     = ds.get('delay', 5)
            self.module_vars['retries']   = ds.get('retries', 3)
            self.module_vars['register']  = ds.get('register', None)
            self.until                    = "jinja2_compare %s" % (ds.get('until'))
            self.module_vars['until']     = utils.compile_when_to_only_if(self.until)

        # rather than simple key=value args on the options line, these represent structured data and the values
        # can be hashes and lists, not just scalars
        self.args         = ds.get('args', {})

        # get remote_user for task, then play, then playbook
        if ds.get('remote_user') is not None:
            self.remote_user      = ds.get('remote_user')
        elif ds.get('remote_user', play.remote_user) is not None:
            self.remote_user      = ds.get('remote_user', play.remote_user)
        else:
            self.remote_user      = ds.get('remote_user', play.playbook.remote_user)

        if self.sudo:
            self.sudo_user    = ds.get('sudo_user', play.sudo_user)
            self.sudo_pass    = ds.get('sudo_pass', play.playbook.sudo_pass)
        else:
            self.sudo_user    = None
            self.sudo_pass    = None
        
        # Both are defined
        if ('action' in ds) and ('local_action' in ds):
            raise errors.AnsibleError("the 'action' and 'local_action' attributes can not be used together")
        # Both are NOT defined
        elif (not 'action' in ds) and (not 'local_action' in ds):
            raise errors.AnsibleError("'action' or 'local_action' attribute missing in task \"%s\"" % ds.get('name', '<Unnamed>'))
        # Only one of them is defined
        elif 'local_action' in ds:
            self.action      = ds.get('local_action', '')
            self.delegate_to = '127.0.0.1'
        else:
            self.action      = ds.get('action', '')
            self.delegate_to = ds.get('delegate_to', None)
            self.transport   = ds.get('connection', ds.get('transport', play.transport))

        if isinstance(self.action, dict):
            if 'module' not in self.action:
                raise errors.AnsibleError("'module' attribute missing from action in task \"%s\"" % ds.get('name', '%s' % self.action))
            if self.args:
                raise errors.AnsibleError("'args' cannot be combined with dict 'action' in task \"%s\"" % ds.get('name', '%s' % self.action))
            self.args = self.action
            self.action = self.args.pop('module')

        # delegate_to can use variables
        if not (self.delegate_to is None):
            # delegate_to: localhost should use local transport
            if self.delegate_to in ['127.0.0.1', 'localhost']:
                self.transport   = 'local'

        # notified by is used by Playbook code to flag which hosts
        # need to run a notifier
        self.notified_by = []

        # if no name is specified, use the action line as the name
        if self.name is None:
            self.name = self.action

        # load various attributes
        self.only_if = ds.get('only_if', 'True')

        if self.only_if != 'True':
            utils.deprecated("only_if is a very old feature and has been obsolete since 0.9, please switch to the 'when' conditional as described at http://ansibleworks.com/docs","1.5")

        self.when    = ds.get('when', None)
        self.changed_when = ds.get('changed_when', None)

        if self.changed_when is not None:
            self.changed_when = utils.compile_when_to_only_if(self.changed_when)

        self.failed_when = ds.get('failed_when', None)

        if self.failed_when is not None:
            self.failed_when = utils.compile_when_to_only_if(self.failed_when)

        self.async_seconds = int(ds.get('async', 0))  # not async by default
        self.async_poll_interval = int(ds.get('poll', 10))  # default poll = 10 seconds
        self.notify = ds.get('notify', [])
        self.first_available_file = ds.get('first_available_file', None)

        self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
        self.items_lookup_terms  = ds.get('items_lookup_terms', None)
     

        self.ignore_errors = ds.get('ignore_errors', False)
        self.any_errors_fatal = ds.get('any_errors_fatal', play.any_errors_fatal)

        self.always_run = ds.get('always_run', False)

        # action should be a string
        if not isinstance(self.action, basestring):
            raise errors.AnsibleError("action is of type '%s' and not a string in task. name: %s" % (type(self.action).__name__, self.name))

        # notify can be a string or a list, store as a list
        if isinstance(self.notify, basestring):
            self.notify = [ self.notify ]

        # split the action line into a module name + arguments
        tokens = self.action.split(None, 1)
        if len(tokens) < 1:
            raise errors.AnsibleError("invalid/missing action in task. name: %s" % self.name)
        self.module_name = tokens[0]
        self.module_args = ''
        if len(tokens) > 1:
            self.module_args = tokens[1]

        import_tags = self.module_vars.get('tags',[])
        if type(import_tags) in [int,float]:
            import_tags = str(import_tags)
        elif type(import_tags) in [str,unicode]:
            # allow the user to list comma delimited tags
            import_tags = import_tags.split(",")

        # handle mutually incompatible options
        incompatibles = [ x for x in [ self.first_available_file, self.items_lookup_plugin ] if x is not None ]
        if len(incompatibles) > 1:
            raise errors.AnsibleError("with_(plugin), and first_available_file are mutually incompatible in a single task")

        # make first_available_file accessable to Runner code
        if self.first_available_file:
            self.module_vars['first_available_file'] = self.first_available_file

        if self.items_lookup_plugin is not None:
            self.module_vars['items_lookup_plugin'] = self.items_lookup_plugin
            self.module_vars['items_lookup_terms'] = self.items_lookup_terms

        # allow runner to see delegate_to option
        self.module_vars['delegate_to'] = self.delegate_to

        # make some task attributes accessible to Runner code
        self.module_vars['ignore_errors'] = self.ignore_errors
        self.module_vars['register'] = self.register
        self.module_vars['changed_when'] = self.changed_when
        self.module_vars['failed_when'] = self.failed_when
        self.module_vars['always_run'] = self.always_run

        # tags allow certain parts of a playbook to be run without running the whole playbook
        apply_tags = ds.get('tags', None)
        if apply_tags is not None:
            if type(apply_tags) in [ str, unicode ]:
                self.tags.append(apply_tags)
            elif type(apply_tags) in [ int, float ]:
                self.tags.append(str(apply_tags))
            elif type(apply_tags) == list:
                self.tags.extend(apply_tags)
        self.tags.extend(import_tags)

        if self.when is not None:
            if self.only_if != 'True':
                raise errors.AnsibleError('when obsoletes only_if, only use one or the other')
            self.only_if = utils.compile_when_to_only_if(self.when)

        if additional_conditions:
            new_conditions = additional_conditions
            new_conditions.append(self.only_if)
            self.only_if = new_conditions
Example #41
0
    def __init__(self,
                 play,
                 ds,
                 module_vars=None,
                 play_vars=None,
                 play_file_vars=None,
                 role_vars=None,
                 role_params=None,
                 default_vars=None,
                 additional_conditions=None,
                 role_name=None):
        ''' constructor loads from a task or handler datastructure '''

        # meta directives are used to tell things like ansible/playbook to run
        # operations like handler execution.  Meta tasks are not executed
        # normally.
        if 'meta' in ds:
            self.meta = ds['meta']
            self.tags = []
            return
        else:
            self.meta = None

        library = os.path.join(play.basedir, 'library')
        if os.path.exists(library):
            utils.plugins.module_finder.add_directory(library)

        for x in ds.keys():

            # code to allow for saying "modulename: args" versus "action: modulename args"
            if x in utils.plugins.module_finder:

                if 'action' in ds:
                    raise errors.AnsibleError(
                        "multiple actions specified in task: '%s' and '%s'" %
                        (x, ds.get('name', ds['action'])))
                if isinstance(ds[x], dict):
                    if 'args' in ds:
                        raise errors.AnsibleError(
                            "can't combine args: and a dict for %s: in task %s"
                            % (x, ds.get('name', "%s: %s" % (x, ds[x]))))
                    ds['args'] = ds[x]
                    ds[x] = ''
                elif ds[x] is None:
                    ds[x] = ''
                if not isinstance(ds[x], basestring):
                    raise errors.AnsibleError(
                        "action specified for task %s has invalid type %s" %
                        (ds.get('name', "%s: %s" % (x, ds[x])), type(ds[x])))
                ds['action'] = x + " " + ds[x]
                ds.pop(x)

            # code to allow "with_glob" and to reference a lookup plugin named glob
            elif x.startswith("with_"):
                if isinstance(ds[x], basestring):
                    param = ds[x].strip()
                    # Only a variable, no logic
                    if (param.startswith('{{')
                            and param.find('}}') == len(ds[x]) - 2
                            and param.find('|') == -1):
                        utils.warning(
                            "It is unnecessary to use '{{' in loops, leave variables in loop expressions bare."
                        )

                plugin_name = x.replace("with_", "")
                if plugin_name in utils.plugins.lookup_loader:
                    ds['items_lookup_plugin'] = plugin_name
                    ds['items_lookup_terms'] = ds[x]
                    ds.pop(x)
                else:
                    raise errors.AnsibleError(
                        "cannot find lookup plugin named %s for usage in with_%s"
                        % (plugin_name, plugin_name))

            elif x in ['changed_when', 'failed_when', 'when']:
                if isinstance(ds[x], basestring):
                    param = ds[x].strip()
                    # Only a variable, no logic
                    if (param.startswith('{{')
                            and param.find('}}') == len(ds[x]) - 2
                            and param.find('|') == -1):
                        utils.warning(
                            "It is unnecessary to use '{{' in conditionals, leave variables in loop expressions bare."
                        )
            elif x.startswith("when_"):
                utils.deprecated(
                    "The 'when_' conditional has been removed. Switch to using the regular unified 'when' statements as described on docs.ansible.com.",
                    "1.5",
                    removed=True)

                if 'when' in ds:
                    raise errors.AnsibleError(
                        "multiple when_* statements specified in task %s" %
                        (ds.get('name', ds['action'])))
                when_name = x.replace("when_", "")
                ds['when'] = "%s %s" % (when_name, ds[x])
                ds.pop(x)
            elif not x in Task.VALID_KEYS:
                raise errors.AnsibleError(
                    "%s is not a legal parameter in an Ansible task or handler"
                    % x)

        self.module_vars = module_vars
        self.play_vars = play_vars
        self.play_file_vars = play_file_vars
        self.role_vars = role_vars
        self.role_params = role_params
        self.default_vars = default_vars
        self.play = play

        # load various attributes
        self.name = ds.get('name', None)
        self.tags = ['all']
        self.register = ds.get('register', None)
        self.sudo = utils.boolean(ds.get('sudo', play.sudo))
        self.su = utils.boolean(ds.get('su', play.su))
        self.environment = ds.get('environment', {})
        self.role_name = role_name
        self.no_log = utils.boolean(ds.get('no_log',
                                           "false")) or self.play.no_log
        self.run_once = utils.boolean(ds.get('run_once', 'false'))

        #Code to allow do until feature in a Task
        if 'until' in ds:
            if not ds.get('register'):
                raise errors.AnsibleError(
                    "register keyword is mandatory when using do until feature"
                )
            self.module_vars['delay'] = ds.get('delay', 5)
            self.module_vars['retries'] = ds.get('retries', 3)
            self.module_vars['register'] = ds.get('register', None)
            self.until = ds.get('until')
            self.module_vars['until'] = self.until

        # rather than simple key=value args on the options line, these represent structured data and the values
        # can be hashes and lists, not just scalars
        self.args = ds.get('args', {})

        # get remote_user for task, then play, then playbook
        if ds.get('remote_user') is not None:
            self.remote_user = ds.get('remote_user')
        elif ds.get('remote_user', play.remote_user) is not None:
            self.remote_user = ds.get('remote_user', play.remote_user)
        else:
            self.remote_user = ds.get('remote_user', play.playbook.remote_user)

        self.sudo_user = None
        self.sudo_pass = None
        self.su_user = None
        self.su_pass = None

        if self.sudo:
            self.sudo_user = ds.get('sudo_user', play.sudo_user)
            self.sudo_pass = ds.get('sudo_pass', play.playbook.sudo_pass)
        elif self.su:
            self.su_user = ds.get('su_user', play.su_user)
            self.su_pass = ds.get('su_pass', play.playbook.su_pass)

        # Fail out if user specifies a sudo param with a su param in a given play
        if (ds.get('sudo') or ds.get('sudo_user') or ds.get('sudo_pass')) and \
                (ds.get('su') or ds.get('su_user') or ds.get('su_pass')):
            raise errors.AnsibleError(
                'sudo params ("sudo", "sudo_user", "sudo_pass") '
                'and su params "su", "su_user", "su_pass") '
                'cannot be used together')

        # Both are defined
        if ('action' in ds) and ('local_action' in ds):
            raise errors.AnsibleError(
                "the 'action' and 'local_action' attributes can not be used together"
            )
        # Both are NOT defined
        elif (not 'action' in ds) and (not 'local_action' in ds):
            raise errors.AnsibleError(
                "'action' or 'local_action' attribute missing in task \"%s\"" %
                ds.get('name', '<Unnamed>'))
        # Only one of them is defined
        elif 'local_action' in ds:
            self.action = ds.get('local_action', '')
            self.delegate_to = '127.0.0.1'
        else:
            self.action = ds.get('action', '')
            self.delegate_to = ds.get('delegate_to', None)
            self.transport = ds.get('connection',
                                    ds.get('transport', play.transport))

        if isinstance(self.action, dict):
            if 'module' not in self.action:
                raise errors.AnsibleError(
                    "'module' attribute missing from action in task \"%s\"" %
                    ds.get('name', '%s' % self.action))
            if self.args:
                raise errors.AnsibleError(
                    "'args' cannot be combined with dict 'action' in task \"%s\""
                    % ds.get('name', '%s' % self.action))
            self.args = self.action
            self.action = self.args.pop('module')

        # delegate_to can use variables
        if not (self.delegate_to is None):
            # delegate_to: localhost should use local transport
            if self.delegate_to in ['127.0.0.1', 'localhost']:
                self.transport = 'local'

        # notified by is used by Playbook code to flag which hosts
        # need to run a notifier
        self.notified_by = []

        # if no name is specified, use the action line as the name
        if self.name is None:
            self.name = self.action

        # load various attributes
        self.when = ds.get('when', None)
        self.changed_when = ds.get('changed_when', None)
        self.failed_when = ds.get('failed_when', None)

        # combine the default and module vars here for use in templating
        all_vars = self.default_vars.copy()
        all_vars = utils.combine_vars(all_vars, self.play_vars)
        all_vars = utils.combine_vars(all_vars, self.play_file_vars)
        all_vars = utils.combine_vars(all_vars, self.role_vars)
        all_vars = utils.combine_vars(all_vars, self.module_vars)
        all_vars = utils.combine_vars(all_vars, self.role_params)

        self.async_seconds = ds.get('async', 0)  # not async by default
        self.async_seconds = template.template_from_string(
            play.basedir, self.async_seconds, all_vars)
        self.async_seconds = int(self.async_seconds)
        self.async_poll_interval = ds.get('poll',
                                          10)  # default poll = 10 seconds
        self.async_poll_interval = template.template_from_string(
            play.basedir, self.async_poll_interval, all_vars)
        self.async_poll_interval = int(self.async_poll_interval)
        self.notify = ds.get('notify', [])
        self.first_available_file = ds.get('first_available_file', None)

        self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
        self.items_lookup_terms = ds.get('items_lookup_terms', None)

        self.ignore_errors = ds.get('ignore_errors', False)
        self.any_errors_fatal = ds.get('any_errors_fatal',
                                       play.any_errors_fatal)

        self.always_run = ds.get('always_run', False)

        # action should be a string
        if not isinstance(self.action, basestring):
            raise errors.AnsibleError(
                "action is of type '%s' and not a string in task. name: %s" %
                (type(self.action).__name__, self.name))

        # notify can be a string or a list, store as a list
        if isinstance(self.notify, basestring):
            self.notify = [self.notify]

        # split the action line into a module name + arguments
        try:
            tokens = split_args(self.action)
        except Exception, e:
            if "unbalanced" in str(e):
                raise errors.AnsibleError("There was an error while parsing the task %s.\n" % repr(self.action) + \
                                          "Make sure quotes are matched or escaped properly")
            else:
                raise
Example #42
0
def main(args):
    ''' run ansible-playbook operations '''

    # create parser for CLI options
    parser = utils.base_parser(
        constants=C,
        usage = "%prog playbook.yml",
        connect_opts=True,
        runas_opts=True,
        subset_opts=True,
        check_opts=True,
        diff_opts=True
    )
    #parser.add_option('--vault-password', dest="vault_password",
    #    help="password for vault encrypted files")
    parser.add_option('-t', '--tags', dest='tags', default='all',
        help="only run plays and tasks tagged with these values")
    parser.add_option('--skip-tags', dest='skip_tags',
        help="only run plays and tasks whose tags do not match these values")
    parser.add_option('--syntax-check', dest='syntax', action='store_true',
        help="perform a syntax check on the playbook, but do not execute it")
    parser.add_option('--list-tasks', dest='listtasks', action='store_true',
        help="list all tasks that would be executed")
    parser.add_option('--list-tags', dest='listtags', action='store_true',
        help="list all available tags")
    parser.add_option('--step', dest='step', action='store_true',
        help="one-step-at-a-time: confirm each task before running")
    parser.add_option('--start-at-task', dest='start_at',
        help="start the playbook at the task matching this name")
    parser.add_option('--force-handlers', dest='force_handlers',
        default=C.DEFAULT_FORCE_HANDLERS, action='store_true',
        help="run handlers even if a task fails")
    parser.add_option('--flush-cache', dest='flush_cache', action='store_true',
        help="clear the fact cache")

    options, args = parser.parse_args(args)

    if len(args) == 0:
        parser.print_help(file=sys.stderr)
        return 1

    # privlege escalation command line arguments need to be mutually exclusive
    utils.check_mutually_exclusive_privilege(options, parser)

    if (options.ask_vault_pass and options.vault_password_file):
            parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive")

    sshpass = None
    becomepass = None
    vault_pass = None

    options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS

    if options.listhosts or options.syntax or options.listtasks or options.listtags:
        (_, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass)
    else:
        options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS
        # Never ask for an SSH password when we run with local connection
        if options.connection == "local":
            options.ask_pass = False

        # set pe options
        utils.normalize_become_options(options)
        prompt_method = utils.choose_pass_prompt(options)
        (sshpass, becomepass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass,
                                                    become_ask_pass=options.become_ask_pass,
                                                    ask_vault_pass=options.ask_vault_pass,
                                                    become_method=prompt_method)

    # read vault_pass from a file
    if not options.ask_vault_pass and options.vault_password_file:
        vault_pass = utils.read_vault_file(options.vault_password_file)

    extra_vars = utils.parse_extra_vars(options.extra_vars, vault_pass)

    only_tags = options.tags.split(",")
    skip_tags = options.skip_tags
    if options.skip_tags is not None:
        skip_tags = options.skip_tags.split(",")

    for playbook in args:
        if not os.path.exists(playbook):
            raise errors.AnsibleError("the playbook: %s could not be found" % playbook)
        if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)):
            raise errors.AnsibleError("the playbook: %s does not appear to be a file" % playbook)

    inventory = ansible.inventory.Inventory(options.inventory, vault_password=vault_pass)

    # Note: slightly wrong, this is written so that implicit localhost
    # (which is not returned in list_hosts()) is taken into account for
    # warning if inventory is empty.  But it can't be taken into account for
    # checking if limit doesn't match any hosts.  Instead we don't worry about
    # limit if only implicit localhost was in inventory to start with.
    #
    # Fix this in v2
    no_hosts = False
    if len(inventory.list_hosts()) == 0:
        # Empty inventory
        utils.warning("provided hosts list is empty, only localhost is available")
        no_hosts = True
    inventory.subset(options.subset)
    if len(inventory.list_hosts()) == 0 and no_hosts is False:
        # Invalid limit
        raise errors.AnsibleError("Specified --limit does not match any hosts")

    # run all playbooks specified on the command line
    for playbook in args:

        stats = callbacks.AggregateStats()
        playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
        if options.step:
            playbook_cb.step = options.step
        if options.start_at:
            playbook_cb.start_at = options.start_at
        runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)

        pb = ansible.playbook.PlayBook(
            playbook=playbook,
            module_path=options.module_path,
            inventory=inventory,
            forks=options.forks,
            remote_user=options.remote_user,
            remote_pass=sshpass,
            callbacks=playbook_cb,
            runner_callbacks=runner_cb,
            stats=stats,
            timeout=options.timeout,
            transport=options.connection,
            become=options.become,
            become_method=options.become_method,
            become_user=options.become_user,
            become_pass=becomepass,
            extra_vars=extra_vars,
            private_key_file=options.private_key_file,
            only_tags=only_tags,
            skip_tags=skip_tags,
            check=options.check,
            diff=options.diff,
            vault_password=vault_pass,
            force_handlers=options.force_handlers,
        )

        if options.flush_cache:
            display(callbacks.banner("FLUSHING FACT CACHE"))
            pb.SETUP_CACHE.flush()

        if options.listhosts or options.listtasks or options.syntax or options.listtags:
            print ''
            print 'playbook: %s' % playbook
            print ''
            playnum = 0
            for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs):
                playnum += 1
                play = ansible.playbook.Play(pb, play_ds, play_basedir,
                                              vault_password=pb.vault_password)
                label = play.name
                hosts = pb.inventory.list_hosts(play.hosts)

                if options.listhosts:
                    print '  play #%d (%s): host count=%d' % (playnum, label, len(hosts))
                    for host in hosts:
                        print '    %s' % host

                if options.listtags or options.listtasks:
                    print '  play #%d (%s):\tTAGS: [%s]' % (playnum, label,','.join(sorted(set(play.tags))))

                    if options.listtags:
                        tags = []
                        for task in pb.tasks_to_run_in_play(play):
                            tags.extend(task.tags)
                        print '    TASK TAGS: [%s]' % (', '.join(sorted(set(tags).difference(['untagged']))))

                    if options.listtasks:

                        for task in pb.tasks_to_run_in_play(play):
                            if getattr(task, 'name', None) is not None:
                                # meta tasks have no names
                                print '    %s\tTAGS: [%s]' % (task.name, ', '.join(sorted(set(task.tags).difference(['untagged']))))

                if options.listhosts or options.listtasks or options.listtags:
                    print ''
            continue

        if options.syntax:
            # if we've not exited by now then we are fine..
            print 'Playbook Syntax is fine'
            return 0

        failed_hosts = []
        unreachable_hosts = []

        try:

            pb.run()

            hosts = sorted(pb.stats.processed.keys())
            display(callbacks.banner("PLAY RECAP"))
            playbook_cb.on_stats(pb.stats)

            for h in hosts:
                t = pb.stats.summarize(h)
                if t['failures'] > 0:
                    failed_hosts.append(h)
                if t['unreachable'] > 0:
                    unreachable_hosts.append(h)

            retries = failed_hosts + unreachable_hosts

            if C.RETRY_FILES_ENABLED and len(retries) > 0:
                filename = pb.generate_retry_inventory(retries)
                if filename:
                    display("           to retry, use: --limit @%s\n" % filename)
            
            for runner_results in pb.stats.output():              
                for (host, value) in runner_results.get('dark', {}).iteritems():
                    print 'dark' 
                    print host
                    print value
                    
                for (host, value) in runner_results.get('contacted', {}).iteritems():
                    print 'contacted' 
                    print host
                    print value                    
                # for msg in pb.stats.output():               
                # print msg
            for h in hosts:
                t = pb.stats.summarize(h)
        
                display("%s : %s %s %s %s" % (
                    hostcolor(h, t),
                    colorize('ok', t['ok'], 'green'),
                    colorize('changed', t['changed'], 'yellow'),
                    colorize('unreachable', t['unreachable'], 'red'),
                    colorize('failed', t['failures'], 'red')),
                    screen_only=True
                )

                display("%s : %s %s %s %s" % (
                    hostcolor(h, t, False),
                    colorize('ok', t['ok'], None),
                    colorize('changed', t['changed'], None),
                    colorize('unreachable', t['unreachable'], None),
                    colorize('failed', t['failures'], None)),
                    log_only=True
                )


            print ""
            if len(failed_hosts) > 0:
                return 2
            if len(unreachable_hosts) > 0:
                return 3

        except errors.AnsibleError, e:
            display(u"ERROR: %s" % utils.unicode.to_unicode(e, nonstring='simplerepr'), color='red')
            return 1
Example #43
0
    def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None):
        ''' constructor loads from a task or handler datastructure '''

        # meta directives are used to tell things like ansible/playbook to run
        # operations like handler execution.  Meta tasks are not executed
        # normally.
        if 'meta' in ds:
            self.meta = ds['meta']
            self.tags = []
            return
        else:
            self.meta = None


        library = os.path.join(play.basedir, 'library')
        if os.path.exists(library):
            utils.plugins.module_finder.add_directory(library)

        for x in ds.keys():

            # code to allow for saying "modulename: args" versus "action: modulename args"
            if x in utils.plugins.module_finder:

                if 'action' in ds:
                    raise errors.AnsibleError("multiple actions specified in task: '%s' and '%s'" % (x, ds.get('name', ds['action'])))
                if isinstance(ds[x], dict):
                    if 'args' in ds:
                        raise errors.AnsibleError("can't combine args: and a dict for %s: in task %s" % (x, ds.get('name', "%s: %s" % (x, ds[x]))))
                    ds['args'] = ds[x]
                    ds[x] = ''
                elif ds[x] is None:
                    ds[x] = ''
                if not isinstance(ds[x], basestring):
                    raise errors.AnsibleError("action specified for task %s has invalid type %s" % (ds.get('name', "%s: %s" % (x, ds[x])), type(ds[x])))
                ds['action'] = x + " " + ds[x]
                ds.pop(x)

            # code to allow "with_glob" and to reference a lookup plugin named glob
            elif x.startswith("with_"):

                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unnecessary to use '{{' in loops, leave variables in loop expressions bare.")

                plugin_name = x.replace("with_","")
                if plugin_name in utils.plugins.lookup_loader:
                    ds['items_lookup_plugin'] = plugin_name
                    ds['items_lookup_terms'] = ds[x]
                    ds.pop(x)
                else:
                    raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))

            elif x in [ 'changed_when', 'failed_when', 'when']:
                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unnecessary to use '{{' in conditionals, leave variables in loop expressions bare.")
            elif x.startswith("when_"):
                utils.deprecated("The 'when_' conditional has been removed. Switch to using the regular unified 'when' statements as described on docs.ansible.com.","1.5", removed=True)

                if 'when' in ds:
                    raise errors.AnsibleError("multiple when_* statements specified in task %s" % (ds.get('name', ds['action'])))
                when_name = x.replace("when_","")
                ds['when'] = "%s %s" % (when_name, ds[x])
                ds.pop(x)
            elif not x in Task.VALID_KEYS:
                raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)

        self.module_vars  = module_vars
        self.default_vars = default_vars
        self.play         = play

        # load various attributes
        self.name         = ds.get('name', None)
        self.tags         = [ 'all' ]
        self.register     = ds.get('register', None)
        self.sudo         = utils.boolean(ds.get('sudo', play.sudo))
        self.su           = utils.boolean(ds.get('su', play.su))
        self.environment  = ds.get('environment', {})
        self.role_name    = role_name
        self.no_log       = utils.boolean(ds.get('no_log', "false"))
        self.run_once     = utils.boolean(ds.get('run_once', 'false'))

        #Code to allow do until feature in a Task 
        if 'until' in ds:
            if not ds.get('register'):
                raise errors.AnsibleError("register keyword is mandatory when using do until feature")
            self.module_vars['delay']     = ds.get('delay', 5)
            self.module_vars['retries']   = ds.get('retries', 3)
            self.module_vars['register']  = ds.get('register', None)
            self.until                    = ds.get('until')
            self.module_vars['until']     = self.until

        # rather than simple key=value args on the options line, these represent structured data and the values
        # can be hashes and lists, not just scalars
        self.args         = ds.get('args', {})

        # get remote_user for task, then play, then playbook
        if ds.get('remote_user') is not None:
            self.remote_user      = ds.get('remote_user')
        elif ds.get('remote_user', play.remote_user) is not None:
            self.remote_user      = ds.get('remote_user', play.remote_user)
        else:
            self.remote_user      = ds.get('remote_user', play.playbook.remote_user)

        self.sudo_user    = None
        self.sudo_pass    = None
        self.su_user      = None
        self.su_pass      = None

        if self.sudo:
            self.sudo_user    = ds.get('sudo_user', play.sudo_user)
            self.sudo_pass    = ds.get('sudo_pass', play.playbook.sudo_pass)
        elif self.su:
            self.su_user      = ds.get('su_user', play.su_user)
            self.su_pass      = ds.get('su_pass', play.playbook.su_pass)

        # Fail out if user specifies a sudo param with a su param in a given play
        if (ds.get('sudo') or ds.get('sudo_user') or ds.get('sudo_pass')) and \
                (ds.get('su') or ds.get('su_user') or ds.get('su_pass')):
            raise errors.AnsibleError('sudo params ("sudo", "sudo_user", "sudo_pass") '
                                      'and su params "su", "su_user", "su_pass") '
                                      'cannot be used together')

        # Both are defined
        if ('action' in ds) and ('local_action' in ds):
            raise errors.AnsibleError("the 'action' and 'local_action' attributes can not be used together")
        # Both are NOT defined
        elif (not 'action' in ds) and (not 'local_action' in ds):
            raise errors.AnsibleError("'action' or 'local_action' attribute missing in task \"%s\"" % ds.get('name', '<Unnamed>'))
        # Only one of them is defined
        elif 'local_action' in ds:
            self.action      = ds.get('local_action', '')
            self.delegate_to = '127.0.0.1'
        else:
            self.action      = ds.get('action', '')
            self.delegate_to = ds.get('delegate_to', None)
            self.transport   = ds.get('connection', ds.get('transport', play.transport))

        if isinstance(self.action, dict):
            if 'module' not in self.action:
                raise errors.AnsibleError("'module' attribute missing from action in task \"%s\"" % ds.get('name', '%s' % self.action))
            if self.args:
                raise errors.AnsibleError("'args' cannot be combined with dict 'action' in task \"%s\"" % ds.get('name', '%s' % self.action))
            self.args = self.action
            self.action = self.args.pop('module')

        # delegate_to can use variables
        if not (self.delegate_to is None):
            # delegate_to: localhost should use local transport
            if self.delegate_to in ['127.0.0.1', 'localhost']:
                self.transport   = 'local'

        # notified by is used by Playbook code to flag which hosts
        # need to run a notifier
        self.notified_by = []

        # if no name is specified, use the action line as the name
        if self.name is None:
            self.name = self.action

        # load various attributes
        self.when    = ds.get('when', None)
        self.changed_when = ds.get('changed_when', None)
        self.failed_when = ds.get('failed_when', None)

        # combine the default and module vars here for use in templating
        all_vars = self.default_vars.copy()
        all_vars = utils.combine_vars(all_vars, self.module_vars)

        self.async_seconds = ds.get('async', 0)  # not async by default
        self.async_seconds = template.template_from_string(play.basedir, self.async_seconds, all_vars)
        self.async_seconds = int(self.async_seconds)
        self.async_poll_interval = ds.get('poll', 10)  # default poll = 10 seconds
        self.async_poll_interval = template.template_from_string(play.basedir, self.async_poll_interval, all_vars)
        self.async_poll_interval = int(self.async_poll_interval)
        self.notify = ds.get('notify', [])
        self.first_available_file = ds.get('first_available_file', None)

        self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
        self.items_lookup_terms  = ds.get('items_lookup_terms', None)
     

        self.ignore_errors = ds.get('ignore_errors', False)
        self.any_errors_fatal = ds.get('any_errors_fatal', play.any_errors_fatal)

        self.always_run = ds.get('always_run', False)

        # action should be a string
        if not isinstance(self.action, basestring):
            raise errors.AnsibleError("action is of type '%s' and not a string in task. name: %s" % (type(self.action).__name__, self.name))

        # notify can be a string or a list, store as a list
        if isinstance(self.notify, basestring):
            self.notify = [ self.notify ]

        # split the action line into a module name + arguments
        try:
            tokens = split_args(self.action)
        except Exception, e:
            if "unbalanced" in str(e):
                raise errors.AnsibleError("There was an error while parsing the task %s.\n" % repr(self.action) + \
                                          "Make sure quotes are matched or escaped properly")
            else:
                raise
Example #44
0
    def __init__(self, playbook, ds, basedir, vault_password=None):
        ''' constructor loads from a play datastructure '''

        for x in ds.keys():
            if not x in Play.VALID_KEYS:
                raise errors.AnsibleError("%s is not a legal parameter of an Ansible Play" % x)

        # allow all playbook keys to be set by --extra-vars
        self.vars             = ds.get('vars', {})
        self.vars_prompt      = ds.get('vars_prompt', {})
        self.playbook         = playbook
        self.vars             = self._get_vars()
        self.vars_file_vars   = dict() # these are vars read in from vars_files:
        self.role_vars        = dict() # these are vars read in from vars/main.yml files in roles
        self.basedir          = basedir
        self.roles            = ds.get('roles', None)
        self.tags             = ds.get('tags', None)
        self.vault_password   = vault_password
        self.environment      = ds.get('environment', {})

        if self.tags is None:
            self.tags = []
        elif type(self.tags) in [ str, unicode ]:
            self.tags = self.tags.split(",")
        elif type(self.tags) != list:
            self.tags = []

        # make sure we have some special internal variables set, which
        # we use later when loading tasks and handlers
        load_vars = dict()
        load_vars['playbook_dir'] = os.path.abspath(self.basedir)
        if self.playbook.inventory.basedir() is not None:
            load_vars['inventory_dir'] = self.playbook.inventory.basedir()
        if self.playbook.inventory.src() is not None:
            load_vars['inventory_file'] = self.playbook.inventory.src()

        # We first load the vars files from the datastructure
        # so we have the default variables to pass into the roles
        self.vars_files = ds.get('vars_files', [])
        if not isinstance(self.vars_files, list):
            raise errors.AnsibleError('vars_files must be a list')
        processed_vars_files = self._update_vars_files_for_host(None)

        # now we load the roles into the datastructure
        self.included_roles = []
        ds = self._load_roles(self.roles, ds)

        # and finally re-process the vars files as they may have been updated
        # by the included roles, but exclude any which have been processed
        self.vars_files = utils.list_difference(ds.get('vars_files', []), processed_vars_files)
        if not isinstance(self.vars_files, list):
            raise errors.AnsibleError('vars_files must be a list')

        self._update_vars_files_for_host(None)

        # template everything to be efficient, but do not pre-mature template
        # tasks/handlers as they may have inventory scope overrides. We also
        # create a set of temporary variables for templating, so we don't
        # trample on the existing vars structures
        _tasks    = ds.pop('tasks', [])
        _handlers = ds.pop('handlers', [])

        temp_vars = utils.combine_vars(self.vars, self.vars_file_vars)
        temp_vars = utils.combine_vars(temp_vars, self.playbook.extra_vars)

        try:
            ds = template(basedir, ds, temp_vars)
        except errors.AnsibleError, e:
            utils.warning("non fatal error while trying to template play variables: %s" % (str(e)))
Example #45
0
    def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None):
        ''' constructor loads from a task or handler datastructure '''

        # meta directives are used to tell things like ansible/playbook to run
        # operations like handler execution.  Meta tasks are not executed
        # normally.
        if 'meta' in ds:
            self.meta = ds['meta']
            self.tags = []
            return
        else:
            self.meta = None


        library = os.path.join(play.basedir, 'library')
        if os.path.exists(library):
            utils.plugins.module_finder.add_directory(library)

        for x in ds.keys():

            # code to allow for saying "modulename: args" versus "action: modulename args"
            if x in utils.plugins.module_finder:

                if 'action' in ds:
                    raise errors.AnsibleError("multiple actions specified in task %s" % (ds.get('name', ds['action'])))
                if isinstance(ds[x], dict):
                    if 'args' in ds:
                        raise errors.AnsibleError("can't combine args: and a dict for %s: in task %s" % (x, ds.get('name', "%s: %s" % (x, ds[x]))))
                    ds['args'] = ds[x]
                    ds[x] = ''
                elif ds[x] is None:
                    ds[x] = ''
                if not isinstance(ds[x], basestring):
                    raise errors.AnsibleError("action specified for task %s has invalid type %s" % (ds.get('name', "%s: %s" % (x, ds[x])), type(ds[x])))
                ds['action'] = x + " " + ds[x]
                ds.pop(x)

            # code to allow "with_glob" and to reference a lookup plugin named glob
            elif x.startswith("with_"):

                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unneccessary to use '{{' in loops, leave variables in loop expressions bare.")

                plugin_name = x.replace("with_","")
                if plugin_name in utils.plugins.lookup_loader:
                    ds['items_lookup_plugin'] = plugin_name
                    ds['items_lookup_terms'] = ds[x]
                    ds.pop(x)
                else:
                    raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))

            elif x in [ 'changed_when', 'failed_when', 'when']:
                if isinstance(ds[x], basestring) and ds[x].lstrip().startswith("{{"):
                    utils.warning("It is unneccessary to use '{{' in conditionals, leave variables in loop expressions bare.")
            elif x.startswith("when_"):
                utils.deprecated("The 'when_' conditional has been removed. Switch to using the regular unified 'when' statements as described in ansibleworks.com/docs/.","1.5", removed=True)

                if 'when' in ds:
                    raise errors.AnsibleError("multiple when_* statements specified in task %s" % (ds.get('name', ds['action'])))
                when_name = x.replace("when_","")
                ds['when'] = "%s %s" % (when_name, ds[x])
                ds.pop(x)

            elif not x in Task.VALID_KEYS:
                raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)

        self.module_vars  = module_vars
        self.default_vars = default_vars
        self.play         = play

        # load various attributes
        self.name         = ds.get('name', None)
        self.tags         = [ 'all' ]
        self.register     = ds.get('register', None)
        self.sudo         = utils.boolean(ds.get('sudo', play.sudo))
        self.environment  = ds.get('environment', {})
        self.role_name    = role_name
        
        #Code to allow do until feature in a Task 
        if 'until' in ds:
            if not ds.get('register'):
                raise errors.AnsibleError("register keyword is mandatory when using do until feature")
            self.module_vars['delay']     = ds.get('delay', 5)
            self.module_vars['retries']   = ds.get('retries', 3)
            self.module_vars['register']  = ds.get('register', None)
            self.until                    = ds.get('until')
            self.module_vars['until']     = self.until

        # rather than simple key=value args on the options line, these represent structured data and the values
        # can be hashes and lists, not just scalars
        self.args         = ds.get('args', {})

        # get remote_user for task, then play, then playbook
        if ds.get('remote_user') is not None:
            self.remote_user      = ds.get('remote_user')
        elif ds.get('remote_user', play.remote_user) is not None:
            self.remote_user      = ds.get('remote_user', play.remote_user)
        else:
            self.remote_user      = ds.get('remote_user', play.playbook.remote_user)

        if self.sudo:
            self.sudo_user    = ds.get('sudo_user', play.sudo_user)
            self.sudo_pass    = ds.get('sudo_pass', play.playbook.sudo_pass)
        else:
            self.sudo_user    = None
            self.sudo_pass    = None
        
        # Both are defined
        if ('action' in ds) and ('local_action' in ds):
            raise errors.AnsibleError("the 'action' and 'local_action' attributes can not be used together")
        # Both are NOT defined
        elif (not 'action' in ds) and (not 'local_action' in ds):
            raise errors.AnsibleError("'action' or 'local_action' attribute missing in task \"%s\"" % ds.get('name', '<Unnamed>'))
        # Only one of them is defined
        elif 'local_action' in ds:
            self.action      = ds.get('local_action', '')
            self.delegate_to = '127.0.0.1'
        else:
            self.action      = ds.get('action', '')
            self.delegate_to = ds.get('delegate_to', None)
            self.transport   = ds.get('connection', ds.get('transport', play.transport))

        if isinstance(self.action, dict):
            if 'module' not in self.action:
                raise errors.AnsibleError("'module' attribute missing from action in task \"%s\"" % ds.get('name', '%s' % self.action))
            if self.args:
                raise errors.AnsibleError("'args' cannot be combined with dict 'action' in task \"%s\"" % ds.get('name', '%s' % self.action))
            self.args = self.action
            self.action = self.args.pop('module')

        # delegate_to can use variables
        if not (self.delegate_to is None):
            # delegate_to: localhost should use local transport
            if self.delegate_to in ['127.0.0.1', 'localhost']:
                self.transport   = 'local'

        # notified by is used by Playbook code to flag which hosts
        # need to run a notifier
        self.notified_by = []

        # if no name is specified, use the action line as the name
        if self.name is None:
            self.name = self.action

        # load various attributes
        self.when    = ds.get('when', None)
        self.changed_when = ds.get('changed_when', None)
        self.failed_when = ds.get('failed_when', None)

        self.async_seconds = int(ds.get('async', 0))  # not async by default
        self.async_poll_interval = int(ds.get('poll', 10))  # default poll = 10 seconds
        self.notify = ds.get('notify', [])
        self.first_available_file = ds.get('first_available_file', None)

        self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
        self.items_lookup_terms  = ds.get('items_lookup_terms', None)
     

        self.ignore_errors = ds.get('ignore_errors', False)
        self.any_errors_fatal = ds.get('any_errors_fatal', play.any_errors_fatal)

        self.always_run = ds.get('always_run', False)

        # action should be a string
        if not isinstance(self.action, basestring):
            raise errors.AnsibleError("action is of type '%s' and not a string in task. name: %s" % (type(self.action).__name__, self.name))

        # notify can be a string or a list, store as a list
        if isinstance(self.notify, basestring):
            self.notify = [ self.notify ]

        # split the action line into a module name + arguments
        tokens = self.action.split(None, 1)
        if len(tokens) < 1:
            raise errors.AnsibleError("invalid/missing action in task. name: %s" % self.name)
        self.module_name = tokens[0]
        self.module_args = ''
        if len(tokens) > 1:
            self.module_args = tokens[1]

        import_tags = self.module_vars.get('tags',[])
        if type(import_tags) in [int,float]:
            import_tags = str(import_tags)
        elif type(import_tags) in [str,unicode]:
            # allow the user to list comma delimited tags
            import_tags = import_tags.split(",")

        # handle mutually incompatible options
        incompatibles = [ x for x in [ self.first_available_file, self.items_lookup_plugin ] if x is not None ]
        if len(incompatibles) > 1:
            raise errors.AnsibleError("with_(plugin), and first_available_file are mutually incompatible in a single task")

        # make first_available_file accessable to Runner code
        if self.first_available_file:
            self.module_vars['first_available_file'] = self.first_available_file

        if self.items_lookup_plugin is not None:
            self.module_vars['items_lookup_plugin'] = self.items_lookup_plugin
            self.module_vars['items_lookup_terms'] = self.items_lookup_terms

        # allow runner to see delegate_to option
        self.module_vars['delegate_to'] = self.delegate_to

        # make some task attributes accessible to Runner code
        self.module_vars['ignore_errors'] = self.ignore_errors
        self.module_vars['register'] = self.register
        self.module_vars['changed_when'] = self.changed_when
        self.module_vars['failed_when'] = self.failed_when
        self.module_vars['always_run'] = self.always_run

        # tags allow certain parts of a playbook to be run without running the whole playbook
        apply_tags = ds.get('tags', None)
        if apply_tags is not None:
            if type(apply_tags) in [ str, unicode ]:
                self.tags.append(apply_tags)
            elif type(apply_tags) in [ int, float ]:
                self.tags.append(str(apply_tags))
            elif type(apply_tags) == list:
                self.tags.extend(apply_tags)
        self.tags.extend(import_tags)

        if additional_conditions:
            new_conditions = additional_conditions
            new_conditions.append(self.when)
            self.when = new_conditions
Example #46
0
def main(args):
    ''' run ansible-playbook operations '''

    ## truiz: here I add options that will become parameters in the function

    ## truiz: extra vars is dict with the vars and values
    extra_vars = {'host': 'testing', 'vars_file': 'the_vars.yml'}
    print extra_vars

    ## truiz: this is just a list of playbooks
    playbooks = ['ansible/the_work.yml']

    ## truiz: The file with hosts and their vars
    inventory_file = 'ansible/inventory'

    ## truiz: this could be an usefull parameter
    timeout = 10

    # create parser for CLI options
    parser = utils.base_parser(constants=C,
                               usage="%prog playbook.yml",
                               connect_opts=True,
                               runas_opts=True,
                               subset_opts=True,
                               check_opts=True,
                               diff_opts=True)
    parser.add_option('--vault-password',
                      dest="vault_password",
                      help="password for vault encrypted files")
    parser.add_option(
        '--syntax-check',
        dest='syntax',
        action='store_true',
        help="perform a syntax check on the playbook, but do not execute it")
    parser.add_option('--list-tasks',
                      dest='listtasks',
                      action='store_true',
                      help="list all tasks that would be executed")
    parser.add_option('--list-tags',
                      dest='listtags',
                      action='store_true',
                      help="list all available tags")
    parser.add_option('--start-at-task',
                      dest='start_at',
                      help="start the playbook at the task matching this name")
    parser.add_option('--force-handlers',
                      dest='force_handlers',
                      default=C.DEFAULT_FORCE_HANDLERS,
                      action='store_true',
                      help="run handlers even if a task fails")
    parser.add_option('--flush-cache',
                      dest='flush_cache',
                      action='store_true',
                      help="clear the fact cache")

    options, args = parser.parse_args(args)

    if len(args) == 0:
        parser.print_help(file=sys.stderr)
        return 1

    # privlege escalation command line arguments need to be mutually exclusive
    # utils.check_mutually_exclusive_privilege(options, parser)

    # if (options.ask_vault_pass and options.vault_password_file):
    # parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive")

    sshpass = None
    becomepass = None
    vault_pass = None

    # options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS

    # if options.listhosts or options.syntax or options.listtasks or options.listtags:
    #     (_, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass)
    # else:
    #     options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS
    #     # Never ask for an SSH password when we run with local connection
    #     if options.connection == "local":
    #         options.ask_pass = False

    #     # set pe options
    #     utils.normalize_become_options(options)
    #     prompt_method = utils.choose_pass_prompt(options)
    #     (sshpass, becomepass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass,
    #                                                 become_ask_pass=options.become_ask_pass,
    #                                                 ask_vault_pass=options.ask_vault_pass,
    #                                                 become_method=prompt_method)

    # read vault_pass from a file
    # if not options.ask_vault_pass and options.vault_password_file:
    # vault_pass = utils.read_vault_file(options.vault_password_file)

    for playbook in playbooks:
        print playbook
        if not os.path.exists(playbook):
            raise errors.AnsibleError("the playbook: %s could not be found" %
                                      playbook)
        if not (os.path.isfile(playbook)
                or stat.S_ISFIFO(os.stat(playbook).st_mode)):
            raise errors.AnsibleError(
                "the playbook: %s does not appear to be a file" % playbook)

    ## truiz: is better to pass the inventory file
    inventory = ansible.inventory.Inventory(inventory_file,
                                            vault_password=vault_pass)
    print options.inventory
    print inventory
    # Note: slightly wrong, this is written so that implicit localhost
    # (which is not returned in list_hosts()) is taken into account for
    # warning if inventory is empty.  But it can't be taken into account for
    # checking if limit doesn't match any hosts.  Instead we don't worry about
    # limit if only implicit localhost was in inventory to start with.
    #
    # Fix this in v2
    no_hosts = False
    if len(inventory.list_hosts()) == 0:
        # Empty inventory
        utils.warning(
            "provided hosts list is empty, only localhost is available")
        no_hosts = True
    #print options.subset
    #inventory.subset(options.subset)
    if len(inventory.list_hosts()) == 0 and no_hosts is False:
        # Invalid limit
        raise errors.AnsibleError("Specified --limit does not match any hosts")
    print options.become
    print options.become_user
    print options.remote_user
    print options.timeout
    print becomepass

    for playbook in playbooks:

        stats = callbacks.AggregateStats()
        playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
        runner_cb = callbacks.PlaybookRunnerCallbacks(stats,
                                                      verbose=utils.VERBOSITY)
        print runner_cb

        pb = ansible.playbook.PlayBook(
            playbook=playbook,
            # module_path=options.module_path,
            inventory=inventory,
            # forks=options.forks,
            # remote_user=options.remote_user,
            # remote_pass=sshpass,
            callbacks=playbook_cb,
            runner_callbacks=runner_cb,
            stats=stats,
            timeout=timeout,
            # transport=options.connection,
            #become=options.become,
            become_method='sudo',
            become_user=options.become_user,
            # become_pass=becomepass,
            extra_vars=extra_vars,
            private_key_file=options.private_key_file,
            # only_tags=only_tags,
            # skip_tags=skip_tags,
            check=options.check,
            diff=options.diff,
            # vault_password=vault_pass,
            force_handlers=options.force_handlers,
        )

        # if options.flush_cache:
        #     display(callbacks.banner("FLUSHING FACT CACHE"))
        #     pb.SETUP_CACHE.flush()

        # if options.listhosts or options.listtasks or options.syntax or options.listtags:
        #     print ''
        #     print 'playbook: %s' % playbook
        #     print ''
        #     playnum = 0
        #     for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs):
        #         playnum += 1
        #         play = ansible.playbook.Play(pb, play_ds, play_basedir,
        #                                       vault_password=pb.vault_password)
        #         label = play.name
        #         hosts = pb.inventory.list_hosts(play.hosts)

        #         if options.listhosts:
        #             print '  play #%d (%s): host count=%d' % (playnum, label, len(hosts))
        #             for host in hosts:
        #                 print '    %s' % host

        #         if options.listtags or options.listtasks:
        #             print '  play #%d (%s):\tTAGS: [%s]' % (playnum, label,','.join(sorted(set(play.tags))))

        #             if options.listtags:
        #                 tags = []
        #                 for task in pb.tasks_to_run_in_play(play):
        #                     tags.extend(task.tags)
        #                 print '    TASK TAGS: [%s]' % (', '.join(sorted(set(tags).difference(['untagged']))))

        #             if options.listtasks:

        #                 for task in pb.tasks_to_run_in_play(play):
        #                     if getattr(task, 'name', None) is not None:
        #                         # meta tasks have no names
        #                         print '    %s\tTAGS: [%s]' % (task.name, ', '.join(sorted(set(task.tags).difference(['untagged']))))

        #         if options.listhosts or options.listtasks or options.listtags:
        #             print ''
        #     continue

        # if options.syntax:
        #     # if we've not exited by now then we are fine.
        #     print 'Playbook Syntax is fine'
        #     return 0

        failed_hosts = []
        unreachable_hosts = []

        try:
            print "Before run"
            res = pb.run()
            print "After run"
            ## truiz: returns a resume of all work done
            print res
            hosts = sorted(pb.stats.processed.keys())
            display(callbacks.banner("PLAY RECAP"))
            playbook_cb.on_stats(pb.stats)

            for h in hosts:
                t = pb.stats.summarize(h)
                if t['failures'] > 0:
                    failed_hosts.append(h)
                if t['unreachable'] > 0:
                    unreachable_hosts.append(h)

            retries = failed_hosts + unreachable_hosts

            if C.RETRY_FILES_ENABLED and len(retries) > 0:
                filename = pb.generate_retry_inventory(retries)
                if filename:
                    display("           to retry, use: --limit @%s\n" %
                            filename)

            for h in hosts:
                t = pb.stats.summarize(h)

                display("%s : %s %s %s %s" %
                        (hostcolor(h, t), colorize('ok', t['ok'], 'green'),
                         colorize('changed', t['changed'], 'yellow'),
                         colorize('unreachable', t['unreachable'], 'red'),
                         colorize('failed', t['failures'], 'red')),
                        screen_only=True)

                display("%s : %s %s %s %s" %
                        (hostcolor(h, t, False), colorize('ok', t['ok'], None),
                         colorize('changed', t['changed'], None),
                         colorize('unreachable', t['unreachable'], None),
                         colorize('failed', t['failures'], None)),
                        log_only=True)

            print ""
            if len(failed_hosts) > 0:
                return 2
            if len(unreachable_hosts) > 0:
                return 3

        except errors.AnsibleError, e:
            display("ERROR: %s" % e, color='red')
            return 1