-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #132 from scsitteam/acme
Acme
- Loading branch information
Showing
28 changed files
with
3,361 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from ansible.module_utils.basic import AnsibleModule | ||
|
||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.api import \ | ||
Session | ||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.cls import BaseModule | ||
|
||
|
||
class Account(BaseModule): | ||
FIELD_ID = 'name' | ||
CMDS = { | ||
'add': 'add', | ||
'del': 'del', | ||
'set': 'update', | ||
'search': 'get', | ||
'toggle': 'toggle', | ||
} | ||
API_KEY_PATH = 'acmeclient.accounts.account' | ||
API_MOD = 'acmeclient' | ||
API_CONT = 'accounts' | ||
API_CONT_GET = 'settings' | ||
FIELDS_CHANGE = ['description', 'custom_ca', 'eab_kid', 'eab_hmac'] | ||
FIELDS_ALL = [ | ||
'enabled', 'name', 'email', 'ca', | ||
] | ||
FIELDS_ALL.extend(FIELDS_CHANGE) | ||
FIELDS_TYPING = { | ||
'bool': ['enabled'], | ||
'select': ['ca'], | ||
} | ||
EXIST_ATTR = 'account' | ||
|
||
def __init__(self, module: AnsibleModule, result: dict, session: Session = None): | ||
BaseModule.__init__(self=self, m=module, r=result, s=session) | ||
self.account = {} | ||
|
||
def process(self) -> None: | ||
self.b.process() | ||
|
||
if self.p['state'] == 'present' and self.p['register']: | ||
self.register() | ||
|
||
def register(self) -> None: | ||
if self.account.get('statusCode', 100) == 200: | ||
return | ||
|
||
self.r['changed'] = True | ||
if not self.m.check_mode: | ||
cont_get, mod_get = self.API_CONT, self.API_MOD | ||
self.call_cnf['controller'] = cont_get | ||
self.call_cnf['module'] = mod_get | ||
self.s.post(cnf={ | ||
**self.call_cnf, | ||
'command': 'register', | ||
}) | ||
|
||
def reload(self): | ||
# no reload required | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from ansible.module_utils.basic import AnsibleModule | ||
|
||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.api import \ | ||
Session | ||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.main import \ | ||
validate_int_fields, is_unset | ||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.cls import BaseModule | ||
|
||
|
||
class Action(BaseModule): | ||
FIELD_ID = 'name' | ||
CMDS = { | ||
'add': 'add', | ||
'del': 'del', | ||
'set': 'update', | ||
'search': 'get', | ||
'toggle': 'toggle', | ||
} | ||
API_KEY_PATH = 'acmeclient.actions.action' | ||
API_MOD = 'acmeclient' | ||
API_CONT = 'actions' | ||
API_CONT_GET = 'settings' | ||
FIELDS_CHANGE = ['type'] | ||
FIELDS_ALL = [ | ||
'enabled', 'name', 'description', | ||
# SFTP | ||
'sftp_host', 'sftp_host_key', 'sftp_port', 'sftp_user', 'sftp_identity_type', | ||
'sftp_remote_path', 'sftp_chgrp', 'sftp_chmod', 'sftp_chmod_key', | ||
'sftp_filename_cert', 'sftp_filename_key', 'sftp_filename_ca', | ||
'sftp_filename_fullchain', | ||
# Remote SSH | ||
'remote_ssh_host', 'remote_ssh_host_key', 'remote_ssh_port', 'remote_ssh_user', | ||
'remote_ssh_identity_type', 'remote_ssh_command', | ||
# ACME FRITZ!Box | ||
'acme_fritzbox_url', 'acme_fritzbox_username', 'acme_fritzbox_password', | ||
# ACME PANOS | ||
'acme_panos_username', 'acme_panos_password', 'acme_panos_host', | ||
# ACME promox VE | ||
'acme_proxmoxve_user', 'acme_proxmoxve_server', 'acme_proxmoxve_port', | ||
'acme_proxmoxve_nodename', 'acme_proxmoxve_realm', 'acme_proxmoxve_tokenid', | ||
'acme_proxmoxve_tokenkey', | ||
# ACME Vault | ||
'acme_vault_url', 'acme_vault_prefix', 'acme_vault_token', 'acme_vault_kvv2', | ||
# ACME Synology DSM | ||
'acme_synology_dsm_hostname', 'acme_synology_dsm_port', 'acme_synology_dsm_scheme', | ||
'acme_synology_dsm_username', 'acme_synology_dsm_password', 'acme_synology_dsm_create', | ||
'acme_synology_dsm_deviceid', 'acme_synology_dsm_devicename', | ||
# ACME TrueNAS | ||
'acme_truenas_apikey', 'acme_truenas_hostname', 'acme_truenas_scheme', | ||
# ACME unifi | ||
'acme_unifi_keystore', | ||
] | ||
FIELDS_ALL.extend(FIELDS_CHANGE) | ||
FIELDS_TYPING = { | ||
'bool': ['enabled', 'acme_vault_kvv2', 'acme_synology_dsm_create'], | ||
'select': [ | ||
'type', 'remote_ssh_identity_type', 'acme_synology_dsm_scheme', 'acme_truenas_scheme', | ||
'sftp_identity_type', | ||
], | ||
'int': ['sftp_port', 'remote_ssh_port', 'acme_proxmoxve_port', 'acme_synology_dsm_port'], | ||
} | ||
INT_VALIDATIONS = { | ||
'sftp_port': {'min': 1, 'max': 65535}, | ||
} | ||
EXIST_ATTR = 'action' | ||
|
||
def __init__(self, module: AnsibleModule, result: dict, session: Session = None): | ||
BaseModule.__init__(self=self, m=module, r=result, s=session) | ||
self.action = {} | ||
|
||
def check(self) -> None: | ||
if self.p['state'] == 'present': | ||
if is_unset(self.p['type']): | ||
self.m.fail_json('You need to provide type to create/update actions!') | ||
|
||
validate_int_fields(module=self.m, data=self.p, field_minmax=self.INT_VALIDATIONS) | ||
|
||
if self.p['type'].startswith('acme_'): | ||
for field in self.FIELDS_ALL: | ||
if field.startswith(self.p['type']) and is_unset(self.p[field]): | ||
self.m.fail_json(f"You need to provide {field} to create/update {self.p['type']} actions!") | ||
|
||
self._base_check() | ||
|
||
def reload(self): | ||
# no reload required | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
from ansible.module_utils.basic import AnsibleModule | ||
|
||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.api import \ | ||
Session | ||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.main import \ | ||
validate_int_fields, is_unset | ||
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.cls import BaseModule | ||
|
||
|
||
class Certificate(BaseModule): | ||
FIELD_ID = 'description' | ||
CMDS = { | ||
'add': 'add', | ||
'del': 'del', | ||
'set': 'update', | ||
'search': 'get', | ||
'toggle': 'toggle', | ||
} | ||
API_KEY_PATH = 'acmeclient.certificates.certificate' | ||
API_MOD = 'acmeclient' | ||
API_CONT = 'certificates' | ||
API_CONT_GET = 'settings' | ||
FIELDS_CHANGE = [ | ||
'name', 'alt_names', 'account', 'validation', 'restart_actions', 'auto_renewal', 'renew_interval', 'aliasmode' | ||
] | ||
FIELDS_ALL = [ | ||
'enabled', 'description', 'domainalias', 'challengealias' | ||
] | ||
FIELDS_ALL.extend(FIELDS_CHANGE) | ||
FIELDS_TRANSLATE = { | ||
'alt_names': 'altNames', | ||
'validation': 'validationMethod', | ||
'key_ength': 'keyLength', | ||
'restart_actions': 'restartActions', | ||
'auto_renewal': 'autoRenewal', | ||
'renew_interval': 'renewInterval', | ||
} | ||
FIELDS_TYPING = { | ||
'bool': ['enabled', 'auto_renewal'], | ||
'list': ['alt_names', 'restart_actions'], | ||
'select': ['account', 'validation', 'restart_actions', 'aliasmode'], | ||
'int': ['renew_interval'], | ||
} | ||
INT_VALIDATIONS = { | ||
'renew_interval': {'min': 1, 'max': 5000}, | ||
} | ||
EXIST_ATTR = 'certificate' | ||
SEARCH_ADDITIONAL = { | ||
'existing_accounts': 'acmeclient.accounts.account', | ||
'existing_validations': 'acmeclient.validations.validation', | ||
'existing_actions': 'acmeclient.actions.action', | ||
} | ||
|
||
def __init__(self, module: AnsibleModule, result: dict, session: Session = None): | ||
BaseModule.__init__(self=self, m=module, r=result, s=session) | ||
self.certificate = {} | ||
self.existing_accounts = {} | ||
self.existing_validations = {} | ||
self.existing_actions = {} | ||
|
||
def check(self) -> None: | ||
if self.p['state'] == 'present': | ||
if is_unset(self.p['name']): | ||
self.m.fail_json('You need to provide a name to create/update certificates!') | ||
|
||
validate_int_fields(module=self.m, data=self.p, field_minmax=self.INT_VALIDATIONS) | ||
|
||
if self.p['aliasmode'] == 'domain': | ||
self.FIELDS_CHANGE.append('domainalias') | ||
|
||
elif self.p['aliasmode'] == 'challenge': | ||
self.FIELDS_CHANGE.append('challengealias') | ||
|
||
self._base_check() | ||
|
||
if self.p['state'] == 'present': | ||
self._resolve_relations() | ||
|
||
def _resolve_relations(self) -> None: | ||
if is_unset(self.p['account']): | ||
self.m.fail_json('You need to provide an account to create/update certificates!') | ||
|
||
else: | ||
if len(self.existing_accounts) > 0: | ||
for key, values in self.existing_accounts.items(): | ||
if values['name'] == self.p['account']: | ||
self.p['account'] = key | ||
break | ||
|
||
else: | ||
self.m.fail_json(f"Account {self.p['account']} does not exist! {self.existing_accounts}") | ||
|
||
if is_unset(self.p['validation']): | ||
self.m.fail_json('You need to provide the validation to create/update certificates!') | ||
|
||
else: | ||
if len(self.existing_validations) > 0: | ||
for key, values in self.existing_validations.items(): | ||
if values['name'] == self.p['validation']: | ||
self.p['validation'] = key | ||
break | ||
|
||
else: | ||
self.m.fail_json(f"Validation {self.p['validation']} does not exist!") | ||
|
||
if not is_unset(self.p['restart_actions']): | ||
mapping = { | ||
values['name']: key | ||
for key, values in self.existing_actions.items() | ||
} | ||
|
||
missing = [ | ||
action | ||
for action in self.p['restart_actions'] | ||
if action not in mapping | ||
] | ||
if any(missing): | ||
self.m.fail_json(f"Actions {missing.join(',')} do not exist!") | ||
|
||
self.p['restart_actions'] = [ | ||
mapping[action] | ||
for action in self.p['restart_actions'] | ||
] | ||
|
||
def reload(self): | ||
# no reload required | ||
pass |
Oops, something went wrong.