diff --git a/index.json b/index.json index 90a240e..cc50279 100644 --- a/index.json +++ b/index.json @@ -1,5 +1,5 @@ { - "lastChange": 1738674136, + "lastChange": 1738677385, "templates": [ "/templates/aws-ec2.ec2-restart/template.json", "/templates/aws-ecs.scale-cpu-stress/template.json", @@ -7,6 +7,8 @@ "/templates/aws-zone.zone-outage/template.json", "/templates/caching-redis.redis-high-latency-datadog-check/template.json", "/templates/caching-redis.redis-unavailable-datadog-check/template.json", + "/templates/certificate-expiry.host/template.json", + "/templates/certificate-expiry.kubernetes-deployment/template.json", "/templates/cloud.zone-outage/template.json", "/templates/cloud.zone-outgoing-traffic-loss/template.json", "/templates/datadog.monitor-alerts-on-pod-crash-loop/template.json", diff --git a/templates/certificate-expiry.host/description.yml b/templates/certificate-expiry.host/description.yml new file mode 100644 index 0000000..0670fc3 --- /dev/null +++ b/templates/certificate-expiry.host/description.yml @@ -0,0 +1,5 @@ +license: MIT +gitHub: + owner: steadybit + repository: reliability-hub-db/tree/main/templates/certificate-expiry.host +maintainer: com.steadybit diff --git a/templates/certificate-expiry.host/template.json b/templates/certificate-expiry.host/template.json new file mode 100644 index 0000000..1353dd4 --- /dev/null +++ b/templates/certificate-expiry.host/template.json @@ -0,0 +1,122 @@ +{ + "id": "19c0d7ae-c3a7-44ba-9892-1dff8f665deb", + "templateTitle": "Certificate TLS/SSL expiry", + "templateDescription": "Turn time forward and check whether your TLS/SSL certificates are valid.\n\n## Motivation\n\nNoticing the TLS/SSL certification expiry too late is one problem you can easily avoid by frequently checking your expiry dates. While observability tools already handle this job nicely, you can't know whether they are working in your environment.\nWith this experiment, you can turn the time forward to check whether your HTTPS endpoint works at a given date in the future. Additionally, you can configure one of the [observability integrations](https://hub.steadybit.com/extensions?tags=Observability) to validate your observability tool's alerting.\n\n## Structure\nFirst, we validate that the given HTTPS endpoint is working today. Next, we will travel with the host in time to validate that the HTTPS endpoint continues to work on a given date. If the TLS/SSL certificate has already expired at that date, the HTTP check will throw failures.\n\n## Warning\nPlease be aware that we will manipulate the time for a given host. Applications running at that host may struggle to deal with the change in the clock correctly, and you may experience other side effects.", + "placeholders": [ + { + "key": "httpEndpoint", + "name": "Secured HTTP Endpoint", + "description": "### What is the secured HTTP endpoint URL that should still work in the future?\nThe HTTP endpoint should be secured with an SSL certificate to validate the certificate expiry.\nWe will perform requests before and while changing a host's time to validate that this endpoint works fine today and in the future and that the SSL certificate hasn't expired." + }, + { + "key": "hostname", + "name": "Host Providing HTTP Endpoint", + "description": "### What is the hostname of the host providing the secured HTTP endpoint?" + }, + { + "key": "expiration", + "name": "Expiration", + "description": "### Which time frame in the future would you like to validate the certificate's expiration date?\nWe'll use a time travel attack to turn time forward the given duration and check whether the TLS certificate is still valid." + } + ], + "tags": [ + "Certificate Expiry" + ], + "experimentName": "TLS/SSL Certificate doesn't expire within next [[expiration]] for [[hostname]]", + "hypothesis": "When a host's time is +[[expiration]], the secured HTTP endpoint still works and no certificates are expired.", + "lanes": [ + { + "steps": [ + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "headers": [], + "method": "GET", + "successRate": 100, + "maxConcurrent": 5, + "responseTime": "500ms", + "requestsPerSecond": 10, + "url": "[[httpEndpoint]]", + "duration": "10s", + "followRedirects": false, + "readTimeout": "5s", + "connectTimeout": "5s", + "responseTimeMode": "NO_VERIFICATION", + "statusCode": "200-299" + }, + "customLabel": "GIVEN: HTTP requests are valid for today", + "actionType": "com.steadybit.extension_http.check.periodically", + "radius": { + "targetType": "com.steadybit.extension_http.client-location", + "maximum": 1 + } + }, + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "headers": [], + "method": "GET", + "successRate": 100, + "maxConcurrent": 5, + "responseTime": "500ms", + "requestsPerSecond": 10, + "url": "[[httpEndpoint]]", + "duration": "60s", + "followRedirects": false, + "readTimeout": "5s", + "connectTimeout": "5s", + "responseTimeMode": "NO_VERIFICATION", + "statusCode": "200-299" + }, + "customLabel": "THEN: HTTP requests continue to be valid in +[[expiration]]", + "actionType": "com.steadybit.extension_http.check.periodically", + "radius": { + "targetType": "com.steadybit.extension_http.client-location", + "maximum": 1 + } + } + ] + }, + { + "steps": [ + { + "type": "wait", + "ignoreFailure": false, + "parameters": { + "duration": "10s" + } + }, + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "offset": "[[expiration]]", + "duration": "60s", + "disableNtp": true + }, + "customLabel": "WHEN: Host's time is +[[expiration]]", + "actionType": "com.steadybit.extension_host.timetravel", + "radius": { + "targetType": "com.steadybit.extension_host.host", + "predicate": { + "operator": "AND", + "predicates": [ + { + "key": "host.hostname", + "operator": "EQUALS", + "values": [ + "[[hostname]]" + ] + } + ] + }, + "query": null, + "percentage": 100 + } + } + ] + } + ] +} \ No newline at end of file diff --git a/templates/certificate-expiry.kubernetes-deployment/description.yml b/templates/certificate-expiry.kubernetes-deployment/description.yml new file mode 100644 index 0000000..8f7a06a --- /dev/null +++ b/templates/certificate-expiry.kubernetes-deployment/description.yml @@ -0,0 +1,5 @@ +license: MIT +gitHub: + owner: steadybit + repository: reliability-hub-db/tree/main/templates/certificate-expiry.kubernetes-deployment +maintainer: com.steadybit diff --git a/templates/certificate-expiry.kubernetes-deployment/template.json b/templates/certificate-expiry.kubernetes-deployment/template.json new file mode 100644 index 0000000..177f314 --- /dev/null +++ b/templates/certificate-expiry.kubernetes-deployment/template.json @@ -0,0 +1,179 @@ +{ + "id": "019127d4-37a9-7e33-86ef-f25f8da9f4eb", + "templateTitle": "Certificate TLS/SSL expiry for Kubernetes deployment", + "templateDescription": "Turn time forward and check whether your TLS/SSL certificates are valid.\n\n## Motivation\n\nNoticing the TLS/SSL certification expiry too late is one problem you can easily avoid by frequently checking your expiry dates. While observability tools already handle this job nicely, you can't know whether they are working in your environment.\nWith this experiment, you can turn the time forward to check whether your HTTPS endpoint works at a given date in the future. Additionally, you can configure one of the [observability integrations](https://hub.steadybit.com/extensions?tags=Observability) to validate your observability tool's alerting.\n\n## Structure\nFirst, we validate that the given HTTPS endpoint is working today. Next, we will travel with the host in time to validate that the HTTPS endpoint continues to work on a given date. If the TLS/SSL certificate has already expired at that date, the HTTP check will throw failures.\n\n## Warning\nPlease be aware that we will manipulate the time for a given Kubernetes node. Containers running at that host may struggle to deal with the change in the clock correctly, and you may experience other side effects.", + "placeholders": [ + { + "key": "httpEndpoint", + "name": "Secured HTTP Endpoint", + "description": "### What is the secured HTTP endpoint URL that should still work in the future?\nThe HTTP endpoint should be secured with an SSL certificate to validate the certificate expiry.\nWe will perform requests before and while changing a host's time to validate that this endpoint works fine today and in the future and that the SSL certificate hasn't expired." + }, + { + "key": "k8sClusterName", + "name": "Kubernetes Cluster Name", + "description": "### What is the Kubernetes cluster in which the deployment providing the HTTP endpoint runs?" + }, + { + "key": "k8sNamespace", + "name": "Kubernetes Namespace", + "description": "### What is the Kubernetes namespace in which the deployment providing the HTTP endpoint runs?" + }, + { + "key": "k8sDeployment", + "name": "Kubernetes Deployment", + "description": "### What is the Kubernetes deployment providing the secured HTTP endpoint?" + }, + { + "key": "expiration", + "name": "Expiration", + "description": "### Which time frame in the future would you like to validate the certificate's expiration date?\nWe'll use a time travel attack to turn time forward the given duration and check whether the TLS certificate is still valid." + } + ], + "tags": [ + "Certificate Expiry" + ], + "experimentName": "TLS/SSL Certificate doesn't expire within next [[expiration]] for [[k8sDeployment]]", + "hypothesis": "When a host's time is +[[expiration]] days, the secured HTTP endpoint still works and no certificates are expired.", + "lanes": [ + { + "steps": [ + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "headers": [], + "method": "GET", + "successRate": 100, + "maxConcurrent": 5, + "responseTime": "500ms", + "requestsPerSecond": 10, + "url": "[[httpEndpoint]]", + "duration": "10s", + "followRedirects": false, + "readTimeout": "5s", + "connectTimeout": "5s", + "responseTimeMode": "NO_VERIFICATION", + "statusCode": "200-299" + }, + "customLabel": "GIVEN: HTTP requests are valid for today", + "actionType": "com.steadybit.extension_http.check.periodically", + "radius": { + "targetType": "com.steadybit.extension_http.client-location", + "maximum": 1 + } + }, + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "headers": [], + "method": "GET", + "successRate": 100, + "maxConcurrent": 5, + "responseTime": "500ms", + "requestsPerSecond": 10, + "url": "[[httpEndpoint]]", + "duration": "60s", + "followRedirects": false, + "readTimeout": "5s", + "connectTimeout": "5s", + "responseTimeMode": "NO_VERIFICATION", + "statusCode": "200-299" + }, + "customLabel": "THEN: HTTP requests continue to be valid in +[[expiration]] days", + "actionType": "com.steadybit.extension_http.check.periodically", + "radius": { + "targetType": "com.steadybit.extension_http.client-location", + "maximum": 1 + } + } + ] + }, + { + "steps": [ + { + "type": "wait", + "ignoreFailure": false, + "parameters": { + "duration": "10s" + } + }, + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "offset": "[[expiration]]", + "duration": "60s", + "disableNtp": true + }, + "customLabel": "WHEN: Host's time is +[[expiration]] days", + "actionType": "com.steadybit.extension_host.timetravel", + "radius": { + "targetType": "com.steadybit.extension_host.host", + "predicate": { + "query": "(k8s.cluster-name=\"[[k8sClusterName]]\" AND k8s.namespace=\"[[k8sNamespace]]\" AND k8s.deployment=\"[[k8sDeployment]]\")" + }, + "query": "(k8s.cluster-name=\"[[k8sClusterName]]\" AND k8s.namespace=\"[[k8sNamespace]]\" AND k8s.deployment=\"[[k8sDeployment]]\")", + "percentage": 100 + } + } + ] + }, + { + "steps": [ + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "duration": "70s" + }, + "actionType": "com.steadybit.extension_kubernetes.kubernetes_logs", + "radius": { + "targetType": "com.steadybit.extension_kubernetes.kubernetes-cluster", + "predicate": { + "operator": "AND", + "predicates": [ + { + "key": "k8s.cluster-name", + "operator": "EQUALS", + "values": [ + "[[k8sClusterName]]" + ] + } + ] + }, + "query": null + } + } + ] + }, + { + "steps": [ + { + "type": "action", + "ignoreFailure": false, + "parameters": { + "duration": "70s" + }, + "actionType": "com.steadybit.extension_kubernetes.pod_count_metric", + "radius": { + "targetType": "com.steadybit.extension_kubernetes.kubernetes-cluster", + "predicate": { + "operator": "AND", + "predicates": [ + { + "key": "k8s.cluster-name", + "operator": "EQUALS", + "values": [ + "[[k8sClusterName]]" + ] + } + ] + }, + "query": null + } + } + ] + } + ] +} \ No newline at end of file