diff --git a/.gitignore b/.gitignore index 8c1c2ed..132397c 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,6 @@ config.yml .gitignore .DS_Store api_playground.py + +.vscode/ +.gitignore diff --git a/plugins/module_utils/statuscake.py b/plugins/module_utils/statuscake.py index 7d1709d..5dbf5b3 100644 --- a/plugins/module_utils/statuscake.py +++ b/plugins/module_utils/statuscake.py @@ -48,17 +48,15 @@ def full_url(self, path): return f"https://api.statuscake.com{path}" def prepare_data(self, data): - return data + cleaned_data = {} + for key, val in data.items(): + if val: + cleaned_data[key] = val + return cleaned_data def _request(self, method, path, **kwargs): requests_method = getattr(self.client, method) try: - data = {} - for key, val in kwargs["data"].items(): - if val: - data[key] = val - data = self.prepare_data(data) - kwargs["data"] = data logger.debug(f"Request data: {kwargs['data']}") except KeyError: pass @@ -89,6 +87,7 @@ def find_by_name(self): return test def prepare_data(self, data): + data = super().prepare_data(data) for key in self.CSV_PARAMETERS: if key in data: key_csv = f"{key}_csv" @@ -220,6 +219,7 @@ def find_by_website_url(self): return test def prepare_data(self, data): + data = super().prepare_data(data) for key in self.CSV_PARAMETERS: if key in data: key_csv = f"{key}_csv" @@ -262,7 +262,7 @@ def create(self): self._request("post", self.url, data=self.config) if self.response.status_code == 201: self.id = int(self.response.json()["data"]["new_id"]) - msg = f"A new test for '{self.config['website_url']}' was created." + msg = f"A new SSL test for '{self.config['website_url']}' was created." logger.info(msg) self.status.success = True self.status.changed = True diff --git a/plugins/modules/statuscake_ssl_test.py b/plugins/modules/statuscake_ssl_test.py new file mode 100644 index 0000000..01861d2 --- /dev/null +++ b/plugins/modules/statuscake_ssl_test.py @@ -0,0 +1,61 @@ +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.caktus.hosting_services.plugins.module_utils.statuscake import ( + SSLTest, +) + + +def main(): + argument_spec = { + "api_key": {"required": True, "type": "str", "no_log": True}, + "state": {"required": True, "type": "str", "choices": ["present", "absent"]}, + "website_url": {"required": True, "type": "str"}, + "check_rate": { + "required": True, + "type": "int", + "choices": [300, 600, 1800, 86400, 2073600], + }, + "contact_groups": {"required": False, "type": "list"}, + "alert_at": {"required": True, "type": "list"}, + "alert_reminder": {"required": True, "type": "bool"}, + "alert_expiry": {"required": True, "type": "bool"}, + "alert_broken": {"required": True, "type": "bool"}, + "alert_mixed": {"required": True, "type": "bool"}, + "follow_redirects": {"required": False, "type": "bool"}, + "paused": {"required": False, "type": "bool"}, + "hostname": {"required": False, "type": "str"}, + "user_agent": {"required": False, "type": "str"}, + "log_file": {"required": False, "type": "str"}, + } + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) + api_key = module.params["api_key"] + website_url = module.params["website_url"] + state = module.params["state"] + test = SSLTest( + api_key=api_key, + state=state, + website_url=website_url, + check_rate=module.params["check_rate"], + contact_groups=module.params["contact_groups"], + alert_at=module.params["alert_at"], + alert_reminder=module.params["alert_reminder"], + alert_expiry=module.params["alert_expiry"], + alert_broken=module.params["alert_broken"], + alert_mixed=module.params["alert_mixed"], + follow_redirects=module.params["follow_redirects"], + paused=module.params["paused"], + hostname=module.params["hostname"], + user_agent=module.params["user_agent"], + log_file=module.params["log_file"], + ) + status = test.sync() + if status.success: + module.exit_json( + changed=status.changed, + msg=status.message, + ) + else: + module.fail_json(msg=status.message) + + +if __name__ == "__main__": + main() diff --git a/roles/statuscake_monitoring/defaults/main.yml b/roles/statuscake_monitoring/defaults/main.yml index 98cc89f..f235c05 100644 --- a/roles/statuscake_monitoring/defaults/main.yml +++ b/roles/statuscake_monitoring/defaults/main.yml @@ -1,5 +1,47 @@ +# Uptime tests defaults statuscake_api_key: "" -statuscake_default_check_rate: 300 -statuscake_default_test_type: HTTP -statuscake_uptime_tests: [] -statuscake_merged_uptime_tests: [] +statuscake_test_types: [uptime, ssl] +statuscake_basic_username: "" +statuscake_basic_password: "" +statuscake_check_rate: 300 +statuscake_contact_groups: null +statuscake_final_endpoint: null +statuscake_follow_redirects: null +statuscake_log_file: "" +statuscake_find_string: "" +statuscake_confirmation: 2 +statuscake_custom_header: "" +statuscake_do_not_find: False +statuscake_dns_ip: null +statuscake_dns_server: "" +statuscake_enable_ssl_alert: False +statuscake_host: "" +statuscake_include_header: False +statuscake_paused: False +statuscake_port: null +statuscake_post_body: "" +statuscake_post_raw: "" +statuscake_regions: null +statuscake_state: present +statuscake_status_codes: ['204', '205', '206', '303', '400', '401', '403', '404', '405', '406', '408', '410', '413', '444', '429', '494', '495', '496', '499', '500', '501', '502', '503', '504', '505', '506', '507', '508', '509', '510', '511', '521', '522', '523', '524', '520', '598', '599'] +statuscake_tags: null +statuscake_test_type: HTTP +statuscake_timeout: "" +statuscake_trigger_rate: "" +statuscake_use_jar: "" +statuscake_user_agent: "" + +# SSL tests defaults +statuscake_ssl_alert_at: [28, 7, 1] # Comma separated list representing days to be notified before a cert expires. EG: Alert 28, 7, and 1 day before. +statuscake_ssl_alert_broken: True +statuscake_ssl_alert_expiry: True +statuscake_ssl_alert_mixed: True +statuscake_ssl_alert_reminder: True +statuscake_ssl_follow_redirects: False +statuscake_ssl_check_rate: 86400 +statuscake_ssl_contact_groups: "{{ statuscake_contact_groups }}" +statuscake_ssl_hostname: null +statuscake_ssl_log_file: "" +statuscake_ssl_paused: "{{ statuscake_paused }}" +statuscake_ssl_state: "{{ statuscake_state }}" +statuscake_ssl_user_agent: "" diff --git a/roles/statuscake_monitoring/tasks/main.yml b/roles/statuscake_monitoring/tasks/main.yml index f8fa07c..b966113 100644 --- a/roles/statuscake_monitoring/tasks/main.yml +++ b/roles/statuscake_monitoring/tasks/main.yml @@ -1,48 +1,62 @@ -- name: Merge statuscake_uptime_tests with templates - set_fact: - statuscake_merged_uptime_tests: "{{ (statuscake_merged_uptime_tests | default([])) + [ item['template'] | default({}) | combine(item) ] }}" - loop: "{{ statuscake_uptime_tests }}" - loop_control: - label: "{{ item['name'] }}" - - name: Configure uptime tests + tags: uptime caktus.hosting_services.statuscake_uptime_test: api_key: "{{ statuscake_api_key }}" - state: "{{ item['state'] }}" name: "{{ item['name'] }}" - check_rate: "{{ item['check_rate']|default(statuscake_default_check_rate) }}" - test_type: "{{ item['test_type']|default(statuscake_default_test_type) }}" website_url: "{{ item['website_url'] }}" - basic_username: "{{ item['basic_username']|default(omit) }}" - basic_password: "{{ item['basic_password']|default(omit) }}" - tags: "{{ item['tags']|default(omit) }}" - contact_groups: "{{ item['contact_groups']|default(omit) }}" - final_endpoint: "{{ item['final_endpoint']|default(omit) }}" - follow_redirects: "{{ item['follow_redirects']|default(omit) }}" - log_file: "{{ item['log_file']|default(omit) }}" - find_string: "{{ item['find_string']|default(omit) }}" - confirmation: "{{ item['confirmation']|default(omit) }}" - custom_header: "{{ item['custom_header']|default(omit) }}" - do_not_find: "{{ item['do_not_find']|default(omit) }}" - dns_ip: "{{ item['dns_ip']|default(omit) }}" - dns_server: "{{ item['dns_server']|default(omit) }}" - enable_ssl_alert: "{{ item['enable_ssl_alert']|default(omit) }}" - host: "{{ item['host']|default(omit) }}" - include_header: "{{ item['include_header']|default(omit) }}" - paused: "{{ item['paused']|default(omit) }}" - port: "{{ item['port']|default(omit) }}" - post_body: "{{ item['post_body']|default(omit) }}" - post_raw: "{{ item['post_raw']|default(omit) }}" - regions: "{{ item['regions']|default(omit) }}" - status_codes: "{{ item['status_codes']|default(omit) }}" - timeout: "{{ item['timeout']|default(omit) }}" - trigger_rate: "{{ item['trigger_rate']|default(omit) }}" - use_jar: "{{ item['use_jar']|default(omit) }}" - user_agent: "{{ item['user_agent']|default(omit) }}" - loop: "{{ statuscake_merged_uptime_tests }}" + basic_username: "{{ item['basic_username']|default(statuscake_basic_username) }}" + basic_password: "{{ item['basic_password']|default(statuscake_basic_password) }}" + check_rate: "{{ item['check_rate']|default(statuscake_check_rate) }}" + contact_groups: "{{ item['contact_groups'] | default(statuscake_contact_groups) }}" + final_endpoint: "{{ item['final_endpoint']|default(statuscake_final_endpoint) }}" + follow_redirects: "{{ item['follow_redirects']|default(statuscake_follow_redirects) }}" + log_file: "{{ item['log_file']|default(statuscake_log_file) }}" + find_string: "{{ item['find_string']|default(statuscake_find_string) }}" + confirmation: "{{ item['confirmation']|default(statuscake_confirmation) }}" + custom_header: "{{ item['custom_header']|default(statuscake_custom_header) }}" + do_not_find: "{{ item['do_not_find']|default(statuscake_do_not_find) }}" + dns_ip: "{{ item['dns_ip']|default(statuscake_dns_ip) }}" + dns_server: "{{ item['dns_server']|default(statuscake_dns_server) }}" + enable_ssl_alert: "{{ item['enable_ssl_alert']|default(statuscake_enable_ssl_alert) }}" + host: "{{ item['host']|default(statuscake_host) }}" + include_header: "{{ item['include_header']|default(statuscake_include_header) }}" + paused: "{{ item['paused']|default(statuscake_paused) }}" + port: "{{ item['port']|default(statuscake_port)|default(omit,true) }}" + post_body: "{{ item['post_body']|default(statuscake_post_body) }}" + post_raw: "{{ item['post_raw']|default(statuscake_post_raw) }}" + regions: "{{ item['regions']|default(statuscake_regions) }}" + state: "{{ item['state'] | default(statuscake_state) }}" + status_codes: "{{ item['status_codes']|default(statuscake_status_codes)|default(omit,true) }}" + tags: "{{ item['tags'] | default(statuscake_tags) | default(statuscake_) }}" + test_type: "{{ item['test_type']|default(statuscake_test_type) }}" + timeout: "{{ item['timeout']|default(statuscake_timeout)|default(omit,true) }}" + trigger_rate: "{{ item['trigger_rate']|default(statuscake_trigger_rate)|default(omit,true) }}" + use_jar: "{{ item['use_jar']|default(statuscake_use_jar) }}" + user_agent: "{{ item['user_agent']|default(statuscake_user_agent) }}" + when: "'uptime' in item['test_types'] | default(statuscake_test_types)" + loop: "{{ statuscake_tests }}" loop_control: - label: "{{ item['name'] }}" + label: "{{ item['website_url'] }}" -- name: Clean up StatusCake variables - set_fact: - statuscake_merged_uptime_tests: [] +- name: Configure ssl tests + tags: ssl + caktus.hosting_services.statuscake_ssl_test: + api_key: "{{ statuscake_api_key }}" + state: "{{ item['state'] | default(statuscake_ssl_state) }}" + website_url: "{{ item['website_url'] }}" + check_rate: "{{ item['check_rate']|default(statuscake_ssl_check_rate) }}" + contact_groups: "{{ item['contact_groups']|default(statuscake_ssl_contact_groups) }}" + alert_at: "{{ item['alert_at']|default(statuscake_ssl_alert_at) }}" + alert_reminder: "{{ item['alert_reminder']|default(statuscake_ssl_alert_reminder) }}" + alert_expiry: "{{ item['alert_expiry']|default(statuscake_ssl_alert_expiry) }}" + alert_broken: "{{ item['alert_broken']|default(statuscake_ssl_alert_broken) }}" + alert_mixed: "{{ item['alert_mixed']|default(statuscake_ssl_alert_mixed) }}" + follow_redirects: "{{ item['follow_redirects']|default(statuscake_ssl_follow_redirects) }}" + paused: "{{ item['paused']|default(statuscake_ssl_paused) }}" + hostname: "{{ item['hostname']|default(statuscake_ssl_hostname) }}" + user_agent: "{{ item['user_agent']|default(statuscake_ssl_user_agent) }}" + log_file: "{{ item['log_file']|default(statuscake_ssl_log_file) }}" + when: "'ssl' in item['test_types'] | default(statuscake_test_types)" + loop: "{{ statuscake_tests }}" + loop_control: + label: "{{ item['website_url'] }}"