mirror of
https://github.com/ansible/awx.git
synced 2026-02-14 17:50:02 -03:30
Remove Collections module parameters deprecated in Controller 4.0.0
This commit is contained in:
@@ -49,15 +49,33 @@ options:
|
||||
type: str
|
||||
credential_type:
|
||||
description:
|
||||
- Name of credential type.
|
||||
- Will be preferred over kind
|
||||
- The credential type being created.
|
||||
- Can be a built-in credential type such as "Machine", or a custom credential type such as "My Credential Type"
|
||||
type: str
|
||||
inputs:
|
||||
description:
|
||||
- >-
|
||||
Credential inputs where the keys are var names used in templating.
|
||||
Refer to the Automation Platform Controller documentation for example syntax.
|
||||
- Any fields in this dict will take prescedence over any fields mentioned below (i.e. host, username, etc)
|
||||
- authorize (use this for net type)
|
||||
- authorize_password (password for net credentials that require authorize)
|
||||
- client (client or application ID for azure_rm type)
|
||||
- security_token (STS token for aws type)
|
||||
- secret (secret token for azure_rm type)
|
||||
- tenant (tenant ID for azure_rm type)
|
||||
- subscription (subscription ID for azure_rm type)
|
||||
- domain (domain for openstack type)
|
||||
- become_method (become method to use for privilege escalation; some examples are "None", "sudo", "su", "pbrun")
|
||||
- become_username (become username; use "ASK" and launch job to be prompted)
|
||||
- become_password (become password; use "ASK" and launch job to be prompted)
|
||||
- vault_password (the vault password; use "ASK" and launch job to be prompted)
|
||||
- project (project that should use this credential for GCP)
|
||||
- host (the host for this credential)
|
||||
- username (the username for this credential; ``access_key`` for AWS)
|
||||
- password (the password for this credential; ``secret_key`` for AWS, ``api_key`` for RAX)
|
||||
- ssh_key_data (SSH private key content; to extract the content from a file path, use the lookup function (see examples))
|
||||
- vault_id (the vault identifier; this parameter is only valid if C(kind) is specified as C(vault).)
|
||||
- ssh_key_unlock (unlock password for ssh_key; use "ASK" and launch job to be prompted)
|
||||
type: dict
|
||||
update_secrets:
|
||||
description:
|
||||
@@ -73,119 +91,6 @@ options:
|
||||
description:
|
||||
- Team that should own this credential.
|
||||
type: str
|
||||
|
||||
kind:
|
||||
description:
|
||||
- Type of credential being added.
|
||||
- The ssh choice refers to a Tower Machine credential.
|
||||
- Deprecated, please use credential_type
|
||||
required: False
|
||||
type: str
|
||||
choices: ["aws", "controller", "gce", "azure_rm", "openstack", "satellite6", "rhv", "vmware", "aim", "conjur", "hashivault_kv", "hashivault_ssh",
|
||||
"azure_kv", "insights", "kubernetes_bearer_token", "net", "scm", "ssh", "github_token", "gitlab_token", "vault"]
|
||||
host:
|
||||
description:
|
||||
- Host for this credential.
|
||||
- Deprecated, will be removed in a future release
|
||||
type: str
|
||||
username:
|
||||
description:
|
||||
- Username for this credential. ``access_key`` for AWS.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- Password for this credential. ``secret_key`` for AWS. ``api_key`` for RAX.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
project:
|
||||
description:
|
||||
- Project that should use this credential for GCP.
|
||||
- Deprecated, will be removed in a future release
|
||||
type: str
|
||||
ssh_key_data:
|
||||
description:
|
||||
- SSH private key content. To extract the content from a file path, use the lookup function (see examples).
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
ssh_key_unlock:
|
||||
description:
|
||||
- Unlock password for ssh_key.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
authorize:
|
||||
description:
|
||||
- Should use authorize for net type.
|
||||
- Deprecated, please use inputs
|
||||
type: bool
|
||||
authorize_password:
|
||||
description:
|
||||
- Password for net credentials that require authorize.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
client:
|
||||
description:
|
||||
- Client or application ID for azure_rm type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
security_token:
|
||||
description:
|
||||
- STS token for aws type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
secret:
|
||||
description:
|
||||
- Secret token for azure_rm type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
subscription:
|
||||
description:
|
||||
- Subscription ID for azure_rm type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
tenant:
|
||||
description:
|
||||
- Tenant ID for azure_rm type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
domain:
|
||||
description:
|
||||
- Domain for openstack type.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
become_method:
|
||||
description:
|
||||
- Become method to use for privilege escalation.
|
||||
- Some examples are "None", "sudo", "su", "pbrun"
|
||||
- Due to become plugins, these can be arbitrary
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
become_username:
|
||||
description:
|
||||
- Become username.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
become_password:
|
||||
description:
|
||||
- Become password.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
vault_password:
|
||||
description:
|
||||
- Vault password.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
vault_id:
|
||||
description:
|
||||
- Vault identifier.
|
||||
- This parameter is only valid if C(kind) is specified as C(vault).
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
- Desired state of the resource.
|
||||
@@ -290,53 +195,6 @@ EXAMPLES = '''
|
||||
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
KIND_CHOICES = {
|
||||
'aws': 'Amazon Web Services',
|
||||
'controller': 'Red Hat Ansible Automation Platform',
|
||||
'gce': 'Google Compute Engine',
|
||||
'azure_rm': 'Microsoft Azure Resource Manager',
|
||||
'openstack': 'OpenStack',
|
||||
'satellite6': 'Red Hat Satellite 6',
|
||||
'rhv': 'Red Hat Virtualization',
|
||||
'vmware': 'VMware vCenter',
|
||||
'aim': 'CyberArk AIM Central Credential Provider Lookup',
|
||||
'conjur': 'CyberArk Conjur Secret Lookup',
|
||||
'hashivault_kv': 'HashiCorp Vault Secret Lookup',
|
||||
'hashivault_ssh': 'HashiCorp Vault Signed SSH',
|
||||
'azure_kv': 'Microsoft Azure Key Vault',
|
||||
'insights': 'Insights',
|
||||
'kubernetes_bearer_token': 'OpenShift or Kubernetes API Bearer Token',
|
||||
'net': 'Network',
|
||||
'scm': 'Source Control',
|
||||
'ssh': 'Machine',
|
||||
'github_token': 'GitHub Personal Access Token',
|
||||
'gitlab_token': 'GitLab Personal Access Token',
|
||||
'vault': 'Vault',
|
||||
}
|
||||
|
||||
|
||||
OLD_INPUT_NAMES = (
|
||||
'authorize',
|
||||
'authorize_password',
|
||||
'client',
|
||||
'security_token',
|
||||
'secret',
|
||||
'tenant',
|
||||
'subscription',
|
||||
'domain',
|
||||
'become_method',
|
||||
'become_username',
|
||||
'become_password',
|
||||
'vault_password',
|
||||
'project',
|
||||
'host',
|
||||
'username',
|
||||
'password',
|
||||
'ssh_key_data',
|
||||
'vault_id',
|
||||
'ssh_key_unlock',
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
# Any additional arguments that are not fields of the item can be added here
|
||||
@@ -351,33 +209,11 @@ def main():
|
||||
update_secrets=dict(type='bool', default=True, no_log=False),
|
||||
user=dict(),
|
||||
team=dict(),
|
||||
# These are for backwards compatability
|
||||
kind=dict(choices=list(KIND_CHOICES.keys())),
|
||||
host=dict(),
|
||||
username=dict(),
|
||||
password=dict(no_log=True),
|
||||
project=dict(),
|
||||
ssh_key_data=dict(no_log=True),
|
||||
ssh_key_unlock=dict(no_log=True),
|
||||
authorize=dict(type='bool'),
|
||||
authorize_password=dict(no_log=True),
|
||||
client=dict(),
|
||||
security_token=dict(no_log=False),
|
||||
secret=dict(no_log=True),
|
||||
subscription=dict(),
|
||||
tenant=dict(),
|
||||
domain=dict(),
|
||||
become_method=dict(),
|
||||
become_username=dict(),
|
||||
become_password=dict(no_log=True),
|
||||
vault_password=dict(no_log=True),
|
||||
vault_id=dict(),
|
||||
# End backwards compatability
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = ControllerAPIModule(argument_spec=argument_spec, required_one_of=[['kind', 'credential_type']])
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@@ -389,25 +225,9 @@ def main():
|
||||
inputs = module.params.get('inputs')
|
||||
user = module.params.get('user')
|
||||
team = module.params.get('team')
|
||||
# The legacy arguments are put into a hash down below
|
||||
kind = module.params.get('kind')
|
||||
# End backwards compatability
|
||||
state = module.params.get('state')
|
||||
|
||||
# Deprecation warnings
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg='{0} parameter has been deprecated, please use inputs instead'.format(legacy_input),
|
||||
version="4.0.0")
|
||||
if kind:
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg='The kind parameter has been deprecated, please use credential_type instead',
|
||||
version="4.0.0")
|
||||
|
||||
cred_type_id = module.resolve_name_to_id('credential_types', credential_type if credential_type else KIND_CHOICES[kind])
|
||||
cred_type_id = module.resolve_name_to_id('credential_types', credential_type)
|
||||
if organization:
|
||||
org_id = module.resolve_name_to_id('organizations', organization)
|
||||
|
||||
@@ -444,26 +264,14 @@ def main():
|
||||
if team:
|
||||
team_id = module.resolve_name_to_id('teams', team)
|
||||
|
||||
# Create credential input from legacy inputs
|
||||
has_inputs = False
|
||||
credential_inputs = {}
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
has_inputs = True
|
||||
credential_inputs[legacy_input] = module.params.get(legacy_input)
|
||||
|
||||
if inputs:
|
||||
has_inputs = True
|
||||
credential_inputs.update(inputs)
|
||||
|
||||
# Create the data that gets sent for create and update
|
||||
credential_fields = {
|
||||
'name': new_name if new_name else (module.get_item_name(credential) if credential else name),
|
||||
'credential_type': cred_type_id,
|
||||
}
|
||||
if has_inputs:
|
||||
credential_fields['inputs'] = credential_inputs
|
||||
|
||||
if inputs:
|
||||
credential_fields['inputs'] = inputs
|
||||
if description:
|
||||
credential_fields['description'] = description
|
||||
if organization:
|
||||
|
||||
@@ -33,16 +33,6 @@ options:
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
min_interval:
|
||||
description:
|
||||
- Minimum interval in seconds, to request an update from the controller.
|
||||
- deprecated, use interval instead
|
||||
type: float
|
||||
max_interval:
|
||||
description:
|
||||
- Maximum interval in seconds, to request an update from the controller.
|
||||
- deprecated, use interval instead
|
||||
type: float
|
||||
timeout:
|
||||
description:
|
||||
- Maximum time in seconds to wait for a job to finish.
|
||||
@@ -106,8 +96,6 @@ def main():
|
||||
job_id=dict(type='int', required=True),
|
||||
job_type=dict(choices=['project_updates', 'jobs', 'inventory_updates', 'workflow_jobs'], default='jobs'),
|
||||
timeout=dict(type='int'),
|
||||
min_interval=dict(type='float'),
|
||||
max_interval=dict(type='float'),
|
||||
interval=dict(type='float', default=1),
|
||||
)
|
||||
|
||||
@@ -118,25 +106,8 @@ def main():
|
||||
job_id = module.params.get('job_id')
|
||||
job_type = module.params.get('job_type')
|
||||
timeout = module.params.get('timeout')
|
||||
min_interval = module.params.get('min_interval')
|
||||
max_interval = module.params.get('max_interval')
|
||||
interval = module.params.get('interval')
|
||||
|
||||
if min_interval is not None or max_interval is not None:
|
||||
# We can't tell if we got the default or if someone actually set this to 1.
|
||||
# For now if we find 1 and had a min or max then we will do the average logic.
|
||||
if interval == 1:
|
||||
if not min_interval:
|
||||
min_interval = 1
|
||||
if not max_interval:
|
||||
max_interval = 30
|
||||
interval = abs((min_interval + max_interval) / 2)
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg="Min and max interval have been deprecated, please use interval instead; interval will be set to {0}".format(interval),
|
||||
version="4.0.0",
|
||||
)
|
||||
|
||||
# Attempt to look up job based on the provided id
|
||||
job = module.get_one(
|
||||
job_type,
|
||||
|
||||
@@ -63,141 +63,36 @@ options:
|
||||
notification_configuration:
|
||||
description:
|
||||
- The notification configuration file. Note providing this field would disable all notification-configuration-related fields.
|
||||
- username (the mail server username)
|
||||
- sender (the sender email address)
|
||||
- recipients (the recipients email addresses)
|
||||
- use_tls (the TLS trigger)
|
||||
- host (the mail server host)
|
||||
- use_ssl (the SSL trigger)
|
||||
- password (the mail server password)
|
||||
- port (the mail server port)
|
||||
- channels (the destination Slack channels)
|
||||
- token (the access token)
|
||||
- account_token (the Twillio account token)
|
||||
- from_number (the source phone number)
|
||||
- to_numbers (the destination phone numbers)
|
||||
- account_sid (the Twillio account SID)
|
||||
- subdomain (the PagerDuty subdomain)
|
||||
- service_key (the PagerDuty service/integration API key)
|
||||
- client_name (the PagerDuty client identifier)
|
||||
- message_from (the label to be shown with the notification)
|
||||
- color (the notification color)
|
||||
- notify (the notify channel trigger)
|
||||
- url (the target URL)
|
||||
- headers (the HTTP headers as JSON string)
|
||||
- server (the IRC server address)
|
||||
- nickname (the IRC nickname)
|
||||
- targets (the destination channels or users)
|
||||
type: dict
|
||||
messages:
|
||||
description:
|
||||
- Optional custom messages for notification template.
|
||||
type: dict
|
||||
username:
|
||||
description:
|
||||
- The mail server username.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
sender:
|
||||
description:
|
||||
- The sender email address.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
recipients:
|
||||
description:
|
||||
- The recipients email addresses.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: list
|
||||
elements: str
|
||||
use_tls:
|
||||
description:
|
||||
- The TLS trigger.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: bool
|
||||
host:
|
||||
description:
|
||||
- The mail server host.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
use_ssl:
|
||||
description:
|
||||
- The SSL trigger.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: bool
|
||||
password:
|
||||
description:
|
||||
- The mail server password.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
port:
|
||||
description:
|
||||
- The mail server port.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: int
|
||||
channels:
|
||||
description:
|
||||
- The destination Slack channels.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: list
|
||||
elements: str
|
||||
token:
|
||||
description:
|
||||
- The access token.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
account_token:
|
||||
description:
|
||||
- The Twillio account token.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
from_number:
|
||||
description:
|
||||
- The source phone number.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
to_numbers:
|
||||
description:
|
||||
- The destination phone numbers.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: list
|
||||
elements: str
|
||||
account_sid:
|
||||
description:
|
||||
- The Twillio account SID.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
subdomain:
|
||||
description:
|
||||
- The PagerDuty subdomain.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
service_key:
|
||||
description:
|
||||
- The PagerDuty service/integration API key.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
client_name:
|
||||
description:
|
||||
- The PagerDuty client identifier.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
message_from:
|
||||
description:
|
||||
- The label to be shown with the notification.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
color:
|
||||
description:
|
||||
- The notification color.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
choices: ["yellow", "green", "red", "purple", "gray", "random"]
|
||||
type: str
|
||||
notify:
|
||||
description:
|
||||
- The notify channel trigger.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: bool
|
||||
url:
|
||||
description:
|
||||
- The target URL.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
headers:
|
||||
description:
|
||||
- The HTTP headers as JSON string.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: dict
|
||||
server:
|
||||
description:
|
||||
- The IRC server address.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
nickname:
|
||||
description:
|
||||
- The IRC nickname.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: str
|
||||
targets:
|
||||
description:
|
||||
- The destination channels or users.
|
||||
- This parameter has been deprecated, please use 'notification_configuration' instead.
|
||||
type: list
|
||||
elements: str
|
||||
state:
|
||||
description:
|
||||
- Desired state of the resource.
|
||||
@@ -315,34 +210,6 @@ RETURN = ''' # '''
|
||||
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
OLD_INPUT_NAMES = (
|
||||
'username',
|
||||
'sender',
|
||||
'recipients',
|
||||
'use_tls',
|
||||
'host',
|
||||
'use_ssl',
|
||||
'password',
|
||||
'port',
|
||||
'channels',
|
||||
'token',
|
||||
'account_token',
|
||||
'from_number',
|
||||
'to_numbers',
|
||||
'account_sid',
|
||||
'subdomain',
|
||||
'service_key',
|
||||
'client_name',
|
||||
'message_from',
|
||||
'color',
|
||||
'notify',
|
||||
'url',
|
||||
'headers',
|
||||
'server',
|
||||
'nickname',
|
||||
'targets',
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
# Any additional arguments that are not fields of the item can be added here
|
||||
@@ -355,31 +222,6 @@ def main():
|
||||
notification_type=dict(choices=['email', 'grafana', 'irc', 'mattermost', 'pagerduty', 'rocketchat', 'slack', 'twilio', 'webhook']),
|
||||
notification_configuration=dict(type='dict'),
|
||||
messages=dict(type='dict'),
|
||||
username=dict(),
|
||||
sender=dict(),
|
||||
recipients=dict(type='list', elements='str'),
|
||||
use_tls=dict(type='bool'),
|
||||
host=dict(),
|
||||
use_ssl=dict(type='bool'),
|
||||
password=dict(no_log=True),
|
||||
port=dict(type='int'),
|
||||
channels=dict(type='list', elements='str'),
|
||||
token=dict(no_log=True),
|
||||
account_token=dict(no_log=True),
|
||||
from_number=dict(),
|
||||
to_numbers=dict(type='list', elements='str'),
|
||||
account_sid=dict(),
|
||||
subdomain=dict(),
|
||||
service_key=dict(no_log=True),
|
||||
client_name=dict(),
|
||||
message_from=dict(),
|
||||
color=dict(choices=['yellow', 'green', 'red', 'purple', 'gray', 'random']),
|
||||
notify=dict(type='bool'),
|
||||
url=dict(),
|
||||
headers=dict(type='dict'),
|
||||
server=dict(),
|
||||
nickname=dict(),
|
||||
targets=dict(type='list', elements='str'),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
@@ -397,15 +239,6 @@ def main():
|
||||
messages = module.params.get('messages')
|
||||
state = module.params.get('state')
|
||||
|
||||
# Deprecation warnings for all other params
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg='{0} parameter has been deprecated, please use notification_configuration instead'.format(legacy_input),
|
||||
version="4.0.0"
|
||||
)
|
||||
|
||||
# Attempt to look up the related items the user specified (these will fail the module if not found)
|
||||
organization_id = None
|
||||
if organization:
|
||||
@@ -438,12 +271,7 @@ def main():
|
||||
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this
|
||||
module.delete_if_needed(existing_item)
|
||||
|
||||
# Create notification_configuration from legacy inputs
|
||||
final_notification_configuration = {}
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
final_notification_configuration[legacy_input] = module.params.get(legacy_input)
|
||||
# Give anything in notification_configuration prescedence over the individual inputs
|
||||
if notification_configuration is not None:
|
||||
final_notification_configuration.update(notification_configuration)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user