mirror of
https://github.com/ansible/awx.git
synced 2026-06-26 17:08:03 -02:30
Merge pull request #1635 from matburt/new_azure_inventory_and_credentials
Implement Azure RM creds and inventory
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2015 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
CLOUD_PROVIDERS = ('azure', 'ec2', 'gce', 'rax', 'vmware', 'openstack', 'foreman', 'cloudforms')
|
||||
CLOUD_PROVIDERS = ('azure', 'azure_rm', 'ec2', 'gce', 'rax', 'vmware', 'openstack', 'foreman', 'cloudforms')
|
||||
SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom',)
|
||||
|
||||
@@ -466,10 +466,10 @@ def load_inventory_source(source, all_group=None, group_filter_re=None,
|
||||
'''
|
||||
Load inventory from given source directory or file.
|
||||
'''
|
||||
# Sanity check: We need the "azure" module to be titled "windows_azure.py",
|
||||
# because it depends on the "azure" package from PyPI, and naming the
|
||||
# module the same way makes the importer sad.
|
||||
source = source.replace('azure', 'windows_azure')
|
||||
# Sanity check: We sanitize these module names for our API but Ansible proper doesn't follow
|
||||
# good naming conventions
|
||||
if source == 'azure':
|
||||
source = 'windows_azure'
|
||||
|
||||
logger.debug('Analyzing type of source: %s', source)
|
||||
original_all_group = all_group
|
||||
|
||||
55
awx/main/migrations/0019_v300_new_azure_credential.py
Normal file
55
awx/main/migrations/0019_v300_new_azure_credential.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0018_v300_host_ordering'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='credential',
|
||||
name='client',
|
||||
field=models.CharField(default=b'', help_text='Client Id or Application Id for the credential', max_length=128, blank=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='credential',
|
||||
name='secret',
|
||||
field=models.CharField(default=b'', help_text='Secret Token for this credential', max_length=1024, blank=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='credential',
|
||||
name='subscription',
|
||||
field=models.CharField(default=b'', help_text='Subscription identifier for this credential', max_length=1024, blank=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='credential',
|
||||
name='tenant',
|
||||
field=models.CharField(default=b'', help_text='Tenant identifier for this credential', max_length=1024, blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='credential',
|
||||
name='kind',
|
||||
field=models.CharField(default=b'ssh', max_length=32, choices=[(b'ssh', 'Machine'), (b'net', 'Network'), (b'scm', 'Source Control'), (b'aws', 'Amazon Web Services'), (b'rax', 'Rackspace'), (b'vmware', 'VMware vCenter'), (b'foreman', 'Satellite 6'), (b'cloudforms', 'CloudForms'), (b'gce', 'Google Compute Engine'), (b'azure', 'Microsoft Azure Classic (deprecated)'), (b'azure_rm', 'Microsoft Azure Resource Manager'), (b'openstack', 'OpenStack')]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='host',
|
||||
name='instance_id',
|
||||
field=models.CharField(default=b'', max_length=1024, blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventorysource',
|
||||
name='source',
|
||||
field=models.CharField(default=b'', max_length=32, blank=True, choices=[(b'', 'Manual'), (b'file', 'Local File, Directory or Script'), (b'rax', 'Rackspace Cloud Servers'), (b'ec2', 'Amazon EC2'), (b'gce', 'Google Compute Engine'), (b'azure', 'Microsoft Azure Classic (deprecated)'), (b'azure_rm', 'Microsoft Azure Resource Manager'), (b'vmware', 'VMware vCenter'), (b'foreman', 'Satellite 6'), (b'cloudforms', 'CloudForms'), (b'openstack', 'OpenStack'), (b'custom', 'Custom Script')]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventoryupdate',
|
||||
name='source',
|
||||
field=models.CharField(default=b'', max_length=32, blank=True, choices=[(b'', 'Manual'), (b'file', 'Local File, Directory or Script'), (b'rax', 'Rackspace Cloud Servers'), (b'ec2', 'Amazon EC2'), (b'gce', 'Google Compute Engine'), (b'azure', 'Microsoft Azure Classic (deprecated)'), (b'azure_rm', 'Microsoft Azure Resource Manager'), (b'vmware', 'VMware vCenter'), (b'foreman', 'Satellite 6'), (b'cloudforms', 'CloudForms'), (b'openstack', 'OpenStack'), (b'custom', 'Custom Script')]),
|
||||
),
|
||||
|
||||
]
|
||||
@@ -61,7 +61,7 @@ PERMISSION_TYPE_CHOICES = [
|
||||
(PERM_JOBTEMPLATE_CREATE, _('Create a Job Template')),
|
||||
]
|
||||
|
||||
CLOUD_INVENTORY_SOURCES = ['ec2', 'rax', 'vmware', 'gce', 'azure', 'openstack', 'custom', 'foreman', 'cloudforms']
|
||||
CLOUD_INVENTORY_SOURCES = ['ec2', 'rax', 'vmware', 'gce', 'azure', 'azure_rm', 'openstack', 'custom', 'foreman', 'cloudforms']
|
||||
|
||||
VERBOSITY_CHOICES = [
|
||||
(0, '0 (Normal)'),
|
||||
|
||||
@@ -41,7 +41,8 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
|
||||
('foreman', _('Red Hat Satellite 6')),
|
||||
('cloudforms', _('Red Hat CloudForms')),
|
||||
('gce', _('Google Compute Engine')),
|
||||
('azure', _('Microsoft Azure')),
|
||||
('azure', _('Microsoft Azure Classic (deprecated)')),
|
||||
('azure_rm', _('Microsoft Azure Resource Manager')),
|
||||
('openstack', _('OpenStack')),
|
||||
]
|
||||
|
||||
@@ -55,7 +56,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
|
||||
]
|
||||
|
||||
PASSWORD_FIELDS = ('password', 'security_token', 'ssh_key_data', 'ssh_key_unlock',
|
||||
'become_password', 'vault_password')
|
||||
'become_password', 'vault_password', 'secret')
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
@@ -168,6 +169,30 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
|
||||
default='',
|
||||
help_text=_('Vault password (or "ASK" to prompt the user).'),
|
||||
)
|
||||
client = models.CharField(
|
||||
max_length=128,
|
||||
blank=True,
|
||||
default='',
|
||||
help_text=_('Client Id or Application Id for the credential'),
|
||||
)
|
||||
secret = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
help_text=_('Secret Token for this credential'),
|
||||
)
|
||||
subscription = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
help_text=_('Subscription identifier for this credential'),
|
||||
)
|
||||
tenant = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
help_text=_('Tenant identifier for this credential'),
|
||||
)
|
||||
owner_role = ImplicitRoleField(
|
||||
role_name='Credential Owner',
|
||||
role_description='Owner of the credential',
|
||||
|
||||
@@ -355,7 +355,7 @@ class Host(CommonModelNameNotUnique, ResourceMixin):
|
||||
help_text=_('Is this host online and available for running jobs?'),
|
||||
)
|
||||
instance_id = models.CharField(
|
||||
max_length=100,
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
@@ -748,7 +748,8 @@ class InventorySourceOptions(BaseModel):
|
||||
('rax', _('Rackspace Cloud Servers')),
|
||||
('ec2', _('Amazon EC2')),
|
||||
('gce', _('Google Compute Engine')),
|
||||
('azure', _('Microsoft Azure')),
|
||||
('azure', _('Microsoft Azure Classic (deprecated)')),
|
||||
('azure_rm', _('Microsoft Azure Resource Manager')),
|
||||
('vmware', _('VMware vCenter')),
|
||||
('foreman', _('Red Hat Satellite 6')),
|
||||
('cloudforms', _('Red Hat CloudForms')),
|
||||
@@ -969,6 +970,10 @@ class InventorySourceOptions(BaseModel):
|
||||
regions.insert(0, ('all', 'All'))
|
||||
return regions
|
||||
|
||||
@classmethod
|
||||
def get_azure_rm_region_choices(self):
|
||||
return InventorySourceOptions.get_azure_region_choices()
|
||||
|
||||
@classmethod
|
||||
def get_vmware_region_choices(self):
|
||||
"""Return a complete list of regions in VMware, as a list of two-tuples
|
||||
|
||||
@@ -801,6 +801,16 @@ class RunJob(BaseTask):
|
||||
elif cloud_cred and cloud_cred.kind == 'azure':
|
||||
env['AZURE_SUBSCRIPTION_ID'] = cloud_cred.username
|
||||
env['AZURE_CERT_PATH'] = kwargs.get('private_data_files', {}).get('cloud_credential', '')
|
||||
elif cloud_cred and cloud_cred.kind == 'azure_rm':
|
||||
if len(cloud_cred.client) and len(cloud_cred.tenant):
|
||||
env['AZURE_CLIENT_ID'] = cloud_cred.client
|
||||
env['AZURE_SECRET'] = decrypt_field(cloud_cred, 'secret')
|
||||
env['AZURE_TENANT'] = cloud_cred.tenant
|
||||
env['AZURE_SUBSCRIPTION_ID'] = cloud_cred.subscription
|
||||
else:
|
||||
env['AZURE_SUBSCRIPTION_ID'] = cloud_cred.subscription
|
||||
env['AZURE_AD_USER'] = cloud_cred.username
|
||||
env['AZURE_PASSWORD'] = decrypt_field(cloud_cred, 'password')
|
||||
elif cloud_cred and cloud_cred.kind == 'vmware':
|
||||
env['VMWARE_USER'] = cloud_cred.username
|
||||
env['VMWARE_PASSWORD'] = decrypt_field(cloud_cred, 'password')
|
||||
@@ -1278,6 +1288,14 @@ class RunInventoryUpdate(BaseTask):
|
||||
cp.set(section, 'username', credential.username)
|
||||
cp.set(section, 'password', decrypt_field(credential, 'password'))
|
||||
|
||||
elif inventory_update.source == 'azure_rm':
|
||||
section = 'azure'
|
||||
cp.add_section(section)
|
||||
cp.set(section, 'include_powerstate', 'yes')
|
||||
cp.set(section, 'group_by_resource_group', 'yes')
|
||||
cp.set(section, 'group_by_location', 'yes')
|
||||
cp.set(section, 'group_by_tag', 'yes')
|
||||
|
||||
# Return INI content.
|
||||
if cp.sections():
|
||||
f = cStringIO.StringIO()
|
||||
@@ -1298,9 +1316,9 @@ class RunInventoryUpdate(BaseTask):
|
||||
# passwords dictionary.
|
||||
credential = inventory_update.credential
|
||||
if credential:
|
||||
for subkey in ('username', 'host', 'project'):
|
||||
for subkey in ('username', 'host', 'project', 'client', 'tenant', 'subscription'):
|
||||
passwords['source_%s' % subkey] = getattr(credential, subkey)
|
||||
for passkey in ('password', 'ssh_key_data', 'security_token'):
|
||||
for passkey in ('password', 'ssh_key_data', 'security_token', 'secret'):
|
||||
k = 'source_%s' % passkey
|
||||
passwords[k] = decrypt_field(credential, passkey)
|
||||
return passwords
|
||||
@@ -1353,6 +1371,17 @@ class RunInventoryUpdate(BaseTask):
|
||||
elif inventory_update.source == 'azure':
|
||||
env['AZURE_SUBSCRIPTION_ID'] = passwords.get('source_username', '')
|
||||
env['AZURE_CERT_PATH'] = cloud_credential
|
||||
elif inventory_update.source == 'azure_rm':
|
||||
if len(passwords.get('source_client', '')) and \
|
||||
len(passwords.get('source_tenant', '')):
|
||||
env['AZURE_CLIENT_ID'] = passwords.get('source_client', '')
|
||||
env['AZURE_SECRET'] = passwords.get('source_secret', '')
|
||||
env['AZURE_TENANT'] = passwords.get('source_tenant', '')
|
||||
env['AZURE_SUBSCRIPTION_ID'] = passwords.get('source_subscription', '')
|
||||
else:
|
||||
env['AZURE_SUBSCRIPTION_ID'] = passwords.get('source_subscription', '')
|
||||
env['AZURE_AD_USER'] = passwords.get('source_username', '')
|
||||
env['AZURE_PASSWORD'] = passwords.get('source_password', '')
|
||||
elif inventory_update.source == 'gce':
|
||||
env['GCE_EMAIL'] = passwords.get('source_username', '')
|
||||
env['GCE_PROJECT'] = passwords.get('source_project', '')
|
||||
|
||||
Reference in New Issue
Block a user