mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 05:42:50 +00:00
Merge branch 'devel' of https://github.com/fangchin/ansible into devel
This commit is contained in:
94
lib/ansible/inventory/expand_hosts.py
Normal file
94
lib/ansible/inventory/expand_hosts.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# (c) 2012, Zettar Inc.
|
||||
# Written by Chin Fang <fangchin@zettar.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
'''
|
||||
This module is for enhancing ansible's inventory parsing capability such
|
||||
that it can deal with hostnames specified using a simple pattern in the
|
||||
form of [beg:end], example: [1:5] where if beg is not specified, it
|
||||
defaults to 0.
|
||||
|
||||
If beg is given and is left-zero-padded, e.g. '001', it is taken as a
|
||||
formatting hint when the range is expanded. e.g. [001:010] is to be
|
||||
expanded into 001, 002 ...009, 010.
|
||||
|
||||
Note that when beg is specified with left zero padding, then the length of
|
||||
end must be the same as that of beg, else a exception is raised.
|
||||
'''
|
||||
|
||||
def detect_range(line = None):
|
||||
'''
|
||||
A helper function that checks a given host line to see if it contains
|
||||
a range pattern descibed in the docstring above.
|
||||
|
||||
Returnes True if the given line contains a pattern, else False.
|
||||
'''
|
||||
if (not line.startswith("[") and
|
||||
line.find("[") != -1 and
|
||||
line.find(":") != -1 and
|
||||
line.find("]") != -1 and
|
||||
line.index("[") < line.index(":") < line.index("]")):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def expand_hostname_range(line = None):
|
||||
'''
|
||||
A helper function that expands a given line that contains a pattern
|
||||
specified in top docstring, and returns a list that consists of the
|
||||
expanded version.
|
||||
|
||||
The '[' and ']' characters are used to maintain the pseudo-code
|
||||
appearance. They are replaced in this function with '|' to ease
|
||||
string splitting.
|
||||
|
||||
References: http://ansible.github.com/patterns.html#hosts-and-groups
|
||||
'''
|
||||
all_hosts = []
|
||||
if line:
|
||||
# A hostname such as db[1:6]-node is considered to consists
|
||||
# three parts:
|
||||
# head: 'db'
|
||||
# nrange: [1:6]; range() is a built-in. Can't use the name
|
||||
# tail: '-node'
|
||||
|
||||
(head, nrange, tail) = line.replace('[','|').replace(']','|').split('|')
|
||||
bounds = nrange.split(":")
|
||||
if len(bounds) != 2:
|
||||
raise ValueError("host range incorrectly specified!")
|
||||
beg = bounds[0]
|
||||
end = bounds[1]
|
||||
if not beg:
|
||||
beg = "0"
|
||||
if not end:
|
||||
raise ValueError("host range end value missing!")
|
||||
if beg[0] == '0' and len(beg) > 1:
|
||||
rlen = len(beg) # range length formatting hint
|
||||
else:
|
||||
rlen = None
|
||||
if rlen > 1 and rlen != len(end):
|
||||
raise ValueError("host range format incorrectly specified!")
|
||||
|
||||
for _ in range(int(beg), int(end)):
|
||||
if rlen:
|
||||
rseq = str(_).zfill(rlen) # range sequence
|
||||
else:
|
||||
rseq = str(_)
|
||||
hname = ''.join((head, rseq, tail))
|
||||
all_hosts.append(hname)
|
||||
|
||||
return all_hosts
|
||||
@@ -24,6 +24,8 @@ import subprocess
|
||||
import ansible.constants as C
|
||||
from ansible.inventory.host import Host
|
||||
from ansible.inventory.group import Group
|
||||
from ansible.inventory.expand_hosts import detect_range
|
||||
from ansible.inventory.expand_hosts import expand_hostname_range
|
||||
from ansible import errors
|
||||
from ansible import utils
|
||||
|
||||
@@ -80,21 +82,40 @@ class InventoryParser(object):
|
||||
continue
|
||||
hostname = tokens[0]
|
||||
port = C.DEFAULT_REMOTE_PORT
|
||||
if hostname.find(":") != -1:
|
||||
tokens2 = hostname.split(":")
|
||||
hostname = tokens2[0]
|
||||
port = tokens2[1]
|
||||
# Two cases to check:
|
||||
# 0. A hostname that contains a range pesudo-code and a port
|
||||
# 1. A hostname that contains just a port
|
||||
if (hostname.find("[") != -1 and
|
||||
hostname.find("]") != -1 and
|
||||
hostname.find(":") != -1 and
|
||||
(hostname.rindex("]") < hostname.rindex(":")) or
|
||||
(hostname.find("]") == -1 and hostname.find(":") != -1)):
|
||||
tokens2 = hostname.rsplit(":", 1)
|
||||
hostname = tokens2[0]
|
||||
port = tokens2[1]
|
||||
|
||||
host = None
|
||||
_all_hosts = []
|
||||
if hostname in self.hosts:
|
||||
host = self.hosts[hostname]
|
||||
_all_hosts.append(host)
|
||||
else:
|
||||
host = Host(name=hostname, port=port)
|
||||
self.hosts[hostname] = host
|
||||
if detect_range(hostname):
|
||||
_hosts = expand_hostname_range(hostname)
|
||||
for _ in _hosts:
|
||||
host = Host(name=_, port=port)
|
||||
self.hosts[_] = host
|
||||
_all_hosts.append(host)
|
||||
else:
|
||||
host = Host(name=hostname, port=port)
|
||||
self.hosts[hostname] = host
|
||||
_all_hosts.append(host)
|
||||
if len(tokens) > 1:
|
||||
for t in tokens[1:]:
|
||||
(k,v) = t.split("=")
|
||||
host.set_variable(k,v)
|
||||
self.groups[active_group_name].add_host(host)
|
||||
for _ in _all_hosts:
|
||||
self.groups[active_group_name].add_host(_)
|
||||
|
||||
# [southeast:children]
|
||||
# atlanta
|
||||
|
||||
Reference in New Issue
Block a user