Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: discovered hosts returned as dict #25

Merged
merged 3 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions nectl/configs/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def render_cmd(
role=role,
deployment_group=deployment_group,
)
nectl.render_configs(hosts=hosts)
nectl.render_configs(hosts=hosts.values())
except (DiscoveryError, RenderError) as e:
print(f"Error: {e}")
sys.exit(1)
Expand Down Expand Up @@ -103,7 +103,7 @@ def diff_cmd(
deployment_group=deployment_group,
)
nectl.diff_configs(
hosts=hosts,
hosts=hosts.values(),
username=username,
password=password,
ssh_private_key_file=ssh_key,
Expand Down Expand Up @@ -158,7 +158,7 @@ def apply_cmd(
)

print("Applying config to:")
print("\n".join([f"- {host.id}" for host in hosts]))
print("\n".join([f"- {host}" for host in hosts.keys()]))

if not assumeyes:
click.confirm(
Expand All @@ -167,7 +167,7 @@ def apply_cmd(
)

nectl.apply_configs(
hosts=hosts,
hosts=hosts.values(),
username=username,
password=password,
ssh_private_key_file=ssh_key,
Expand Down Expand Up @@ -214,7 +214,7 @@ def get_cmd(
deployment_group=deployment_group,
)
nectl.get_configs(
hosts=hosts,
hosts=hosts.values(),
username=username,
password=password,
ssh_private_key_file=ssh_key,
Expand Down
8 changes: 5 additions & 3 deletions nectl/datatree/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,13 @@ def list_hosts_cmd(
sys.exit(1)

if output == "json":
print(json.dumps({h.id: h.dict() for h in hosts}, indent=4, default=str))
print(
json.dumps({h.id: h.dict() for h in hosts.values()}, indent=4, default=str)
)
else:
print(
tabulate(
[h.dict() for h in hosts],
[h.dict() for h in hosts.values()],
headers="keys",
tablefmt="psql",
)
Expand Down Expand Up @@ -118,7 +120,7 @@ def get_facts_cmd(
print(f"Error: {e}")
sys.exit(1)

host_facts = {host.id: host.facts for host in hosts}
host_facts = {host.id: host.facts for host in hosts.values()}

if not check:
print(facts_to_json_string(host_facts))
22 changes: 11 additions & 11 deletions nectl/datatree/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def get_filtered_hosts(
site: str = None,
role: str = None,
deployment_group: str = None,
) -> List[Host]:
) -> Dict[str, Host]:
"""
Returns a list of filtered hosts

Expand All @@ -178,7 +178,7 @@ def get_filtered_hosts(
deployment_group (str): filter by deployment group.

Returns:
List[Host]: list of discovered hosts.
Dict[str, Host]: discovered host instances mapped by host ID.

Raises:
DiscoveryError: if hosts cannot be successfully discovered.
Expand All @@ -205,18 +205,18 @@ def is_match(host: Host) -> bool:
return False
return True

hosts = []
hosts = {}

# Loop hosts
for host in get_all_hosts(settings=settings):
for host in get_all_hosts(settings=settings).values():
# Check for match against filters
if is_match(host):
# Add host
hosts.append(host)
hosts[host.id] = host

logger.info(
f"filter matched {len(hosts)} hosts: "
f"{','.join([host.id for host in hosts])}"
f"{','.join([host for host in hosts.keys()])}"
)

if len(hosts) == 0:
Expand Down Expand Up @@ -251,7 +251,7 @@ def _get_host_datatree_path_vars(host_path: str, datatree_dirname: str) -> dict:
]

# Extract host module import path
m = re.match(re.compile(fr".*({datatree_dirname}\/.*?)(\.py)?$"), host_path)
m = re.match(re.compile(rf".*({datatree_dirname}\/.*?)(\.py)?$"), host_path)
if m:
try:
# Import host module
Expand All @@ -269,20 +269,20 @@ def _get_host_datatree_path_vars(host_path: str, datatree_dirname: str) -> dict:
return {}


def get_all_hosts(settings: Settings) -> List[Host]:
def get_all_hosts(settings: Settings) -> Dict[str, Host]:
"""
Returns list of all discovered hosts from datatree.

Args:
settings (Settings): config settings.

Returns:
List[Host]: list of discovered hosts.
Dict[str, Host]: discovered host instances mapped by host ID.

Raises:
DiscoveryError: if hosts cannot be successfully discovered.
"""
hosts: List[Host] = []
hosts: Dict[str, Host] = {}
hostname: str = ""
site: Optional[str] = None
customer: Optional[str] = None
Expand Down Expand Up @@ -359,7 +359,7 @@ def get_all_hosts(settings: Settings) -> List[Host]:
**host_vars,
)
logger.debug(f"found host '{new_host.id}' in: {host_dir}")
hosts.append(new_host)
hosts[new_host.id] = new_host

dur = f"{time.perf_counter()-ts_start:0.4f}"
logger.info(f"finished discovery of {len(hosts)} hosts ({dur}s)")
Expand Down
8 changes: 5 additions & 3 deletions nectl/nectl.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with Nectl. If not, see <http://www.gnu.org/licenses/>.

from typing import Optional, List
from typing import Optional, List, Dict

from .logging import get_logger
from .settings import load_settings, Settings
Expand All @@ -38,15 +38,14 @@ def __init__(
"""
self.settings = settings if settings else load_settings(filepath=kit_filepath)

# TODO: return dict of hosts instead
def get_hosts(
self,
hostname: Optional[str] = None,
customer: Optional[str] = None,
site: Optional[str] = None,
role: Optional[str] = None,
deployment_group: Optional[str] = None,
) -> List[Host]:
) -> Dict[str, Host]:
"""
Get hosts from datatree that match supplied filter parameters.

Expand All @@ -57,6 +56,9 @@ def get_hosts(
role (str): optional role to filter by.
deployment_group (str): optional deployment_group to filter by.

Returns:
Dict[str, Host]: discovered host instances mapped by host ID.

Raises:
DiscoveryError: when an error has been encountered during data tree discovery.
"""
Expand Down
40 changes: 27 additions & 13 deletions tests/integration/test_hosts_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ def test_should_return_8_hosts_when_getting_all_hosts(mock_settings):
# WHEN fetching all hosts
hosts = get_all_hosts(settings=settings)

# THEN expect each host to be of Host type
for host in hosts:
for host_id, host in hosts.items():
# THEN expect each host to be of Host type
assert isinstance(host, Host), host

# THEN expect host ID key
assert host_id == host.id

# THEN expect to have 8 hosts
assert len(hosts) == 8

Expand Down Expand Up @@ -99,7 +102,7 @@ def test_should_return_no_customer_when_when_getting_all_hosts_and_no_customer_r
settings.hosts_customer_regex = None

# WHEN fetching all hosts
hosts = get_all_hosts(settings=settings)
hosts = list(get_all_hosts(settings=settings).values())

# THEN expect site to be set
assert hosts[0].site is not None
Expand All @@ -119,7 +122,7 @@ def test_should_return_no_customer_and_site_when_when_getting_all_hosts_and_no_c
settings.hosts_site_regex = None

# WHEN fetching all hosts
hosts = get_all_hosts(settings=settings)
hosts = list(get_all_hosts(settings=settings).values())

# THEN expect customer to be none
assert hosts[0].customer is None
Expand All @@ -128,7 +131,7 @@ def test_should_return_no_customer_and_site_when_when_getting_all_hosts_and_no_c
assert hosts[0].customer is None


def test_should_return_empty_list_when_getting_filtered_hosts_that_dont_exist(
def test_should_return_empty_dict_when_getting_filtered_hosts_that_dont_exist(
mock_settings,
):
# GIVEN settings using mock kit
Expand All @@ -143,8 +146,8 @@ def test_should_return_empty_list_when_getting_filtered_hosts_that_dont_exist(
# WHEN fetching hosts and using filters
hosts = get_filtered_hosts(settings=settings, site=site, customer=customer)

# THEN expect result to be empty list
assert hosts == []
# THEN expect result to be empty dict
assert hosts == {}


def test_should_return_2_hosts_when_getting_filtered_hosts_by_site_and_customer(
Expand All @@ -165,10 +168,13 @@ def test_should_return_2_hosts_when_getting_filtered_hosts_by_site_and_customer(
# THEN expect to have 2 hosts
assert len(hosts) == 2

for host in hosts:
for host_id, host in hosts.items():
# THEN expect each result to be of Host type
assert isinstance(host, Host), host

# THEN expect host ID key
assert host_id == host.id

# THEN expect host customer
assert host.customer == customer

Expand All @@ -194,10 +200,13 @@ def test_should_return_2_hosts_when_getting_filtered_hosts_by_site_and_role(
# THEN expect to have 2 hosts
assert len(hosts) == 2

for host in hosts:
for host_id, host in hosts.items():
# THEN expect each result to be of Host type
assert isinstance(host, Host), host

# THEN expect host ID key
assert host_id == host.id

# THEN expect host role
assert host.role == role

Expand Down Expand Up @@ -225,10 +234,13 @@ def test_should_return_2_hosts_when_getting_filtered_hosts_by_customer_and_deplo
# THEN expect to have 2 hosts
assert len(hosts) == 2

for host in hosts:
for host_id, host in hosts.items():
# THEN expect each result to be of Host type
assert isinstance(host, Host), host

# THEN expect host ID key
assert host_id == host.id

# THEN expect host customer
assert host.customer == customer

Expand All @@ -252,8 +264,10 @@ def test_should_return_host_properties_when_getting_filtered_hosts_by_site_and_c
hostname = "core0"

# WHEN fetching hosts and using filters
hosts = get_filtered_hosts(
settings=settings, site=site, customer=customer, hostname=hostname
hosts = list(
get_filtered_hosts(
settings=settings, site=site, customer=customer, hostname=hostname
).values()
)

# THEN expect one host
Expand Down Expand Up @@ -299,7 +313,7 @@ def test_should_return_hosts_when_getting_all_hosts_that_are_not_directories(tmp
)

# WHEN fetching all hosts
hosts = get_all_hosts(settings=settings)
hosts = list(get_all_hosts(settings=settings).values())

# THEN expect total hosts
assert len(hosts) == 1
Expand Down
Loading