Skip to content
This repository was archived by the owner on Apr 7, 2022. It is now read-only.
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
18 changes: 12 additions & 6 deletions cfme/common/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ def setup(self):
Sets up the provider robustly
"""
# TODO: Eventually this will become Sentakuified, but only after providers is CEMv3
if self.category in ['cloud', 'infra', 'physical']:
if self.category in ['cloud', 'infra', 'physical', 'config_manager']:
return self.create_rest(check_existing=True, validate_inventory=True)
else:
return self.create(cancel=False, validate_credentials=True,
Expand Down Expand Up @@ -710,8 +710,11 @@ def validate_stats(self, ui=False):
return
else:
# Set off a Refresh Relationships
method = 'ui' if ui else None
self.refresh_provider_relationships(method=method)
if self.category == "config_manager" and ui:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why go the route of making checks and changing function calls based on the category, instead of updating ConfigManager base class to be consistent with the BaseProvider methods?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked with Parthvi about this, due to the level of effort in updating BaseProvider/ConfigManager base class, I'm going to prioritize the test coverage over rejecting these customization within BaseProvider.

self.refresh_relationships()
else:
method = 'ui' if ui else None
self.refresh_provider_relationships(method=method)

refresh_timer = RefreshTimer(time_for_refresh=300)
wait_for(self._do_stats_match,
Expand All @@ -731,7 +734,8 @@ def refresh_provider_relationships(self, from_list_view=False,
"""
# from_list_view is ignored as it is included here for sake of compatibility with UI call.
logger.debug('Refreshing provider relationships')
col = self.appliance.rest_api.collections.providers.find_by(name=self.name)
name = self.ui_name if self.category == "config_manager" else self.name
col = self.appliance.rest_api.collections.providers.find_by(name=name)
try:
col[0].action.refresh()
self.wait_for_relationship_refresh(wait, delay, refresh_delta)
Expand Down Expand Up @@ -764,15 +768,17 @@ def wait_for_relationship_refresh(self, wait=600, delay=1, refresh_delta=10):
@variable(alias='rest')
def last_refresh_date(self):
try:
col = self.appliance.rest_api.collections.providers.find_by(name=self.name)[0]
name = self.ui_name if self.category == "config_manager" else self.name
col = self.appliance.rest_api.collections.providers.find_by(name=name)[0]
return col.last_refresh_date
except AttributeError:
return None

@variable(alias='rest')
def last_refresh_error(self):
try:
col = self.appliance.rest_api.collections.providers.find_by(name=self.name)[0]
name = self.ui_name if self.category == "config_manager" else self.name
col = self.appliance.rest_api.collections.providers.find_by(name=name)[0]
return col.last_refresh_error
except AttributeError:
return None
Expand Down
15 changes: 9 additions & 6 deletions cfme/infrastructure/config_management/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,14 +426,17 @@ def rest_api_entity(self):
})

# TODO: implement this via Sentaku
def create_rest(self):
def create_rest(self, check_existing=False, validate_inventory=False):
"""Create the config manager in CFME using REST"""
include_ssl = False
if check_existing and self.exists:
return False

logger.info("Setting up provider via REST: %s", self.key)

if self.type == "ansible_tower":
config_type = "AnsibleTower"
else:
config_type = "Foreman"
include_ssl = True

payload = {
"type": f"ManageIQ::Providers::{config_type}::Provider",
Expand All @@ -443,11 +446,9 @@ def create_rest(self):
"userid": self.credentials.view_value_mapping["username"],
"password": self.credentials.view_value_mapping["password"],
},
"verify_ssl": self.ssl,
}

if include_ssl:
payload["verify_ssl"] = self.ssl

try:
self.appliance.rest_api.post(
api_endpoint_url=self.appliance.url_path(
Expand All @@ -463,6 +464,8 @@ def create_rest(self):
raise AssertionError(
f"Provider wasn't added, status code {response.status_code}"
)
if validate_inventory:
self.validate(timeout=300)

assert_response(self.appliance)
return True
Expand Down
2 changes: 2 additions & 0 deletions cfme/infrastructure/config_management/ansible_tower.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class AnsibleTowerProvider(ConfigManagerProvider):
tower_cfg_mgr.delete()
"""
type_name = 'ansible_tower'
ssl = attr.ib(default=None)
ui_type = 'Ansible Tower'

_collections = {
Expand All @@ -96,6 +97,7 @@ def from_config(cls, prov_config, prov_key, appliance=None):
cls,
name=data['name'],
url=data['url'],
ssl=data['ssl'],
credentials=cls.Credential(
principal=creds['username'], secret=creds['password']),
key=prov_key
Expand Down
52 changes: 52 additions & 0 deletions cfme/tests/services/test_rest_services.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
from random import choice

import fauxfactory
import pytest
Expand All @@ -7,6 +8,7 @@
from manageiq_client.filters import Q

from cfme import test_requirements
from cfme.infrastructure.config_management.ansible_tower import AnsibleTowerProvider
from cfme.infrastructure.provider import InfraProvider
from cfme.markers.env_markers.provider import ONE
from cfme.rest.gen_data import _creating_skeleton
Expand Down Expand Up @@ -822,6 +824,35 @@ def check_returned_dialog(self, appliance):
dialog_fields, = dialog_groups['dialog_fields']
assert dialog_fields['name']

@pytest.fixture(
params=[
("OrchestrationTemplate", "OrchestrationTemplateServiceDialog"),
("ConfigurationScript", "AnsibleTowerJobTemplateDialogService"),
],
ids=["orchestration_templates", "configuration_scripts"],
)
def create_from_template(self, appliance, request):
rest_collection = appliance.rest_api.collections
template_class, dialog_class = request.param
payload = {
"label": fauxfactory.gen_alpha(start="dialog "),
"template_id": choice(
getattr(
rest_collection,
"orchestration_templates"
if template_class == "OrchestrationTemplate"
else "configuration_scripts",
).all
).id,
"template_class": template_class,
"dialog_class": f"Dialog::{dialog_class}",
}

service_dialog = rest_collection.service_dialogs.action.template_service_dialog(payload)[0]
yield service_dialog
if service_dialog.exists:
service_dialog.action.delete()

def test_query_service_dialog_attributes(self, service_dialogs, soft_assert):
"""Tests access to service dialog attributes.

Expand Down Expand Up @@ -929,6 +960,27 @@ def test_delete_service_dialogs(self, service_dialogs):
"""
delete_resources_from_collection(service_dialogs)

@pytest.mark.provider([AnsibleTowerProvider], override=True, scope="module", selector=ONE)
def test_create_from_template(self, appliance, setup_provider, create_from_template):
"""Tests dialog creation from template.
TODO:
AnsibleTowerProvider is not required while using OrchestrationTemplate, figure out a
way to setup provider only while using ConfigurationScript without writing separate
tests.

Metadata:
test_flag: rest

Polarion:
assignee: nansari
casecomponent: Rest
initialEstimate: 1/4h
tags: service
"""
dialog = create_from_template
get_dialog = appliance.rest_api.collections.service_dialogs.get(label=dialog.label)
assert get_dialog.exists


class TestServiceTemplateRESTAPI:
def test_query_service_templates_attributes(self, service_templates, soft_assert):
Expand Down