Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest

## Tool Versions
KUSTOMIZE_VERSION ?= v3.8.7
CONTROLLER_TOOLS_VERSION ?= v0.9.0
CONTROLLER_TOOLS_VERSION ?= v0.14.0

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
Expand Down
12 changes: 12 additions & 0 deletions api/v1alpha1/endpointmonitor_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ type StatusCakeConfig struct {
// +optional
BasicAuthUser string `json:"basicAuthUser,omitempty"`

// Basic Auth Secret Name
// +optional
BasicAuthSecret string `json:"basicAuthSecret,omitempty"`

// Set Check Rate for the monitor
// +optional
CheckRate int `json:"checkRate,omitempty"`
Expand Down Expand Up @@ -224,6 +228,14 @@ type StatusCakeConfig struct {
// String to look for within the response. Considered down if not found
// +optional
FindString string `json:"findString,omitempty"`

// RawPostData can be used to send parameters within the URL. Changes the request from a GET to a POST
// +optional
RawPostData string `json:"rawPostData,omitempty"`

// UserAgent is used to set a user agent string.
// +optional
UserAgent string `json:"userAgent,omitempty"`
}

// PingdomConfig defines the configuration for Pingdom Monitor Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: endpointmonitors.endpointmonitor.stakater.com
spec:
group: endpointmonitor.stakater.com
Expand Down Expand Up @@ -255,6 +255,9 @@ spec:
statusCakeConfig:
description: Configuration for StatusCake Monitor Provider
properties:
basicAuthSecret:
description: Basic Auth Secret Name
type: string
basicAuthUser:
description: Basic Auth User
type: string
Expand Down Expand Up @@ -288,6 +291,10 @@ spec:
port:
description: TCP Port
type: integer
rawPostData:
description: RawPostData can be used to send parameters within
the URL. Changes the request from a GET to a POST
type: string
realBrowser:
description: Enable Real Browser
type: boolean
Expand All @@ -307,6 +314,9 @@ spec:
triggerRate:
description: Minutes to wait before sending an alert
type: integer
userAgent:
description: UserAgent is used to set a user agent string.
type: string
type: object
updownConfig:
description: Configuration for Updown Monitor Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
controller-gen.kubebuilder.io/version: v0.14.0
creationTimestamp: null
name: endpointmonitors.endpointmonitor.stakater.com
spec:
Expand Down Expand Up @@ -255,6 +255,9 @@ spec:
statusCakeConfig:
description: Configuration for StatusCake Monitor Provider
properties:
basicAuthSecret:
description: Basic Auth Secret Name
type: string
basicAuthUser:
description: Basic Auth User
type: string
Expand Down Expand Up @@ -288,6 +291,10 @@ spec:
port:
description: TCP Port
type: integer
rawPostData:
description: RawPostData can be used to send parameters within
the URL. Changes the request from a GET to a POST
type: string
realBrowser:
description: Enable Real Browser
type: boolean
Expand All @@ -307,6 +314,9 @@ spec:
triggerRate:
description: Minutes to wait before sending an alert
type: integer
userAgent:
description: UserAgent is used to set a user agent string.
type: string
type: object
updownConfig:
description: Configuration for Updown Monitor Provider
Expand Down
13 changes: 10 additions & 3 deletions docs/statuscake-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ Currently additional Statuscake configurations can be added through these fields
|:--------------------------------------------------------:|:------------------------------------------------:|
| CheckRate | Set Check Rate for the monitor (default: 300) |
| TestType | Set Test type - HTTP, TCP, PING (default: HTTP) |
| Paused | Pause the service |
| Paused | Pause the service |
| PingURL | Webhook for alerts |
| FollowRedirect | Enable ingress redirects |
| Port | TCP Port |
| Port | TCP Port |
| TriggerRate | Minutes to wait before sending an alert |
| ContactGroup | Contact Group to be alerted. |
| TestTags | Comma separated list of tags |
| FindString | String to look for within the response |
| BasicAuthUser | Required for [basic-authenticationchecks](#basic-auth-checks) |
| BasicAuthUser | Required for [basic-authenticationchecks](#basic-auth-checks) |
| BasicAuthSecret | Allows for an alternate method of adding basic-auth to checks |
| Regions | Regions to execute the check from |
| RawPostData | Add data to change the request to a POST |
| UserAgent | Add a user agent string to the request |


### Basic Auth checks
Expand All @@ -34,6 +37,10 @@ Statuscake supports checks completing basic auth requirements. In `EndpointMonit

For example; setting the field like `basic-auth-user: 'my-service-username'` will set the username field to the value `my-service-username` and will retrieve the password via `os.Getenv('my-service-username')` and set this appropriately.

In addition to the previous method, you can use the `basicAuthSecret` field to define a secret that should be read by the monitor which contains the basic-auth data. This secret should only contain the keys `username` and `password`. It expects the values for those keys to be strings. NOT base64 encoded strings. Furthermore, the secret must be present in the same namespace as the IngressMonitorController operator. This ensures that we can keep the permissions of the operator to be as small as possible.

So for example, if you have a secret called `my-deployment-secret` it should contain the data `username: my-user` and `password: MyPassword1!` and you should set to `basicAuthSecret: my-deployment-secret`. This will ensure that the monitor can read the basic-auth data correctly.

## Example:

```yaml
Expand Down
3 changes: 3 additions & 0 deletions examples/endpointMonitor/statuscake-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ spec:
statusCakeConfig:
port: 123
basicAuthUser: my-service-username
basicAuthSecret: my-basicauth-secret
checkRate: 300
realBrowser: true
testTags: 'abc,def'
Expand All @@ -20,4 +21,6 @@ spec:
pingUrl: 'https://stakater2.com/'
contactGroup: '123456,654321'
regions: amsterdam, stockholm
rawPostData: '{"test": "data"}'
userAgent: test-user
url: 'https://stakater1.com/'
26 changes: 26 additions & 0 deletions pkg/monitors/statuscake/statuscake-monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
statuscake "github.com/StatusCakeDev/statuscake-go"
endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1"
"github.com/stakater/IngressMonitorController/v2/pkg/config"
"github.com/stakater/IngressMonitorController/v2/pkg/kube"
"github.com/stakater/IngressMonitorController/v2/pkg/models"
"github.com/stakater/IngressMonitorController/v2/pkg/secret"
)

var log = logf.Log.WithName("statuscake-monitor")
Expand Down Expand Up @@ -100,6 +102,24 @@ func buildUpsertForm(m models.Monitor, cgroup string) url.Values {
}
}

if providerConfig != nil && len(providerConfig.BasicAuthSecret) > 0 {
k8sClient, err := kube.GetClient()
if err != nil {
panic(err)
}

namespace := kube.GetCurrentKubernetesNamespace()
username, password, err := secret.ReadBasicAuthSecret(k8sClient.CoreV1().Secrets(namespace), providerConfig.BasicAuthSecret)

if err != nil {
log.Error(err, "Could not read the secret")
} else {
f.Add("basic_username", username)
f.Add("basic_password", password)
log.Info("Basic auth requirement detected. Setting username and password")
}
}

if providerConfig != nil && len(providerConfig.StatusCodes) > 0 {
f.Add("status_codes_csv", providerConfig.StatusCodes)

Expand Down Expand Up @@ -202,6 +222,12 @@ func buildUpsertForm(m models.Monitor, cgroup string) url.Values {
if providerConfig != nil {
f.Add("find_string", providerConfig.FindString)
}
if providerConfig != nil && len(providerConfig.RawPostData) > 0 {
f.Add("post_raw", providerConfig.RawPostData)
}
if providerConfig != nil && len(providerConfig.UserAgent) > 0 {
f.Add("user_agent", providerConfig.UserAgent)
}
return f
}

Expand Down
23 changes: 23 additions & 0 deletions pkg/secret/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"fmt"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
clientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -23,3 +25,24 @@ func LoadSecretData(apiReader client.Reader, secretName, namespace, dataKey stri
}
return string(retStr), nil
}

func ReadBasicAuthSecret(apiReader clientv1.SecretInterface, secretName string) (string, string, error) {
secret, err := apiReader.Get(context.TODO(), secretName, metav1.GetOptions{})
var username, password string
if err != nil {
return "", "", err
}

for key, value := range secret.Data {
switch key {
case "username":
username = string(value)
case "password":
password = string(value)
default:
return "", "", fmt.Errorf("secret %s contained unkown key %s", secretName, key)
}
}

return username, password, err
}