Browse Source

Merge pull request #3822 from codificat/cronjob-example

Merged by openshift-bot
OpenShift Bot 8 years ago
parent
commit
75e79b3f87

+ 3 - 1
README_CONTAINER_IMAGE.md

@@ -38,4 +38,6 @@ Here is an example of how to run a containerized `openshift-ansible` playbook th
            -e PLAYBOOK_FILE=playbooks/certificate_expiry/default.yaml \
            openshift/openshift-ansible
 
-The [playbook2image examples](https://github.com/aweiteka/playbook2image/tree/master/examples) provide additional information on how to use an image built from it like this one.
+Further usage examples are available in the [examples directory](examples/).
+
+Additional usage information for images built from `playbook2image` like this one can be found in the [playbook2image examples](https://github.com/aweiteka/playbook2image/tree/master/examples).

+ 93 - 0
examples/README.md

@@ -0,0 +1,93 @@
+# openshift-ansible usage examples
+
+The primary use of `openshift-ansible` is to install, configure and upgrade OpenShift clusters.
+
+This is typically done by direct invocation of Ansible tools like `ansible-playbook`. This use case is covered in detail in the [OpenShift advanced installation documentation](https://docs.openshift.org/latest/install_config/install/advanced_install.html)
+
+For OpenShift Container Platform there's also an installation utility that wraps `openshift-ansible`. This usage case is covered in the [Quick Installation](https://docs.openshift.com/container-platform/latest/install_config/install/quick_install.html) section of the documentation.
+
+The usage examples below cover use cases other than install/configure/upgrade.
+
+## Container image
+
+The examples below run [openshift-ansible in a container](../README_CONTAINER_IMAGE.md) to perform certificate expiration checks on an OpenShift cluster from pods running on the cluster itself.
+
+You can find more details about the certificate expiration check roles and example playbooks in [the openshift_certificate_expiry role's README](../roles/openshift_certificate_expiry/README.md).
+
+### Job to upload certificate expiration reports
+
+The example `Job` in [certificate-check-upload.yaml](certificate-check-upload.yaml) executes a [Job](https://docs.openshift.org/latest/dev_guide/jobs.html) that checks the expiration dates of the internal certificates of the cluster and uploads HTML and JSON reports to `/etc/origin/certificate_expiration_report` in the masters.
+
+This example uses the [`easy-mode-upload.yaml`](../playbooks/certificate_expiry/easy-mode-upload.yaml) example playbook, which generates reports and uploads them to the masters. The playbook can be customized via environment variables to control the length of the warning period (`CERT_EXPIRY_WARN_DAYS`) and the location in the masters where the reports are uploaded (`COPY_TO_PATH`).
+
+The job expects the inventory to be provided via the *hosts* key of a [ConfigMap](https://docs.openshift.org/latest/dev_guide/configmaps.html) named *inventory*, and the passwordless ssh key that allows connecting to the hosts to be availalbe as *ssh-privatekey* from a [Secret](https://docs.openshift.org/latest/dev_guide/secrets.html) named *sshkey*, so these are created first:
+
+    oc new-project certcheck
+    oc create configmap inventory --from-file=hosts=/etc/ansible/hosts
+    oc secrets new-sshauth sshkey --ssh-privatekey=$HOME/.ssh/id_rsa
+
+Note that `inventory`, `hosts`, `sshkey` and `ssh-privatekey` are referenced by name from the provided example Job definition. If you use different names for the objects/attributes you will have to adjust the Job accordingly.
+
+To create the Job:
+
+    oc create -f examples/certificate-check-upload.yaml
+
+### Scheduled job for certificate expiration report upload
+
+**Note**: This example uses the [ScheduledJob](https://docs.openshift.com/container-platform/3.4/dev_guide/scheduled_jobs.html) object, which has been renamed to [CronJob](https://docs.openshift.org/latest/dev_guide/cron_jobs.html) upstream and is still a Technology Preview subject to further change.
+
+The example `ScheduledJob` in [scheduled-certcheck-upload.yaml](scheduled-certcheck-upload.yaml) does the same as the `Job` example above, but it is scheduled to automatically run every first day of the month (see the `spec.schedule` value in the example).
+
+The job definition is the same and it expects the same configuration: we provide the inventory and ssh key via a ConfigMap and a Secret respectively:
+
+    oc new-project certcheck
+    oc create configmap inventory --from-file=hosts=/etc/ansible/hosts
+    oc secrets new-sshauth sshkey --ssh-privatekey=$HOME/.ssh/id_rsa
+
+And then we create the ScheduledJob:
+
+    oc create -f examples/scheduled-certcheck-upload.yaml
+
+### Job and ScheduledJob to check certificates using volumes
+
+There are two additional examples:
+
+ - A `Job` [certificate-check-volume.yaml](certificate-check-volume.yaml)
+ - A `ScheduledJob` [scheduled-certcheck-upload.yaml](scheduled-certcheck-upload.yaml)
+
+These perform the same work as the two examples above, but instead of uploading the generated reports to the masters they store them in a custom path within the container that is expected to be backed by a [PersistentVolumeClaim](https://docs.openshift.org/latest/dev_guide/persistent_volumes.html), so that the reports are actually written to storage external to the container.
+
+These examples assume that there is an existing `PersistentVolumeClaim` called `certcheck-reports` and they use the  [`html_and_json_timestamp.yaml`](../playbooks/certificate_expiry/html_and_json_timestamp.yaml) example playbook to write timestamped reports into it.
+
+You can later access the reports from another pod that mounts the same volume, or externally via direct access to the backend storage behind the matching `PersistentVolume`.
+
+To run these examples we prepare the inventory and ssh keys as in the other examples:
+
+    oc new-project certcheck
+    oc create configmap inventory --from-file=hosts=/etc/ansible/hosts
+    oc secrets new-sshauth sshkey --ssh-privatekey=$HOME/.ssh/id_rsa
+
+Additionally we allocate a `PersistentVolumeClaim` to store the reports:
+
+	oc create -f - <<PVC
+	---
+	apiVersion: v1
+	kind: PersistentVolumeClaim
+	metadata:
+	  name: certcheck-reports
+	spec:
+	  accessModes:
+		- ReadWriteOnce
+	  resources:
+		requests:
+		  storage: 1Gi
+	PVC
+
+With that we can run the `Job` once:
+
+    oc create -f examples/certificate-check-volume.yaml
+
+or schedule it to run periodically as a `ScheduledJob`:
+
+    oc create -f examples/scheduled-certcheck-volume.yaml
+

+ 47 - 0
examples/certificate-check-upload.yaml

@@ -0,0 +1,47 @@
+# An example Job to run a certificate check of OpenShift's internal
+# certificate status from within OpenShift.
+#
+# The generated reports are uploaded to a location in the master
+# hosts, using the playbook 'easy-mode-upload.yaml'.
+#
+# This example uses the openshift/openshift-ansible container image.
+# (see README_CONTAINER_IMAGE.md in the top level dir for more details).
+#
+# The following objects are xpected to be configured before the creation
+# of this Job:
+#   - A ConfigMap named 'inventory' with a key named 'hosts' that
+#     contains the the Ansible inventory file
+#   - A Secret named 'sshkey' with a key named 'ssh-privatekey
+#     that contains the ssh key to connect to the hosts
+# (see examples/README.md for more details)
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: certificate-check
+spec:
+  containers:
+  - name: openshift-ansible
+    image: openshift/openshift-ansible
+    env:
+    - name: PLAYBOOK_FILE
+      value: playbooks/certificate_expiry/easy-mode-upload.yaml
+    - name: INVENTORY_FILE
+      value: /tmp/inventory/hosts       # from configmap vol below
+    - name: ANSIBLE_PRIVATE_KEY_FILE    # from secret vol below
+      value: /opt/app-root/src/.ssh/id_rsa/ssh-privatekey
+    - name: CERT_EXPIRY_WARN_DAYS
+      value: "45"      # must be a string, don't forget the quotes
+    volumeMounts:
+    - name: sshkey
+      mountPath: /opt/app-root/src/.ssh/id_rsa
+    - name: inventory
+      mountPath: /tmp/inventory
+  volumes:
+  - name: sshkey
+    secret:
+      secretName: sshkey
+  - name: inventory
+    configMap:
+      name: inventory
+  restartPolicy: Never

+ 54 - 0
examples/certificate-check-volume.yaml

@@ -0,0 +1,54 @@
+# An example Job to run a certificate check of OpenShift's internal
+# certificate status from within OpenShift.
+#
+# The generated reports are stored in a Persistent Volume using
+# the playbook 'html_and_json_timestamp.yaml'.
+#
+# This example uses the openshift/openshift-ansible container image.
+# (see README_CONTAINER_IMAGE.md in the top level dir for more details).
+#
+# The following objects are xpected to be configured before the creation
+# of this Job:
+#   - A ConfigMap named 'inventory' with a key named 'hosts' that
+#     contains the the Ansible inventory file
+#   - A Secret named 'sshkey' with a key named 'ssh-privatekey
+#     that contains the ssh key to connect to the hosts
+#   - A PersistentVolumeClaim named 'certcheck-reports' where the
+#     generated reports are going to be stored
+# (see examples/README.md for more details)
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: certificate-check
+spec:
+  containers:
+  - name: openshift-ansible
+    image: openshift/openshift-ansible
+    env:
+    - name: PLAYBOOK_FILE
+      value: playbooks/certificate_expiry/html_and_json_timestamp.yaml
+    - name: INVENTORY_FILE
+      value: /tmp/inventory/hosts       # from configmap vol below
+    - name: ANSIBLE_PRIVATE_KEY_FILE    # from secret vol below
+      value: /opt/app-root/src/.ssh/id_rsa/ssh-privatekey
+    - name: CERT_EXPIRY_WARN_DAYS
+      value: "45"      # must be a string, don't forget the quotes
+    volumeMounts:
+    - name: sshkey
+      mountPath: /opt/app-root/src/.ssh/id_rsa
+    - name: inventory
+      mountPath: /tmp/inventory
+    - name: reports
+      mountPath: /var/lib/certcheck
+  volumes:
+  - name: sshkey
+    secret:
+      secretName: sshkey
+  - name: inventory
+    configMap:
+      name: inventory
+  - name: reports
+    persistentVolumeClaim:
+      claimName: certcheck-reports
+  restartPolicy: Never

+ 53 - 0
examples/scheduled-certcheck-upload.yaml

@@ -0,0 +1,53 @@
+# An example ScheduledJob to run a regular check of OpenShift's internal
+# certificate status.
+#
+# Each job will upload new reports to a directory in the master hosts
+#
+# The Job specification is the same as 'certificate-check-upload.yaml'
+# and the expected pre-configuration is equivalent.
+# See that Job example and examples/README.md for more details.
+#
+# NOTE: ScheduledJob has been renamed to CronJob in upstream k8s recently. At
+# some point (OpenShift 3.6+) this will have to be renamed to "kind: CronJob"
+# and once the API stabilizes the apiVersion will have to be updated too.
+---
+apiVersion: batch/v2alpha1
+kind: ScheduledJob
+metadata:
+  name: certificate-check
+  labels:
+    app: certcheck
+spec:
+  schedule: "0 0 1 * *"      # every 1st day of the month at midnight
+  jobTemplate:
+    metadata:
+      labels:
+        app: certcheck
+    spec:
+      template:
+        spec:
+          containers:
+          - name: openshift-ansible
+            image: openshift/openshift-ansible
+            env:
+            - name: PLAYBOOK_FILE
+              value: playbooks/certificate_expiry/easy-mode-upload.yaml
+            - name: INVENTORY_FILE
+              value: /tmp/inventory/hosts       # from configmap vol below
+            - name: ANSIBLE_PRIVATE_KEY_FILE    # from secret vol below
+              value: /opt/app-root/src/.ssh/id_rsa/ssh-privatekey
+            - name: CERT_EXPIRY_WARN_DAYS
+              value: "45"      # must be a string, don't forget the quotes
+            volumeMounts:
+            - name: sshkey
+              mountPath: /opt/app-root/src/.ssh/id_rsa
+            - name: inventory
+              mountPath: /tmp/inventory
+          volumes:
+          - name: sshkey
+            secret:
+              secretName: sshkey
+          - name: inventory
+            configMap:
+              name: inventory
+          restartPolicy: Never

+ 58 - 0
examples/scheduled-certcheck-volume.yaml

@@ -0,0 +1,58 @@
+# An example ScheduledJob to run a regular check of OpenShift's internal
+# certificate status.
+#
+# Each job will add a new pair of reports to the configured Persistent Volume
+#
+# The Job specification is the same as 'certificate-check-volume.yaml'
+# and the expected pre-configuration is equivalent.
+# See that Job example and examples/README.md for more details.
+#
+# NOTE: ScheduledJob has been renamed to CronJob in upstream k8s recently. At
+# some point (OpenShift 3.6+) this will have to be renamed to "kind: CronJob"
+# and once the API stabilizes the apiVersion will have to be updated too.
+---
+apiVersion: batch/v2alpha1
+kind: ScheduledJob
+metadata:
+  name: certificate-check
+  labels:
+    app: certcheck
+spec:
+  schedule: "0 0 1 * *"      # every 1st day of the month at midnight
+  jobTemplate:
+    metadata:
+      labels:
+        app: certcheck
+    spec:
+      template:
+        spec:
+          containers:
+          - name: openshift-ansible
+            image: openshift/openshift-ansible
+            env:
+            - name: PLAYBOOK_FILE
+              value: playbooks/certificate_expiry/html_and_json_timestamp.yaml
+            - name: INVENTORY_FILE
+              value: /tmp/inventory/hosts       # from configmap vol below
+            - name: ANSIBLE_PRIVATE_KEY_FILE    # from secret vol below
+              value: /opt/app-root/src/.ssh/id_rsa/ssh-privatekey
+            - name: CERT_EXPIRY_WARN_DAYS
+              value: "45"      # must be a string, don't forget the quotes
+            volumeMounts:
+            - name: sshkey
+              mountPath: /opt/app-root/src/.ssh/id_rsa
+            - name: inventory
+              mountPath: /tmp/inventory
+            - name: reports
+              mountPath: /var/lib/certcheck
+          volumes:
+          - name: sshkey
+            secret:
+              secretName: sshkey
+          - name: inventory
+            configMap:
+              name: inventory
+          - name: reports
+            persistentVolumeClaim:
+              claimName: certcheck-reports
+          restartPolicy: Never

+ 40 - 0
playbooks/certificate_expiry/easy-mode-upload.yaml

@@ -0,0 +1,40 @@
+# This example generates HTML and JSON reports and
+#
+# Copies of the generated HTML and JSON reports are uploaded to the masters,
+# which is particularly useful when this playbook is run from a container.
+#
+# All certificates (healthy or not) are included in the results
+#
+# Optional environment variables to alter the behaviour of the playbook:
+# CERT_EXPIRY_WARN_DAYS:  Length of the warning window in days (45)
+# COPY_TO_PATH: path to copy reports to in the masters (/etc/origin/certificate_expiration_report)
+---
+- name: Generate certificate expiration reports
+  hosts: nodes:masters:etcd
+  gather_facts: no
+  vars:
+    openshift_certificate_expiry_save_json_results: yes
+    openshift_certificate_expiry_generate_html_report: yes
+    openshift_certificate_expiry_show_all: yes
+    openshift_certificate_expiry_warning_days: "{{ lookup('env', 'CERT_EXPIRY_WARN_DAYS') | default('45', true) }}"
+  roles:
+    - role: openshift_certificate_expiry
+
+- name: Upload reports to master
+  hosts: masters
+  gather_facts: no
+  vars:
+    destination_path: "{{ lookup('env', 'COPY_TO_PATH') | default('/etc/origin/certificate_expiration_report', true) }}"
+    timestamp: "{{ lookup('pipe', 'date +%Y%m%d') }}"
+  tasks:
+    - name: Ensure that the target directory exists
+      file:
+        path: "{{ destination_path }}"
+        state: directory
+    - name: Copy the reports
+      copy:
+        dest: "{{ destination_path }}/{{ timestamp }}-{{ item }}"
+        src: "/tmp/{{ item }}"
+      with_items:
+        - "cert-expiry-report.html"
+        - "cert-expiry-report.json"

+ 16 - 0
playbooks/certificate_expiry/html_and_json_timestamp.yaml

@@ -0,0 +1,16 @@
+---
+# Generate timestamped HTML and JSON reports in /var/lib/certcheck
+
+- name: Check cert expirys
+  hosts: nodes:masters:etcd
+  become: yes
+  gather_facts: no
+  vars:
+    openshift_certificate_expiry_generate_html_report: yes
+    openshift_certificate_expiry_save_json_results: yes
+    openshift_certificate_expiry_show_all: yes
+    timestamp: "{{ lookup('pipe', 'date +%Y%m%d') }}"
+    openshift_certificate_expiry_html_report_path: "/var/lib/certcheck/{{ timestamp }}-cert-expiry-report.html"
+    openshift_certificate_expiry_json_results_path: "/var/lib/certcheck/{{ timestamp }}-cert-expiry-report.json"
+  roles:
+    - role: openshift_certificate_expiry

+ 117 - 16
roles/openshift_certificate_expiry/README.md

@@ -19,7 +19,6 @@ to be used with an inventory that is representative of the
 cluster. For best results run `ansible-playbook` with the `-v` option.
 
 
-
 # Role Variables
 
 Core variables in this role:
@@ -51,8 +50,8 @@ How to use the Certificate Expiration Checking Role.
 
 Run one of the example playbooks using an inventory file
 representative of your existing cluster. Some example playbooks are
-included in this role, or you can read on below after this example to
-craft you own.
+included in this role, or you can [read on below for more examples](#more-example-playbooks)
+to help you craft you own.
 
 ```
 $ ansible-playbook -v -i HOSTS playbooks/certificate_expiry/easy-mode.yaml
@@ -69,11 +68,47 @@ Using the `easy-mode.yaml` playbook will produce:
 > `/usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/easy-mode.yaml`
 > instead
 
+## Run from a container
+
+The example playbooks that use this role are packaged in the
+[container image for openshift-ansible](../../README_CONTAINER_IMAGE.md), so you
+can run any of them by setting the `PLAYBOOK_FILE` environment variable when
+running an openshift-ansible container.
+
+There are several [examples](../../examples/README.md) in the `examples` directory that run certificate check playbooks from a container running on OpenShift.
+
 ## More Example Playbooks
 
 > **Note:** These Playbooks are available to run directly out of the
 > [/playbooks/certificate_expiry/](../../playbooks/certificate_expiry/) directory.
 
+### Default behavior
+
+This playbook just invokes the certificate expiration check role with default options:
+
+
+```yaml
+---
+- name: Check cert expirys
+  hosts: nodes:masters:etcd
+  become: yes
+  gather_facts: no
+  roles:
+    - role: openshift_certificate_expiry
+```
+
+**From git:**
+```
+$ ansible-playbook -v -i HOSTS playbooks/certificate_expiry/default.yaml
+```
+**From openshift-ansible-playbooks rpm:**
+```
+$ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/default.yaml
+```
+
+> [View This Playbook](../../playbooks/certificate_expiry/default.yaml)
+
+### Easy mode
 
 This example playbook is great if you're just wanting to **try the
 role out**. This playbook enables HTML and JSON reports. All
@@ -104,35 +139,70 @@ $ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/ce
 
 > [View This Playbook](../../playbooks/certificate_expiry/easy-mode.yaml)
 
-***
+### Easy mode and upload reports to masters
+
+This example builds on top of [easy-mode.yaml](#easy-mode) and additionally
+uploads a copy of the generated reports to the masters, with a timestamp in the
+file names.
+
+This is specially useful when the playbook runs from within a container, because
+the reports are generated inside the container and we need a way to access them.
+Uploading a copy of the reports to the masters is one way to make it easy to
+access them. Alternatively you can use the
+[role variables](#role-variables) that control the path of the generated reports
+to point to a container volume (see the [playbook with custom paths](#generate-html-and-json-reports-in-a-custom-path) for an example).
 
-Default behavior:
+With the container use case in mind, this playbook allows control over some
+options via environment variables:
+
+ - `CERT_EXPIRY_WARN_DAYS`: sets `openshift_certificate_expiry_warning_days`, overriding the role's default.
+ - `COPY_TO_PATH`: path in the masters where generated reports are uploaded.
 
 ```yaml
 ---
-- name: Check cert expirys
+- name: Generate certificate expiration reports
   hosts: nodes:masters:etcd
-  become: yes
   gather_facts: no
+  vars:
+    openshift_certificate_expiry_save_json_results: yes
+    openshift_certificate_expiry_generate_html_report: yes
+    openshift_certificate_expiry_show_all: yes
+    openshift_certificate_expiry_warning_days: "{{ lookup('env', 'CERT_EXPIRY_WARN_DAYS') | default('45', true) }}"
   roles:
     - role: openshift_certificate_expiry
+
+- name: Upload reports to master
+  hosts: masters
+  gather_facts: no
+  vars:
+    destination_path: "{{ lookup('env', 'COPY_TO_PATH') | default('/etc/origin/certificate_expiration_report', true) }}"
+    timestamp: "{{ lookup('pipe', 'date +%Y%m%d') }}"
+  tasks:
+    - name: Create directory in masters
+      file:
+        path: "{{ destination_path }}"
+        state: directory
+    - name: Copy the reports to the masters
+      copy:
+        dest: "{{ destination_path }}/{{ timestamp }}-{{ item }}"
+        src: "/tmp/{{ item }}"
+      with_items:
+        - "cert-expiry-report.html"
+        - "cert-expiry-report.json"
 ```
 
 **From git:**
 ```
-$ ansible-playbook -v -i HOSTS playbooks/certificate_expiry/default.yaml
+$ ansible-playbook -v -i HOSTS playbooks/certificate_expiry/easy-mode-upload.yaml
 ```
 **From openshift-ansible-playbooks rpm:**
 ```
-$ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/default.yaml
+$ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/easy-mode-upload.yaml
 ```
 
-> [View This Playbook](../../playbooks/certificate_expiry/default.yaml)
+> [View This Playbook](../../playbooks/certificate_expiry/easy-mode-upload.yaml)
 
-***
-
-
-Generate HTML and JSON artifacts in their default paths:
+### Generate HTML and JSON artifacts in their default paths
 
 ```yaml
 ---
@@ -158,7 +228,38 @@ $ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/ce
 
 > [View This Playbook](../../playbooks/certificate_expiry/html_and_json_default_paths.yaml)
 
-***
+### Generate HTML and JSON reports in a custom path
+
+This example customizes the report generation path to point to a specific path (`/var/lib/certcheck`) and uses a date timestamp for the generated files. This allows you to reuse a certain location to keep multiple copies of the reports.
+
+```yaml
+---
+- name: Check cert expirys
+  hosts: nodes:masters:etcd
+  become: yes
+  gather_facts: no
+  vars:
+    openshift_certificate_expiry_generate_html_report: yes
+    openshift_certificate_expiry_save_json_results: yes
+    timestamp: "{{ lookup('pipe', 'date +%Y%m%d') }}"
+    openshift_certificate_expiry_html_report_path: "/var/lib/certcheck/{{ timestamp }}-cert-expiry-report.html"
+    openshift_certificate_expiry_json_results_path: "/var/lib/certcheck/{{ timestamp }}-cert-expiry-report.json"
+  roles:
+    - role: openshift_certificate_expiry
+```
+
+**From git:**
+```
+$ ansible-playbook -v -i HOSTS playbooks/certificate_expiry/html_and_json_timestamp.yaml
+```
+**From openshift-ansible-playbooks rpm:**
+```
+$ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/html_and_json_timestamp.yaml
+```
+
+> [View This Playbook](../../playbooks/certificate_expiry/html_and_json_timestamp.yaml)
+
+### Long warning window
 
 Change the expiration warning window to 1500 days (good for testing
 the module out):
@@ -186,7 +287,7 @@ $ ansible-playbook -v -i HOSTS /usr/share/ansible/openshift-ansible/playbooks/ce
 
 > [View This Playbook](../../playbooks/certificate_expiry/longer_warning_period.yaml)
 
-***
+### Long warning window and JSON report
 
 Change the expiration warning window to 1500 days (good for testing
 the module out) and save the results as a JSON file: