mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 09:27:36 -02:30
Merge branch 'devel' into 6967-prompt-credential-password
This commit is contained in:
@@ -39,9 +39,11 @@ class V1CredentialFilterBackend(BaseFilterBackend):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def filter_queryset(self, request, queryset, view):
|
def filter_queryset(self, request, queryset, view):
|
||||||
|
# TODO: remove in 3.3
|
||||||
from awx.api.versioning import get_request_version
|
from awx.api.versioning import get_request_version
|
||||||
if get_request_version(request) == 1:
|
if get_request_version(request) == 1:
|
||||||
queryset = queryset.filter(credential_type__managed_by_tower=True)
|
queryset = queryset.filter(credential_type__managed_by_tower=True)
|
||||||
|
queryset = queryset.filter(~Q(credential_type__kind='insights'))
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1390,7 +1390,9 @@ class GroupSerializer(BaseSerializerWithVariables):
|
|||||||
def create(self, validated_data): # TODO: remove in 3.3
|
def create(self, validated_data): # TODO: remove in 3.3
|
||||||
instance = super(GroupSerializer, self).create(validated_data)
|
instance = super(GroupSerializer, self).create(validated_data)
|
||||||
if self.version == 1: # TODO: remove in 3.3
|
if self.version == 1: # TODO: remove in 3.3
|
||||||
InventorySource.objects.create(deprecated_group=instance, inventory=instance.inventory)
|
manual_src = InventorySource(deprecated_group=instance, inventory=instance.inventory)
|
||||||
|
manual_src.v1_group_name = instance.name
|
||||||
|
manual_src.save()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_name(self, value):
|
def validate_name(self, value):
|
||||||
|
|||||||
@@ -2119,7 +2119,7 @@ class HostInsights(GenericAPIView):
|
|||||||
if host.inventory and host.inventory.insights_credential:
|
if host.inventory and host.inventory.insights_credential:
|
||||||
cred = host.inventory.insights_credential
|
cred = host.inventory.insights_credential
|
||||||
else:
|
else:
|
||||||
return Response(dict(error=_('No Insights Credential found for the Inventory, "{}", that this host belongs to.').format(host.inventory.name)), status=status.HTTP_404_NOT_FOUND)
|
return Response(dict(error=_('The Insights Credential for "{}" was not found.').format(host.inventory.name)), status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
url = settings.INSIGHTS_URL_BASE + '/r/insights/v3/systems/{}/reports/'.format(host.insights_system_id)
|
url = settings.INSIGHTS_URL_BASE + '/r/insights/v3/systems/{}/reports/'.format(host.insights_system_id)
|
||||||
(username, password) = self._extract_insights_creds(cred)
|
(username, password) = self._extract_insights_creds(cred)
|
||||||
|
|||||||
@@ -1,24 +1,38 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from django.utils.timezone import now
|
||||||
|
from django.utils.text import slugify
|
||||||
|
|
||||||
from awx.main.models.base import PERM_INVENTORY_SCAN, PERM_INVENTORY_DEPLOY
|
from awx.main.models.base import PERM_INVENTORY_SCAN, PERM_INVENTORY_DEPLOY
|
||||||
|
from awx.main import utils
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('awx.main.migrations')
|
logger = logging.getLogger('awx.main.migrations')
|
||||||
|
|
||||||
|
|
||||||
def _create_fact_scan_project(Project, org):
|
def _create_fact_scan_project(ContentType, Project, org):
|
||||||
|
ct = ContentType.objects.get_for_model(Project)
|
||||||
name = "Tower Fact Scan - {}".format(org.name if org else "No Organization")
|
name = "Tower Fact Scan - {}".format(org.name if org else "No Organization")
|
||||||
proj = Project(name=name,
|
proj = Project(name=name,
|
||||||
scm_url='https://github.com/ansible/tower-fact-modules',
|
scm_url='https://github.com/ansible/tower-fact-modules',
|
||||||
scm_type='git',
|
scm_type='git',
|
||||||
scm_update_on_launch=True,
|
scm_update_on_launch=True,
|
||||||
scm_update_cache_timeout=86400,
|
scm_update_cache_timeout=86400,
|
||||||
organization=org)
|
organization=org,
|
||||||
|
created=now(),
|
||||||
|
modified=now(),
|
||||||
|
polymorphic_ctype=ct)
|
||||||
|
proj.save()
|
||||||
|
|
||||||
|
slug_name = slugify(unicode(name)).replace(u'-', u'_')
|
||||||
|
proj.local_path = u'_%d__%s' % (int(proj.pk), slug_name)
|
||||||
|
|
||||||
proj.save()
|
proj.save()
|
||||||
return proj
|
return proj
|
||||||
|
|
||||||
|
|
||||||
def _create_fact_scan_projects(Project, orgs):
|
def _create_fact_scan_projects(ContentType, Project, orgs):
|
||||||
return {org.id : _create_fact_scan_project(Project, org) for org in orgs}
|
return {org.id : _create_fact_scan_project(ContentType, Project, org) for org in orgs}
|
||||||
|
|
||||||
|
|
||||||
def _get_tower_scan_job_templates(JobTemplate):
|
def _get_tower_scan_job_templates(JobTemplate):
|
||||||
@@ -31,9 +45,10 @@ def _get_orgs(Organization, job_template_ids):
|
|||||||
|
|
||||||
|
|
||||||
def _migrate_scan_job_templates(apps):
|
def _migrate_scan_job_templates(apps):
|
||||||
Organization = apps.get_model('main', 'Organization')
|
|
||||||
Project = apps.get_model('main', 'Project')
|
|
||||||
JobTemplate = apps.get_model('main', 'JobTemplate')
|
JobTemplate = apps.get_model('main', 'JobTemplate')
|
||||||
|
Organization = apps.get_model('main', 'Organization')
|
||||||
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||||
|
Project = apps.get_model('main', 'Project')
|
||||||
|
|
||||||
project_no_org = None
|
project_no_org = None
|
||||||
|
|
||||||
@@ -50,16 +65,17 @@ def _migrate_scan_job_templates(apps):
|
|||||||
if orgs.count() == 0:
|
if orgs.count() == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
org_proj_map = _create_fact_scan_projects(Project, orgs)
|
org_proj_map = _create_fact_scan_projects(ContentType, Project, orgs)
|
||||||
for jt in jts:
|
for jt in jts:
|
||||||
if jt.inventory and jt.inventory.organization:
|
if jt.inventory and jt.inventory.organization:
|
||||||
jt.project = org_proj_map[jt.inventory.organization.id]
|
jt.project_id = org_proj_map[jt.inventory.organization.id].id
|
||||||
# Job Templates without an Organization; through related Inventory
|
# Job Templates without an Organization; through related Inventory
|
||||||
else:
|
else:
|
||||||
if not project_no_org:
|
if not project_no_org:
|
||||||
project_no_org = _create_fact_scan_project(Project, None)
|
project_no_org = _create_fact_scan_project(ContentType, Project, None)
|
||||||
jt.project = project_no_org
|
jt.project_id = project_no_org.id
|
||||||
jt.job_type = PERM_INVENTORY_DEPLOY
|
jt.job_type = PERM_INVENTORY_DEPLOY
|
||||||
|
jt.playbook = "scan_facts.yml"
|
||||||
jt.use_fact_cache = True
|
jt.use_fact_cache = True
|
||||||
jt.save()
|
jt.save()
|
||||||
|
|
||||||
|
|||||||
@@ -379,10 +379,10 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin):
|
|||||||
from awx.main.tasks import delete_inventory
|
from awx.main.tasks import delete_inventory
|
||||||
if self.pending_deletion is True:
|
if self.pending_deletion is True:
|
||||||
raise RuntimeError("Inventory is already pending deletion.")
|
raise RuntimeError("Inventory is already pending deletion.")
|
||||||
self.websocket_emit_status('pending_deletion')
|
|
||||||
delete_inventory.delay(self.pk)
|
|
||||||
self.pending_deletion = True
|
self.pending_deletion = True
|
||||||
self.save(update_fields=['pending_deletion'])
|
self.save(update_fields=['pending_deletion'])
|
||||||
|
self.websocket_emit_status('pending_deletion')
|
||||||
|
delete_inventory.delay(self.pk)
|
||||||
|
|
||||||
|
|
||||||
class SmartInventoryMembership(BaseModel):
|
class SmartInventoryMembership(BaseModel):
|
||||||
@@ -1249,10 +1249,11 @@ class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
|
|||||||
replace_text = '__replace_%s__' % now()
|
replace_text = '__replace_%s__' % now()
|
||||||
old_name_re = re.compile(r'^inventory_source \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.*?$')
|
old_name_re = re.compile(r'^inventory_source \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.*?$')
|
||||||
if not self.name or old_name_re.match(self.name) or '__replace_' in self.name:
|
if not self.name or old_name_re.match(self.name) or '__replace_' in self.name:
|
||||||
|
group_name = getattr(self, 'v1_group_name', '')
|
||||||
if self.inventory and self.pk:
|
if self.inventory and self.pk:
|
||||||
self.name = '%s (%s)' % (self.inventory.name, self.pk)
|
self.name = '%s (%s - %s)' % (group_name, self.inventory.name, self.pk)
|
||||||
elif self.inventory:
|
elif self.inventory:
|
||||||
self.name = '%s (%s)' % (self.inventory.name, replace_text)
|
self.name = '%s (%s - %s)' % (group_name, self.inventory.name, replace_text)
|
||||||
elif not is_new_instance:
|
elif not is_new_instance:
|
||||||
self.name = 'inventory source (%s)' % self.pk
|
self.name = 'inventory source (%s)' % self.pk
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1670,6 +1670,11 @@ class RunInventoryUpdate(BaseTask):
|
|||||||
cp.set(section, 'group_by_resource_group', 'yes')
|
cp.set(section, 'group_by_resource_group', 'yes')
|
||||||
cp.set(section, 'group_by_location', 'yes')
|
cp.set(section, 'group_by_location', 'yes')
|
||||||
cp.set(section, 'group_by_tag', 'yes')
|
cp.set(section, 'group_by_tag', 'yes')
|
||||||
|
if inventory_update.source_regions:
|
||||||
|
cp.set(
|
||||||
|
section, 'locations',
|
||||||
|
','.join([x.strip() for x in inventory_update.source_regions.split(',')])
|
||||||
|
)
|
||||||
|
|
||||||
# Return INI content.
|
# Return INI content.
|
||||||
if cp.sections():
|
if cp.sections():
|
||||||
@@ -1747,6 +1752,7 @@ class RunInventoryUpdate(BaseTask):
|
|||||||
env['AZURE_SUBSCRIPTION_ID'] = passwords.get('source_subscription', '')
|
env['AZURE_SUBSCRIPTION_ID'] = passwords.get('source_subscription', '')
|
||||||
env['AZURE_AD_USER'] = passwords.get('source_username', '')
|
env['AZURE_AD_USER'] = passwords.get('source_username', '')
|
||||||
env['AZURE_PASSWORD'] = passwords.get('source_password', '')
|
env['AZURE_PASSWORD'] = passwords.get('source_password', '')
|
||||||
|
env['AZURE_INI_PATH'] = cloud_credential
|
||||||
elif inventory_update.source == 'gce':
|
elif inventory_update.source == 'gce':
|
||||||
env['GCE_EMAIL'] = passwords.get('source_username', '')
|
env['GCE_EMAIL'] = passwords.get('source_username', '')
|
||||||
env['GCE_PROJECT'] = passwords.get('source_project', '')
|
env['GCE_PROJECT'] = passwords.get('source_project', '')
|
||||||
|
|||||||
@@ -67,6 +67,29 @@ def test_filter_by_v1_kind_with_vault(get, admin, organization):
|
|||||||
assert response.data['count'] == 2
|
assert response.data['count'] == 2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_insights_credentials_not_in_v1_api_list(get, admin, organization):
|
||||||
|
credential_type = CredentialType.defaults['insights']()
|
||||||
|
credential_type.save()
|
||||||
|
cred = Credential(
|
||||||
|
credential_type=credential_type,
|
||||||
|
name='Best credential ever',
|
||||||
|
organization=organization,
|
||||||
|
inputs={
|
||||||
|
'username': u'joe',
|
||||||
|
'password': u'secret'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cred.save()
|
||||||
|
|
||||||
|
response = get(
|
||||||
|
reverse('api:credential_list', kwargs={'version': 'v1'}),
|
||||||
|
admin
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.data['count'] == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_custom_credentials_not_in_v1_api_list(get, admin, organization):
|
def test_custom_credentials_not_in_v1_api_list(get, admin, organization):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -199,5 +199,5 @@ class TestHostInsights():
|
|||||||
|
|
||||||
resp = view.get(None)
|
resp = view.get(None)
|
||||||
|
|
||||||
assert resp.data['error'] == 'No Insights Credential found for the Inventory, "inventory_name_here", that this host belongs to.'
|
assert resp.data['error'] == 'The Insights Credential for "inventory_name_here" was not found.'
|
||||||
assert resp.status_code == 404
|
assert resp.status_code == 404
|
||||||
|
|||||||
@@ -18,32 +18,45 @@ EXAMPLES = '''
|
|||||||
# Example fact output:
|
# Example fact output:
|
||||||
# host | success >> {
|
# host | success >> {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "services": [
|
# "packages": {
|
||||||
# {
|
# "libbz2-1.0": [
|
||||||
# "source": "apt",
|
# {
|
||||||
# "version": "1.0.6-5",
|
# "version": "1.0.6-5",
|
||||||
# "arch": "amd64",
|
# "source": "apt",
|
||||||
# "name": "libbz2-1.0"
|
# "arch": "amd64",
|
||||||
# },
|
# "name": "libbz2-1.0"
|
||||||
# {
|
# }
|
||||||
# "source": "apt",
|
# ],
|
||||||
# "version": "2.7.1-4ubuntu1",
|
# "patch": [
|
||||||
# "arch": "amd64",
|
# {
|
||||||
# "name": "patch"
|
# "version": "2.7.1-4ubuntu1",
|
||||||
# },
|
# "source": "apt",
|
||||||
# {
|
# "arch": "amd64",
|
||||||
# "source": "apt",
|
# "name": "patch"
|
||||||
# "version": "4.8.2-19ubuntu1",
|
# }
|
||||||
# "arch": "amd64",
|
# ],
|
||||||
# "name": "gcc-4.8-base"
|
# "gcc-4.8-base": [
|
||||||
# }, ... ] } }
|
# {
|
||||||
|
# "version": "4.8.2-19ubuntu1",
|
||||||
|
# "source": "apt",
|
||||||
|
# "arch": "amd64",
|
||||||
|
# "name": "gcc-4.8-base"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "version": "4.9.2-19ubuntu1",
|
||||||
|
# "source": "apt",
|
||||||
|
# "arch": "amd64",
|
||||||
|
# "name": "gcc-4.8-base"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def rpm_package_list():
|
def rpm_package_list():
|
||||||
import rpm
|
import rpm
|
||||||
trans_set = rpm.TransactionSet()
|
trans_set = rpm.TransactionSet()
|
||||||
installed_packages = []
|
installed_packages = {}
|
||||||
for package in trans_set.dbMatch():
|
for package in trans_set.dbMatch():
|
||||||
package_details = dict(name=package[rpm.RPMTAG_NAME],
|
package_details = dict(name=package[rpm.RPMTAG_NAME],
|
||||||
version=package[rpm.RPMTAG_VERSION],
|
version=package[rpm.RPMTAG_VERSION],
|
||||||
@@ -51,7 +64,10 @@ def rpm_package_list():
|
|||||||
epoch=package[rpm.RPMTAG_EPOCH],
|
epoch=package[rpm.RPMTAG_EPOCH],
|
||||||
arch=package[rpm.RPMTAG_ARCH],
|
arch=package[rpm.RPMTAG_ARCH],
|
||||||
source='rpm')
|
source='rpm')
|
||||||
installed_packages.append(package_details)
|
if package_details['name'] not in installed_packages:
|
||||||
|
installed_packages[package_details['name']] = [package_details]
|
||||||
|
else:
|
||||||
|
installed_packages[package_details['name']].append(package_details)
|
||||||
return installed_packages
|
return installed_packages
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +82,10 @@ def deb_package_list():
|
|||||||
version=ac_pkg.version,
|
version=ac_pkg.version,
|
||||||
arch=ac_pkg.architecture,
|
arch=ac_pkg.architecture,
|
||||||
source='apt')
|
source='apt')
|
||||||
installed_packages.append(package_details)
|
if package_details['name'] not in installed_packages:
|
||||||
|
installed_packages[package_details['name']] = [package_details]
|
||||||
|
else:
|
||||||
|
installed_packages[package_details['name']].append(package_details)
|
||||||
return installed_packages
|
return installed_packages
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,27 +20,19 @@ EXAMPLES = '''
|
|||||||
# Example fact output:
|
# Example fact output:
|
||||||
# host | success >> {
|
# host | success >> {
|
||||||
# "ansible_facts": {
|
# "ansible_facts": {
|
||||||
# "services": [
|
# "services": {
|
||||||
# {
|
# "network": {
|
||||||
# "name": "acpid",
|
# "source": "sysv",
|
||||||
# "source": "sysv",
|
# "state": "running",
|
||||||
# "state": "running"
|
# "name": "network"
|
||||||
# },
|
# },
|
||||||
# {
|
# "arp-ethers.service": {
|
||||||
# "name": "apparmor",
|
# "source": "systemd",
|
||||||
# "source": "sysv",
|
# "state": "stopped",
|
||||||
# "state": "stopped"
|
# "name": "arp-ethers.service"
|
||||||
# },
|
# }
|
||||||
# {
|
# }
|
||||||
# "name": "atd",
|
# }
|
||||||
# "source": "sysv",
|
|
||||||
# "state": "running"
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# "name": "cron",
|
|
||||||
# "source": "sysv",
|
|
||||||
# "state": "running"
|
|
||||||
# }, .... ] } }
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +46,7 @@ class BaseService(object):
|
|||||||
class ServiceScanService(BaseService):
|
class ServiceScanService(BaseService):
|
||||||
|
|
||||||
def gather_services(self):
|
def gather_services(self):
|
||||||
services = []
|
services = {}
|
||||||
service_path = self.module.get_bin_path("service")
|
service_path = self.module.get_bin_path("service")
|
||||||
if service_path is None:
|
if service_path is None:
|
||||||
return None
|
return None
|
||||||
@@ -73,7 +65,7 @@ class ServiceScanService(BaseService):
|
|||||||
service_state = "running"
|
service_state = "running"
|
||||||
else:
|
else:
|
||||||
service_state = "stopped"
|
service_state = "stopped"
|
||||||
services.append({"name": service_name, "state": service_state, "source": "sysv"})
|
services[service_name] = {"name": service_name, "state": service_state, "source": "sysv"}
|
||||||
|
|
||||||
# Upstart
|
# Upstart
|
||||||
if initctl_path is not None and chkconfig_path is None:
|
if initctl_path is not None and chkconfig_path is None:
|
||||||
@@ -92,7 +84,7 @@ class ServiceScanService(BaseService):
|
|||||||
else:
|
else:
|
||||||
pid = None # NOQA
|
pid = None # NOQA
|
||||||
payload = {"name": service_name, "state": service_state, "goal": service_goal, "source": "upstart"}
|
payload = {"name": service_name, "state": service_state, "goal": service_goal, "source": "upstart"}
|
||||||
services.append(payload)
|
services[service_name] = payload
|
||||||
|
|
||||||
# RH sysvinit
|
# RH sysvinit
|
||||||
elif chkconfig_path is not None:
|
elif chkconfig_path is not None:
|
||||||
@@ -134,7 +126,7 @@ class ServiceScanService(BaseService):
|
|||||||
else:
|
else:
|
||||||
service_state = 'stopped'
|
service_state = 'stopped'
|
||||||
service_data = {"name": service_name, "state": service_state, "source": "sysv"}
|
service_data = {"name": service_name, "state": service_state, "source": "sysv"}
|
||||||
services.append(service_data)
|
services[service_name] = service_data
|
||||||
return services
|
return services
|
||||||
|
|
||||||
|
|
||||||
@@ -153,7 +145,7 @@ class SystemctlScanService(BaseService):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def gather_services(self):
|
def gather_services(self):
|
||||||
services = []
|
services = {}
|
||||||
if not self.systemd_enabled():
|
if not self.systemd_enabled():
|
||||||
return None
|
return None
|
||||||
systemctl_path = self.module.get_bin_path("systemctl", opt_dirs=["/usr/bin", "/usr/local/bin"])
|
systemctl_path = self.module.get_bin_path("systemctl", opt_dirs=["/usr/bin", "/usr/local/bin"])
|
||||||
@@ -168,22 +160,20 @@ class SystemctlScanService(BaseService):
|
|||||||
state_val = "running"
|
state_val = "running"
|
||||||
else:
|
else:
|
||||||
state_val = "stopped"
|
state_val = "stopped"
|
||||||
services.append({"name": line_data[0],
|
services[line_data[0]] = {"name": line_data[0], "state": state_val, "source": "systemd"}
|
||||||
"state": state_val,
|
|
||||||
"source": "systemd"})
|
|
||||||
return services
|
return services
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(argument_spec = dict())
|
module = AnsibleModule(argument_spec = dict())
|
||||||
service_modules = (ServiceScanService, SystemctlScanService)
|
service_modules = (ServiceScanService, SystemctlScanService)
|
||||||
all_services = []
|
all_services = {}
|
||||||
incomplete_warning = False
|
incomplete_warning = False
|
||||||
for svc_module in service_modules:
|
for svc_module in service_modules:
|
||||||
svcmod = svc_module(module)
|
svcmod = svc_module(module)
|
||||||
svc = svcmod.gather_services()
|
svc = svcmod.gather_services()
|
||||||
if svc is not None:
|
if svc is not None:
|
||||||
all_services += svc
|
all_services.update(svc)
|
||||||
if svcmod.incomplete_warning:
|
if svcmod.incomplete_warning:
|
||||||
incomplete_warning = True
|
incomplete_warning = True
|
||||||
if len(all_services) == 0:
|
if len(all_services) == 0:
|
||||||
|
|||||||
@@ -777,30 +777,31 @@ GCE_INSTANCE_ID_VAR = None
|
|||||||
# It's not possible to get zones in Azure without authenticating, so we
|
# It's not possible to get zones in Azure without authenticating, so we
|
||||||
# provide a list here.
|
# provide a list here.
|
||||||
AZURE_REGION_CHOICES = [
|
AZURE_REGION_CHOICES = [
|
||||||
('Central_US', _('US Central')),
|
('eastus', _('US East')),
|
||||||
('East_US_1', _('US East')),
|
('eastus2', _('US East 2')),
|
||||||
('East_US_2', _('US East 2')),
|
('centralus', _('US Central')),
|
||||||
('North_Central_US', _('US North Central')),
|
('northcentralus', _('US North Central')),
|
||||||
('South_Central_US', _('US South Central')),
|
('southcentralus', _('US South Central')),
|
||||||
('West_Central_US', _('US West Central')),
|
('westcentralus', _('US West Central')),
|
||||||
('West_US', _('US West')),
|
('westus', _('US West')),
|
||||||
('East_Canada', _('Canada East')),
|
('westus2', _('US West 2')),
|
||||||
('Central_Canada', _('Canada Central')),
|
('canadaeast', _('Canada East')),
|
||||||
('South_Brazil', _('Brazil South')),
|
('canadacentral', _('Canada Central')),
|
||||||
('North_Europe', _('Europe North')),
|
('brazilsouth', _('Brazil South')),
|
||||||
('West_Europe', _('Europe West')),
|
('northeurope', _('Europe North')),
|
||||||
('West_UK', _('UK West')),
|
('westeurope', _('Europe West')),
|
||||||
('South_UK', _('UK South')),
|
('ukwest', _('UK West')),
|
||||||
('East_Asia', _('Asia East')),
|
('uksouth', _('UK South')),
|
||||||
('Southest_Asia', _('Asia Southeast')),
|
('eastasia', _('Asia East')),
|
||||||
('East_Australia', _('Australia East')),
|
('southestasia', _('Asia Southeast')),
|
||||||
('Southest_Australia', _('Australia Southeast')),
|
('australiaeast', _('Australia East')),
|
||||||
('West_India', _('India West')),
|
('australiasoutheast', _('Australia Southeast')),
|
||||||
('South_India', _('India South')),
|
('westindia', _('India West')),
|
||||||
('East_Japan', _('Japan East')),
|
('southindia', _('India South')),
|
||||||
('West_Japan', _('Japan West')),
|
('japaneast', _('Japan East')),
|
||||||
('Central_Korea', _('Korea Central')),
|
('japanwest', _('Japan West')),
|
||||||
('South_Korea', _('Korea South')),
|
('koreacentral', _('Korea Central')),
|
||||||
|
('koreasouth', _('Korea South')),
|
||||||
]
|
]
|
||||||
AZURE_REGIONS_BLACKLIST = []
|
AZURE_REGIONS_BLACKLIST = []
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export default [
|
|||||||
var formTracker = $scope.$parent.vm.formTracker;
|
var formTracker = $scope.$parent.vm.formTracker;
|
||||||
var dropdownValue = 'azure';
|
var dropdownValue = 'azure';
|
||||||
var activeAuthForm = 'azure';
|
var activeAuthForm = 'azure';
|
||||||
|
let codeInputInitialized = false;
|
||||||
|
|
||||||
// Default active form
|
// Default active form
|
||||||
if ($stateParams.currentTab === '' || $stateParams.currentTab === 'auth') {
|
if ($stateParams.currentTab === '' || $stateParams.currentTab === 'auth') {
|
||||||
@@ -244,8 +245,6 @@ export default [
|
|||||||
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
||||||
var dropdownRendered = false;
|
var dropdownRendered = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function populateLDAPGroupType(flag){
|
function populateLDAPGroupType(flag){
|
||||||
if($scope.$parent.AUTH_LDAP_GROUP_TYPE !== null) {
|
if($scope.$parent.AUTH_LDAP_GROUP_TYPE !== null) {
|
||||||
$scope.$parent.AUTH_LDAP_GROUP_TYPE = _.find($scope.$parent.AUTH_LDAP_GROUP_TYPE_options, { value: $scope.$parent.AUTH_LDAP_GROUP_TYPE });
|
$scope.$parent.AUTH_LDAP_GROUP_TYPE = _.find($scope.$parent.AUTH_LDAP_GROUP_TYPE_options, { value: $scope.$parent.AUTH_LDAP_GROUP_TYPE });
|
||||||
@@ -292,12 +291,24 @@ export default [
|
|||||||
populateTacacsProtocol(flag);
|
populateTacacsProtocol(flag);
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on('codeMirror_populated', function(e, key) {
|
$scope.$on('$locationChangeStart', (event, url) => {
|
||||||
startCodeMirrors(key);
|
let parts = url.split('/');
|
||||||
|
let tab = parts[parts.length - 1];
|
||||||
|
|
||||||
|
if (tab === 'auth' && !codeInputInitialized) {
|
||||||
|
startCodeMirrors();
|
||||||
|
codeInputInitialized = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on('populated', function() {
|
$scope.$on('populated', function() {
|
||||||
startCodeMirrors();
|
let tab = $stateParams.currentTab;
|
||||||
|
|
||||||
|
if (tab === 'auth') {
|
||||||
|
startCodeMirrors();
|
||||||
|
codeInputInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
populateLDAPGroupType(false);
|
populateLDAPGroupType(false);
|
||||||
populateTacacsProtocol(false);
|
populateTacacsProtocol(false);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,28 +8,35 @@ export default [
|
|||||||
'$scope',
|
'$scope',
|
||||||
'$rootScope',
|
'$rootScope',
|
||||||
'$state',
|
'$state',
|
||||||
|
'$stateParams',
|
||||||
'$timeout',
|
'$timeout',
|
||||||
'ConfigurationJobsForm',
|
'ConfigurationJobsForm',
|
||||||
'ConfigurationService',
|
'ConfigurationService',
|
||||||
'ConfigurationUtils',
|
'ConfigurationUtils',
|
||||||
'CreateSelect2',
|
'CreateSelect2',
|
||||||
'GenerateForm',
|
'GenerateForm',
|
||||||
|
'ParseTypeChange',
|
||||||
'i18n',
|
'i18n',
|
||||||
function(
|
function(
|
||||||
$scope,
|
$scope,
|
||||||
$rootScope,
|
$rootScope,
|
||||||
$state,
|
$state,
|
||||||
|
$stateParams,
|
||||||
$timeout,
|
$timeout,
|
||||||
ConfigurationJobsForm,
|
ConfigurationJobsForm,
|
||||||
ConfigurationService,
|
ConfigurationService,
|
||||||
ConfigurationUtils,
|
ConfigurationUtils,
|
||||||
CreateSelect2,
|
CreateSelect2,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
|
ParseTypeChange,
|
||||||
i18n
|
i18n
|
||||||
) {
|
) {
|
||||||
var jobsVm = this;
|
|
||||||
var generator = GenerateForm;
|
var generator = GenerateForm;
|
||||||
var form = ConfigurationJobsForm;
|
var form = ConfigurationJobsForm;
|
||||||
|
|
||||||
|
let tab;
|
||||||
|
let codeInputInitialized = false;
|
||||||
|
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options = [];
|
$scope.$parent.AD_HOC_COMMANDS_options = [];
|
||||||
_.each($scope.$parent.configDataResolve.AD_HOC_COMMANDS.default, function(command) {
|
_.each($scope.$parent.configDataResolve.AD_HOC_COMMANDS.default, function(command) {
|
||||||
$scope.$parent.AD_HOC_COMMANDS_options.push({
|
$scope.$parent.AD_HOC_COMMANDS_options.push({
|
||||||
@@ -75,6 +82,18 @@ export default [
|
|||||||
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
// Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching
|
||||||
var dropdownRendered = false;
|
var dropdownRendered = false;
|
||||||
|
|
||||||
|
function initializeCodeInput () {
|
||||||
|
let name = 'AWX_TASK_ENV';
|
||||||
|
|
||||||
|
ParseTypeChange({
|
||||||
|
scope: $scope.$parent,
|
||||||
|
variable: name,
|
||||||
|
parseType: 'application/json',
|
||||||
|
field_id: `configuration_jobs_template_${name}`
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.parseTypeChange('parseType', name);
|
||||||
|
}
|
||||||
|
|
||||||
function populateAdhocCommand(flag){
|
function populateAdhocCommand(flag){
|
||||||
$scope.$parent.AD_HOC_COMMANDS = $scope.$parent.AD_HOC_COMMANDS.toString();
|
$scope.$parent.AD_HOC_COMMANDS = $scope.$parent.AD_HOC_COMMANDS.toString();
|
||||||
@@ -107,22 +126,55 @@ export default [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$on('AD_HOC_COMMANDS_populated', function(e, data, flag) {
|
|
||||||
populateAdhocCommand(flag);
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.$on('populated', function() {
|
|
||||||
populateAdhocCommand(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fix for bug where adding selected opts causes form to be $dirty and triggering modal
|
// Fix for bug where adding selected opts causes form to be $dirty and triggering modal
|
||||||
// TODO Find better solution for this bug
|
// TODO Find better solution for this bug
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.$parent.configuration_jobs_template_form.$setPristine();
|
$scope.$parent.configuration_jobs_template_form.$setPristine();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
angular.extend(jobsVm, {
|
$scope.$on('AD_HOC_COMMANDS_populated', function(e, data, flag) {
|
||||||
|
populateAdhocCommand(flag);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controllers for each tab are initialized when configuration is opened. A listener
|
||||||
|
* on the URL itself is necessary to determine which tab is active. If a non-active
|
||||||
|
* tab initializes a codemirror, it doesn't display properly until the user navigates
|
||||||
|
* to the tab and it's been clicked.
|
||||||
|
*/
|
||||||
|
$scope.$on('$locationChangeStart', (event, url) => {
|
||||||
|
let parts = url.split('/');
|
||||||
|
tab = parts[parts.length - 1];
|
||||||
|
|
||||||
|
if (tab === 'jobs' && !codeInputInitialized) {
|
||||||
|
initializeCodeInput();
|
||||||
|
codeInputInitialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Necessary to listen for revert clicks and relaunch the codemirror instance.
|
||||||
|
*/
|
||||||
|
$scope.$on('codeMirror_populated', () => {
|
||||||
|
if (tab === 'jobs') {
|
||||||
|
initializeCodeInput();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This event is fired if the user navigates directly to this tab, where the
|
||||||
|
* $locationChangeStart does not. Watching this and location ensure proper display on
|
||||||
|
* direct load of this tab or if the user comes from a different tab.
|
||||||
|
*/
|
||||||
|
$scope.$on('populated', () => {
|
||||||
|
tab = $stateParams.currentTab;
|
||||||
|
|
||||||
|
if (tab === 'jobs') {
|
||||||
|
initializeCodeInput();
|
||||||
|
codeInputInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
populateAdhocCommand(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -4,76 +4,82 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['i18n', function(i18n) {
|
export default ['i18n', function(i18n) {
|
||||||
return {
|
return {
|
||||||
showHeader: false,
|
showHeader: false,
|
||||||
name: 'configuration_jobs_template',
|
name: 'configuration_jobs_template',
|
||||||
showActions: true,
|
showActions: true,
|
||||||
|
fields: {
|
||||||
|
AD_HOC_COMMANDS: {
|
||||||
|
type: 'select',
|
||||||
|
ngOptions: 'command.label for command in AD_HOC_COMMANDS_options track by command.value',
|
||||||
|
reset: 'AD_HOC_COMMANDS',
|
||||||
|
multiSelect: true
|
||||||
|
},
|
||||||
|
AWX_PROOT_BASE_PATH: {
|
||||||
|
type: 'text',
|
||||||
|
reset: 'AWX_PROOT_BASE_PATH',
|
||||||
|
},
|
||||||
|
SCHEDULE_MAX_JOBS: {
|
||||||
|
type: 'number',
|
||||||
|
reset: 'SCHEDULE_MAX_JOBS'
|
||||||
|
},
|
||||||
|
AWX_PROOT_SHOW_PATHS: {
|
||||||
|
type: 'textarea',
|
||||||
|
reset: 'AWX_PROOT_SHOW_PATHS',
|
||||||
|
rows: 6
|
||||||
|
},
|
||||||
|
AWX_ANSIBLE_CALLBACK_PLUGINS: {
|
||||||
|
type: 'textarea',
|
||||||
|
reset: 'AWX_ANSIBLE_CALLBACK_PLUGINS',
|
||||||
|
rows: 6
|
||||||
|
},
|
||||||
|
AWX_PROOT_HIDE_PATHS: {
|
||||||
|
type: 'textarea',
|
||||||
|
reset: 'AWX_PROOT_HIDE_PATHS',
|
||||||
|
rows: 6
|
||||||
|
},
|
||||||
|
AWX_PROOT_ENABLED: {
|
||||||
|
type: 'toggleSwitch',
|
||||||
|
},
|
||||||
|
DEFAULT_JOB_TIMEOUT: {
|
||||||
|
type: 'text',
|
||||||
|
reset: 'DEFAULT_JOB_TIMEOUT',
|
||||||
|
},
|
||||||
|
DEFAULT_INVENTORY_UPDATE_TIMEOUT: {
|
||||||
|
type: 'text',
|
||||||
|
reset: 'DEFAULT_INVENTORY_UPDATE_TIMEOUT',
|
||||||
|
},
|
||||||
|
DEFAULT_PROJECT_UPDATE_TIMEOUT: {
|
||||||
|
type: 'text',
|
||||||
|
reset: 'DEFAULT_PROJECT_UPDATE_TIMEOUT',
|
||||||
|
},
|
||||||
|
ANSIBLE_FACT_CACHE_TIMEOUT: {
|
||||||
|
type: 'text',
|
||||||
|
reset: 'ANSIBLE_FACT_CACHE_TIMEOUT',
|
||||||
|
},
|
||||||
|
AWX_TASK_ENV: {
|
||||||
|
type: 'textarea',
|
||||||
|
reset: 'AWX_TASK_ENV',
|
||||||
|
rows: 6,
|
||||||
|
codeMirror: true,
|
||||||
|
class: 'Form-textAreaLabel Form-formGroup--fullWidth'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
reset: {
|
||||||
|
ngClick: 'vm.resetAllConfirm()',
|
||||||
|
label: i18n._('Revert all to default'),
|
||||||
|
class: 'Form-resetAll'
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
ngClick: 'vm.formCancel()',
|
||||||
|
},
|
||||||
|
save: {
|
||||||
|
ngClick: 'vm.formSave()',
|
||||||
|
ngDisabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
|
||||||
fields: {
|
|
||||||
AD_HOC_COMMANDS: {
|
|
||||||
type: 'select',
|
|
||||||
ngOptions: 'command.label for command in AD_HOC_COMMANDS_options track by command.value',
|
|
||||||
reset: 'AD_HOC_COMMANDS',
|
|
||||||
multiSelect: true
|
|
||||||
},
|
|
||||||
AWX_PROOT_BASE_PATH: {
|
|
||||||
type: 'text',
|
|
||||||
reset: 'AWX_PROOT_BASE_PATH',
|
|
||||||
},
|
|
||||||
SCHEDULE_MAX_JOBS: {
|
|
||||||
type: 'number',
|
|
||||||
reset: 'SCHEDULE_MAX_JOBS'
|
|
||||||
},
|
|
||||||
AWX_PROOT_SHOW_PATHS: {
|
|
||||||
type: 'textarea',
|
|
||||||
reset: 'AWX_PROOT_SHOW_PATHS',
|
|
||||||
rows: 6
|
|
||||||
},
|
|
||||||
AWX_ANSIBLE_CALLBACK_PLUGINS: {
|
|
||||||
type: 'textarea',
|
|
||||||
reset: 'AWX_ANSIBLE_CALLBACK_PLUGINS',
|
|
||||||
rows: 6
|
|
||||||
},
|
|
||||||
AWX_PROOT_HIDE_PATHS: {
|
|
||||||
type: 'textarea',
|
|
||||||
reset: 'AWX_PROOT_HIDE_PATHS',
|
|
||||||
rows: 6
|
|
||||||
},
|
|
||||||
AWX_PROOT_ENABLED: {
|
|
||||||
type: 'toggleSwitch',
|
|
||||||
},
|
|
||||||
DEFAULT_JOB_TIMEOUT: {
|
|
||||||
type: 'text',
|
|
||||||
reset: 'DEFAULT_JOB_TIMEOUT',
|
|
||||||
},
|
|
||||||
DEFAULT_INVENTORY_UPDATE_TIMEOUT: {
|
|
||||||
type: 'text',
|
|
||||||
reset: 'DEFAULT_INVENTORY_UPDATE_TIMEOUT',
|
|
||||||
},
|
|
||||||
DEFAULT_PROJECT_UPDATE_TIMEOUT: {
|
|
||||||
type: 'text',
|
|
||||||
reset: 'DEFAULT_PROJECT_UPDATE_TIMEOUT',
|
|
||||||
},
|
|
||||||
ANSIBLE_FACT_CACHE_TIMEOUT: {
|
|
||||||
type: 'text',
|
|
||||||
reset: 'ANSIBLE_FACT_CACHE_TIMEOUT',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
buttons: {
|
|
||||||
reset: {
|
|
||||||
ngClick: 'vm.resetAllConfirm()',
|
|
||||||
label: i18n._('Revert all to default'),
|
|
||||||
class: 'Form-resetAll'
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
ngClick: 'vm.formCancel()',
|
|
||||||
},
|
|
||||||
save: {
|
|
||||||
ngClick: 'vm.formSave()',
|
|
||||||
ngDisabled: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ export default ['$state', '$stateParams', '$scope', 'SourcesFormDefinition',
|
|||||||
init();
|
init();
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
$scope.mode = 'add';
|
||||||
// apply form definition's default field values
|
// apply form definition's default field values
|
||||||
GenerateForm.applyDefaults(form, $scope);
|
GenerateForm.applyDefaults(form, $scope, true);
|
||||||
$scope.canAdd = inventorySourcesOptions.actions.POST;
|
$scope.canAdd = inventorySourcesOptions.actions.POST;
|
||||||
$scope.envParseType = 'yaml';
|
$scope.envParseType = 'yaml';
|
||||||
initSources();
|
initSources();
|
||||||
@@ -46,36 +47,6 @@ export default ['$state', '$stateParams', '$scope', 'SourcesFormDefinition',
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Detect and alert user to potential SCM status issues
|
|
||||||
var checkSCMStatus = function () {
|
|
||||||
if (!Empty($scope.project)) {
|
|
||||||
Rest.setUrl(GetBasePath('projects') + $scope.project + '/');
|
|
||||||
Rest.get()
|
|
||||||
.success(function (data) {
|
|
||||||
var msg;
|
|
||||||
switch (data.status) {
|
|
||||||
case 'failed':
|
|
||||||
msg = "<div>The Project selected has a status of \"failed\". You must run a successful update before you can select an inventory file.";
|
|
||||||
break;
|
|
||||||
case 'never updated':
|
|
||||||
msg = "<div>The Project selected has a status of \"never updated\". You must run a successful update before you can select an inventory file.";
|
|
||||||
break;
|
|
||||||
case 'missing':
|
|
||||||
msg = '<div>The selected project has a status of \"missing\". Please check the server and make sure ' +
|
|
||||||
' the directory exists and file permissions are set correctly.</div>';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (msg) {
|
|
||||||
Alert('Warning', msg, 'alert-info alert-info--noTextTransform', null, null, null, null, true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.error(function (data, status) {
|
|
||||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
|
||||||
msg: 'Failed to get project ' + $scope.project + '. GET returned status: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register a watcher on project_name
|
// Register a watcher on project_name
|
||||||
if ($scope.getInventoryFilesUnregister) {
|
if ($scope.getInventoryFilesUnregister) {
|
||||||
$scope.getInventoryFilesUnregister();
|
$scope.getInventoryFilesUnregister();
|
||||||
@@ -83,7 +54,6 @@ export default ['$state', '$stateParams', '$scope', 'SourcesFormDefinition',
|
|||||||
$scope.getInventoryFilesUnregister = $scope.$watch('project', function (newValue, oldValue) {
|
$scope.getInventoryFilesUnregister = $scope.$watch('project', function (newValue, oldValue) {
|
||||||
if (newValue !== oldValue) {
|
if (newValue !== oldValue) {
|
||||||
getInventoryFiles(newValue);
|
getInventoryFiles(newValue);
|
||||||
checkSCMStatus();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -118,7 +88,6 @@ export default ['$state', '$stateParams', '$scope', 'SourcesFormDefinition',
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.projectBasePath = GetBasePath('projects');
|
|
||||||
$scope.credentialBasePath = GetBasePath('credentials') + '?credential_type__kind__in=cloud,network';
|
$scope.credentialBasePath = GetBasePath('credentials') + '?credential_type__kind__in=cloud,network';
|
||||||
|
|
||||||
$scope.sourceChange = function(source) {
|
$scope.sourceChange = function(source) {
|
||||||
@@ -144,10 +113,11 @@ export default ['$state', '$stateParams', '$scope', 'SourcesFormDefinition',
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source === 'scm') {
|
if (source === 'scm') {
|
||||||
$scope.overwrite_vars = true;
|
$scope.projectBasePath = GetBasePath('projects') + '?not__status=never updated';
|
||||||
$scope.inventory_source_form.inventory_file.$setPristine();
|
$scope.overwrite_vars = true;
|
||||||
|
$scope.inventory_source_form.inventory_file.$setPristine();
|
||||||
} else {
|
} else {
|
||||||
$scope.overwrite_vars = false;
|
$scope.overwrite_vars = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset fields
|
// reset fields
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ export default ['$state', '$stateParams', '$scope', 'ParseVariableString',
|
|||||||
'rbacUiControlService', 'ToJSON', 'ParseTypeChange', 'GroupsService',
|
'rbacUiControlService', 'ToJSON', 'ParseTypeChange', 'GroupsService',
|
||||||
'GetChoices', 'GetBasePath', 'CreateSelect2', 'GetSourceTypeOptions',
|
'GetChoices', 'GetBasePath', 'CreateSelect2', 'GetSourceTypeOptions',
|
||||||
'inventorySourceData', 'SourcesService', 'inventoryData', 'inventorySourcesOptions', 'Empty',
|
'inventorySourceData', 'SourcesService', 'inventoryData', 'inventorySourcesOptions', 'Empty',
|
||||||
'Wait', 'Rest', 'Alert', 'ProcessErrors',
|
'Wait', 'Rest', 'Alert',
|
||||||
function($state, $stateParams, $scope, ParseVariableString,
|
function($state, $stateParams, $scope, ParseVariableString,
|
||||||
rbacUiControlService, ToJSON,ParseTypeChange, GroupsService,
|
rbacUiControlService, ToJSON,ParseTypeChange, GroupsService,
|
||||||
GetChoices, GetBasePath, CreateSelect2, GetSourceTypeOptions,
|
GetChoices, GetBasePath, CreateSelect2, GetSourceTypeOptions,
|
||||||
inventorySourceData, SourcesService, inventoryData, inventorySourcesOptions, Empty,
|
inventorySourceData, SourcesService, inventoryData, inventorySourcesOptions, Empty,
|
||||||
Wait, Rest, Alert, ProcessErrors) {
|
Wait, Rest, Alert) {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$scope.projectBasePath = GetBasePath('projects');
|
$scope.projectBasePath = GetBasePath('projects') + '?not__status=never updated';
|
||||||
$scope.canAdd = inventorySourcesOptions.actions.POST;
|
$scope.canAdd = inventorySourcesOptions.actions.POST;
|
||||||
// instantiate expected $scope values from inventorySourceData
|
// instantiate expected $scope values from inventorySourceData
|
||||||
_.assign($scope,
|
_.assign($scope,
|
||||||
@@ -136,33 +136,6 @@ export default ['$state', '$stateParams', '$scope', 'ParseVariableString',
|
|||||||
Wait('stop');
|
Wait('stop');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Empty($scope.project)) {
|
|
||||||
Rest.setUrl(GetBasePath('projects') + $scope.project + '/');
|
|
||||||
Rest.get()
|
|
||||||
.success(function (data) {
|
|
||||||
var msg;
|
|
||||||
switch (data.status) {
|
|
||||||
case 'failed':
|
|
||||||
msg = "<div>The Project selected has a status of \"failed\". You must run a successful update before you can select an inventory file.";
|
|
||||||
break;
|
|
||||||
case 'never updated':
|
|
||||||
msg = "<div>The Project selected has a status of \"never updated\". You must run a successful update before you can select an inventory file.";
|
|
||||||
break;
|
|
||||||
case 'missing':
|
|
||||||
msg = '<div>The selected project has a status of \"missing\". Please check the server and make sure ' +
|
|
||||||
' the directory exists and file permissions are set correctly.</div>';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (msg) {
|
|
||||||
Alert('Warning', msg, 'alert-info alert-info--noTextTransform', null, null, null, null, true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.error(function (data, status) {
|
|
||||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
|
||||||
msg: 'Failed to get project ' + $scope.project + '. GET returned status: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSourceSelect() {
|
function initSourceSelect() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export default {
|
|||||||
value: {
|
value: {
|
||||||
page_size:"5",
|
page_size:"5",
|
||||||
order_by:"name",
|
order_by:"name",
|
||||||
|
not__status:"never updated",
|
||||||
role_level:"use_role",
|
role_level:"use_role",
|
||||||
},
|
},
|
||||||
dynamic:true,
|
dynamic:true,
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
$scope.machine_credential_link = getTowerLink('credential');
|
$scope.machine_credential_link = getTowerLink('credential');
|
||||||
$scope.cloud_credential_link = getTowerLink('cloud_credential');
|
$scope.cloud_credential_link = getTowerLink('cloud_credential');
|
||||||
$scope.network_credential_link = getTowerLink('network_credential');
|
$scope.network_credential_link = getTowerLink('network_credential');
|
||||||
|
$scope.vault_credential_link = getTowerLink('vault_credential');
|
||||||
$scope.schedule_link = getTowerLink('schedule');
|
$scope.schedule_link = getTowerLink('schedule');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- VAULT CREDENTAIL DETAIL -->
|
||||||
|
<div class="JobResults-resultRow"
|
||||||
|
ng-show="job.summary_fields.vault_credential.name">
|
||||||
|
<label class="JobResults-resultRowLabel">
|
||||||
|
Vault Credential
|
||||||
|
</label>
|
||||||
|
<div class="JobResults-resultRowText">
|
||||||
|
<a href="{{ vault_credential_link }}"
|
||||||
|
aw-tool-tip="Edit the credential"
|
||||||
|
data-placement="top">
|
||||||
|
{{ job.summary_fields.vault_credential.name }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- FORKS DETAIL -->
|
<!-- FORKS DETAIL -->
|
||||||
<div class="JobResults-resultRow"
|
<div class="JobResults-resultRow"
|
||||||
ng-show="job.forks !== undefined">
|
ng-show="job.forks !== undefined">
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ export default
|
|||||||
$scope.password_needed = data.passwords_needed_to_start && data.passwords_needed_to_start.length > 0;
|
$scope.password_needed = data.passwords_needed_to_start && data.passwords_needed_to_start.length > 0;
|
||||||
$scope.has_default_inventory = data.defaults && data.defaults.inventory && data.defaults.inventory.id;
|
$scope.has_default_inventory = data.defaults && data.defaults.inventory && data.defaults.inventory.id;
|
||||||
$scope.has_default_credential = data.defaults && data.defaults.credential && data.defaults.credential.id;
|
$scope.has_default_credential = data.defaults && data.defaults.credential && data.defaults.credential.id;
|
||||||
|
$scope.has_default_vault_credential = data.defaults && data.defaults.vault_credential && data.defaults.vault_credential.id;
|
||||||
$scope.has_default_extra_credentials = data.defaults && data.defaults.extra_credentials && data.defaults.extra_credentials.length > 0;
|
$scope.has_default_extra_credentials = data.defaults && data.defaults.extra_credentials && data.defaults.extra_credentials.length > 0;
|
||||||
|
|
||||||
$scope.other_prompt_data = {};
|
$scope.other_prompt_data = {};
|
||||||
@@ -231,6 +232,10 @@ export default
|
|||||||
$scope.selected_credentials.machine = angular.copy($scope.defaults.credential);
|
$scope.selected_credentials.machine = angular.copy($scope.defaults.credential);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($scope.has_default_vault_credential) {
|
||||||
|
$scope.selected_credentials.vault = angular.copy($scope.defaults.vault_credential);
|
||||||
|
}
|
||||||
|
|
||||||
if($scope.has_default_extra_credentials) {
|
if($scope.has_default_extra_credentials) {
|
||||||
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
||||||
}
|
}
|
||||||
@@ -361,6 +366,12 @@ export default
|
|||||||
else {
|
else {
|
||||||
$scope.selected_credentials.machine = null;
|
$scope.selected_credentials.machine = null;
|
||||||
}
|
}
|
||||||
|
if($scope.has_default_vault_credential) {
|
||||||
|
$scope.selected_credentials.vault = angular.copy($scope.defaults.vault_credential);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.selected_credentials.vault = null;
|
||||||
|
}
|
||||||
if($scope.has_default_extra_credentials) {
|
if($scope.has_default_extra_credentials) {
|
||||||
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,12 @@
|
|||||||
<span><span class="JobSubmission-previewTagLabel">{{credential_types[extraCredential.credential_type].name | uppercase}}</span>: {{extraCredential.name}}</span>
|
<span><span class="JobSubmission-previewTagLabel">{{credential_types[extraCredential.credential_type].name | uppercase}}</span>: {{extraCredential.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="JobSubmission-previewTagContainer JobSubmission-previewTagContainer--vault" ng-show="selected_credentials.vault">
|
||||||
|
<div class="JobSubmission-previewTag JobSubmission-previewTag--vault" ng-class="{'JobSubmission-previewTag--deletable': ask_credential_on_launch}">
|
||||||
|
<span>
|
||||||
|
<span class="JobSubmission-previewTagLabel">VAULT</span>: {{selected_credentials.vault.name}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="JobSubmission-previewTagRevert" ng-if="ask_credential_on_launch">
|
<div class="JobSubmission-previewTagRevert" ng-if="ask_credential_on_launch">
|
||||||
@@ -167,7 +173,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_verbosity_on_launch">
|
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_verbosity_on_launch">
|
||||||
<label for="verbosity" class="prepend-asterisk Form-inputLabelContainer">
|
<label for="verbosity" class="prepend-asterisk Form-inputLabelContainer">
|
||||||
<span class="Form-inputLabel"> Verbosity</span>
|
<span class="Form-inputLabel" translate> Verbosity</span>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
@@ -333,6 +339,10 @@
|
|||||||
<span class="JobSubmission-previewItemSubTitle">{{credential_types[extraCredential.credential_type].name}}: </span>
|
<span class="JobSubmission-previewItemSubTitle">{{credential_types[extraCredential.credential_type].name}}: </span>
|
||||||
<span>{{extraCredential.name}}</span>
|
<span>{{extraCredential.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span ng-show="selected_credentials.vault" class="JobSubmission-previewItemSubTitle"><span translate>Vault</span>: </span>
|
||||||
|
<span ng-show="selected_credentials.vault">{{selected_credentials.vault.name}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="JobSubmission-footerButtons">
|
<div class="JobSubmission-footerButtons">
|
||||||
|
|||||||
@@ -564,10 +564,6 @@ function(ConfigurationUtils, i18n, $rootScope) {
|
|||||||
_doAutoPopulate();
|
_doAutoPopulate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (attrs.watchbasepath === 'projectBasePath') {
|
|
||||||
_doAutoPopulate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _doAutoPopulate() {
|
function _doAutoPopulate() {
|
||||||
|
|||||||
@@ -375,11 +375,13 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
|||||||
return this.build(options);
|
return this.build(options);
|
||||||
},
|
},
|
||||||
|
|
||||||
applyDefaults: function (form, scope) {
|
applyDefaults: function (form, scope, ignoreMode) {
|
||||||
// Note: This is a hack. Ideally, mode should be set in each <resource>-<mode>.controller.js
|
if(!ignoreMode) {
|
||||||
// The mode is needed by the awlookup directive to auto-populate form fields when there is a
|
// Note: This is a hack. Ideally, mode should be set in each <resource>-<mode>.controller.js
|
||||||
// single related resource.
|
// The mode is needed by the awlookup directive to auto-populate form fields when there is a
|
||||||
scope.mode = this.mode;
|
// single related resource.
|
||||||
|
scope.mode = this.mode;
|
||||||
|
}
|
||||||
|
|
||||||
for (var fld in form.fields) {
|
for (var fld in form.fields) {
|
||||||
if (form.fields[fld]['default'] || form.fields[fld]['default'] === 0) {
|
if (form.fields[fld]['default'] || form.fields[fld]['default'] === 0) {
|
||||||
|
|||||||
@@ -281,6 +281,14 @@
|
|||||||
} else {
|
} else {
|
||||||
data.credential = null;
|
data.credential = null;
|
||||||
}
|
}
|
||||||
|
if ($scope.selectedCredentials && $scope.selectedCredentials
|
||||||
|
.vault && $scope.selectedCredentials
|
||||||
|
.vault.id) {
|
||||||
|
data.vault_credential = $scope.selectedCredentials
|
||||||
|
.vault.id;
|
||||||
|
} else {
|
||||||
|
data.vault_credential = null;
|
||||||
|
}
|
||||||
|
|
||||||
data.extra_vars = ToJSON($scope.parseType,
|
data.extra_vars = ToJSON($scope.parseType,
|
||||||
$scope.variables, true);
|
$scope.variables, true);
|
||||||
|
|||||||
@@ -487,13 +487,20 @@ export default
|
|||||||
data.skip_tags = (Array.isArray($scope.skip_tags)) ? $scope.skip_tags.join() : "";
|
data.skip_tags = (Array.isArray($scope.skip_tags)) ? $scope.skip_tags.join() : "";
|
||||||
if ($scope.selectedCredentials && $scope.selectedCredentials
|
if ($scope.selectedCredentials && $scope.selectedCredentials
|
||||||
.machine && $scope.selectedCredentials
|
.machine && $scope.selectedCredentials
|
||||||
.machine) {
|
.machine.id) {
|
||||||
data.credential = $scope.selectedCredentials
|
data.credential = $scope.selectedCredentials
|
||||||
.machine.id;
|
.machine.id;
|
||||||
} else {
|
} else {
|
||||||
data.credential = null;
|
data.credential = null;
|
||||||
}
|
}
|
||||||
|
if ($scope.selectedCredentials && $scope.selectedCredentials
|
||||||
|
.vault && $scope.selectedCredentials
|
||||||
|
.vault.id) {
|
||||||
|
data.vault_credential = $scope.selectedCredentials
|
||||||
|
.vault.id;
|
||||||
|
} else {
|
||||||
|
data.vault_credential = null;
|
||||||
|
}
|
||||||
data.extra_vars = ToJSON($scope.parseType,
|
data.extra_vars = ToJSON($scope.parseType,
|
||||||
$scope.variables, true);
|
$scope.variables, true);
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,21 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
|
|||||||
$scope.credentialTypeOptions);
|
$scope.credentialTypeOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let updateVaultCredentialList = function() {
|
||||||
|
$scope.credentials.forEach(cred => {
|
||||||
|
if (cred.credential_type === 3) {
|
||||||
|
cred.checked = ($scope.selectedCredentials
|
||||||
|
.vault !== null &&
|
||||||
|
cred.id === $scope.selectedCredentials
|
||||||
|
.vault.id) ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.credTags = MultiCredentialService
|
||||||
|
.updateCredentialTags($scope.selectedCredentials,
|
||||||
|
$scope.credentialTypeOptions);
|
||||||
|
};
|
||||||
|
|
||||||
let uncheckAllCredentials = function() {
|
let uncheckAllCredentials = function() {
|
||||||
$scope.credentials.forEach(cred => {
|
$scope.credentials.forEach(cred => {
|
||||||
cred.checked = 0;
|
cred.checked = 0;
|
||||||
@@ -156,14 +171,29 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$watch('selectedCredentials.vault', () => {
|
||||||
|
if($scope.selectedCredentials &&
|
||||||
|
$scope.selectedCredentials.vault &&
|
||||||
|
parseInt($scope.credentialKind) === 3) {
|
||||||
|
updateVaultCredentialList();
|
||||||
|
} else {
|
||||||
|
uncheckAllCredentials();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$scope.$watchGroup(['credentials',
|
$scope.$watchGroup(['credentials',
|
||||||
'selectedCredentials.machine'], () => {
|
'selectedCredentials.machine',
|
||||||
|
'selectedCredentials.vault'], () => {
|
||||||
if($scope.credentials &&
|
if($scope.credentials &&
|
||||||
$scope.credentials.length > 0) {
|
$scope.credentials.length > 0) {
|
||||||
if($scope.selectedCredentials &&
|
if($scope.selectedCredentials &&
|
||||||
$scope.selectedCredentials.machine &&
|
$scope.selectedCredentials.machine &&
|
||||||
parseInt($scope.credentialKind) === 1) {
|
parseInt($scope.credentialKind) === 1) {
|
||||||
updateMachineCredentialList();
|
updateMachineCredentialList();
|
||||||
|
} else if($scope.selectedCredentials &&
|
||||||
|
$scope.selectedCredentials.vault &&
|
||||||
|
parseInt($scope.credentialKind) === 3) {
|
||||||
|
updateVaultCredentialList();
|
||||||
} else if($scope.selectedCredentials &&
|
} else if($scope.selectedCredentials &&
|
||||||
$scope.selectedCredentials.extra &&
|
$scope.selectedCredentials.extra &&
|
||||||
$scope.selectedCredentials.extra.length > 0 &&
|
$scope.selectedCredentials.extra.length > 0 &&
|
||||||
@@ -189,6 +219,14 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
|
|||||||
} else {
|
} else {
|
||||||
$scope.selectedCredentials.machine = _.cloneDeep(selectedRow);
|
$scope.selectedCredentials.machine = _.cloneDeep(selectedRow);
|
||||||
}
|
}
|
||||||
|
}else if(parseInt($scope.credentialKind) === 3) {
|
||||||
|
if($scope.selectedCredentials &&
|
||||||
|
$scope.selectedCredentials.vault &&
|
||||||
|
$scope.selectedCredentials.vault.id === selectedRow.id) {
|
||||||
|
$scope.selectedCredentials.vault = null;
|
||||||
|
} else {
|
||||||
|
$scope.selectedCredentials.vault = _.cloneDeep(selectedRow);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let rowDeselected = false;
|
let rowDeselected = false;
|
||||||
for (let i = $scope.selectedCredentials.extra.length - 1; i >= 0; i--) {
|
for (let i = $scope.selectedCredentials.extra.length - 1; i >= 0; i--) {
|
||||||
@@ -211,6 +249,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
|
|||||||
$scope.selectedCredentialsDirty = function() {
|
$scope.selectedCredentialsDirty = function() {
|
||||||
if ($scope.originalSelectedCredentials) {
|
if ($scope.originalSelectedCredentials) {
|
||||||
return !($scope.originalSelectedCredentials.machine === null &&
|
return !($scope.originalSelectedCredentials.machine === null &&
|
||||||
|
$scope.originalSelectedCredentials.vault === null &&
|
||||||
$scope.originalSelectedCredentials.extra.length === 0) &&
|
$scope.originalSelectedCredentials.extra.length === 0) &&
|
||||||
!_.isEqual($scope.selectedCredentials,
|
!_.isEqual($scope.selectedCredentials,
|
||||||
$scope.originalSelectedCredentials);
|
$scope.originalSelectedCredentials);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
data.results.forEach((credentialType => {
|
data.results.forEach((credentialType => {
|
||||||
credential_types[credentialType.id] = credentialType;
|
credential_types[credentialType.id] = credentialType;
|
||||||
if(credentialType.kind
|
if(credentialType.kind
|
||||||
.match(/^(machine|cloud|net|ssh)$/)) {
|
.match(/^(machine|cloud|net|ssh|vault)$/)) {
|
||||||
credentialTypeOptions.push({
|
credentialTypeOptions.push({
|
||||||
name: credentialType.name,
|
name: credentialType.name,
|
||||||
value: credentialType.id
|
value: credentialType.id
|
||||||
@@ -111,6 +111,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
val.updateCredentialTags = (creds, typeOpts) => {
|
val.updateCredentialTags = (creds, typeOpts) => {
|
||||||
let machineCred = [];
|
let machineCred = [];
|
||||||
let extraCreds = [];
|
let extraCreds = [];
|
||||||
|
let vaultCred = [];
|
||||||
|
|
||||||
if (creds.machine) {
|
if (creds.machine) {
|
||||||
let mach = creds.machine;
|
let mach = creds.machine;
|
||||||
@@ -118,6 +119,12 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
machineCred = [mach];
|
machineCred = [mach];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (creds.vault) {
|
||||||
|
let vault = creds.vault;
|
||||||
|
vault.postType = "vault";
|
||||||
|
vaultCred = [vault];
|
||||||
|
}
|
||||||
|
|
||||||
if (creds.extra) {
|
if (creds.extra) {
|
||||||
extraCreds = creds.extra
|
extraCreds = creds.extra
|
||||||
.map((cred) => {
|
.map((cred) => {
|
||||||
@@ -127,7 +134,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return machineCred.concat(extraCreds).map(cred => ({
|
return machineCred.concat(extraCreds).concat(vaultCred).map(cred => ({
|
||||||
name: cred.name,
|
name: cred.name,
|
||||||
id: cred.id,
|
id: cred.id,
|
||||||
postType: cred.postType,
|
postType: cred.postType,
|
||||||
@@ -145,6 +152,8 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
if (credToRemove === cred.id) {
|
if (credToRemove === cred.id) {
|
||||||
if (cred.postType === 'machine') {
|
if (cred.postType === 'machine') {
|
||||||
structuredObj[cred.postType] = null;
|
structuredObj[cred.postType] = null;
|
||||||
|
} else if (cred.postType === 'vault') {
|
||||||
|
structuredObj[cred.postType] = null;
|
||||||
} else {
|
} else {
|
||||||
structuredObj[cred.postType] = structuredObj[cred.postType]
|
structuredObj[cred.postType] = structuredObj[cred.postType]
|
||||||
.filter(cred => cred
|
.filter(cred => cred
|
||||||
@@ -163,6 +172,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
val.loadCredentials = (data) => {
|
val.loadCredentials = (data) => {
|
||||||
let selectedCredentials = {
|
let selectedCredentials = {
|
||||||
machine: null,
|
machine: null,
|
||||||
|
vault: null,
|
||||||
extra: []
|
extra: []
|
||||||
}, credTypes, credTypeOptions, credTags;
|
}, credTypes, credTypeOptions, credTags;
|
||||||
|
|
||||||
@@ -187,6 +197,24 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.related.vault_credential) {
|
||||||
|
Rest.setUrl(data.related.vault_credential);
|
||||||
|
credDefers.push(Rest.get()
|
||||||
|
.then(({data}) => {
|
||||||
|
selectedCredentials.vault = data;
|
||||||
|
})
|
||||||
|
.catch(({data, status}) => {
|
||||||
|
ProcessErrors(
|
||||||
|
null, data, status, null,
|
||||||
|
{
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get machine credential. ' +
|
||||||
|
'Get returned status: ' +
|
||||||
|
status
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// get extra credentials
|
// get extra credentials
|
||||||
if (data.related.extra_credentials) {
|
if (data.related.extra_credentials) {
|
||||||
Rest.setUrl(data.related.extra_credentials);
|
Rest.setUrl(data.related.extra_credentials);
|
||||||
|
|||||||
@@ -85,3 +85,11 @@
|
|||||||
.LabelList-deleteContainer:hover > .LabelList-tagDelete, .JobSubmission-previewTagContainerDelete:hover > .JobSubmission-previewTagContainerTagDelete {
|
.LabelList-deleteContainer:hover > .LabelList-tagDelete, .JobSubmission-previewTagContainerDelete:hover > .JobSubmission-previewTagContainerTagDelete {
|
||||||
color: @default-bg;
|
color: @default-bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.JobSubmission-previewTagContainer--vault{
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.JobSubmission-previewTag--vault{
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user