feat(SSH): Add support for SSH endpoint (#473)

* feat(SSH): Add support for SSH endpoint

This commit adds support for SSH endpoint monitoring. Users can now configure an endpoint to be monitored using an SSH command by prefixing the endpoint's URL with ssh:\\. The configuration options for an SSH endpoint include the username, password, and command to be executed on the remote server. In addition, two placeholders are supported for SSH endpoints: [CONNECTED] and [STATUS].

This commit also updates the README to include instructions on how to configure SSH endpoints and the placeholders that can be used in their conditions. The README has been updated to include the new SSH-related options in the endpoints[] configuration object.

Here's a summary of the changes made in this commit:

    Added support for SSH endpoint monitoring
    Updated the documentation to include instructions on how to configure SSH endpoints and the placeholders that can be used in their conditions
This commit is contained in:
Henry Barreto
2023-09-23 14:37:24 -03:00
committed by GitHub
parent 8fbfba2163
commit 05565e3d0a
5 changed files with 260 additions and 1 deletions

View File

@ -256,6 +256,7 @@ func TestEndpoint_Type(t *testing.T) {
type args struct {
URL string
DNS *DNS
SSH *SSH
}
tests := []struct {
args args
@ -325,6 +326,16 @@ func TestEndpoint_Type(t *testing.T) {
},
want: EndpointTypeWS,
},
{
args: args{
URL: "ssh://example.com:22",
SSH: &SSH{
Username: "root",
Password: "password",
},
},
want: EndpointTypeSSH,
},
{
args: args{
URL: "invalid://example.org",
@ -454,6 +465,52 @@ func TestEndpoint_ValidateAndSetDefaultsWithDNS(t *testing.T) {
}
}
func TestEndpoint_ValidateAndSetDefaultsWithSSH(t *testing.T) {
tests := []struct {
name string
username string
password string
expectedErr error
}{
{
name: "fail when has no user",
username: "",
password: "password",
expectedErr: ErrEndpointWithoutSSHUsername,
},
{
name: "fail when has no password",
username: "username",
password: "",
expectedErr: ErrEndpointWithoutSSHPassword,
},
{
name: "success when all fields are set",
username: "username",
password: "password",
expectedErr: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
endpoint := &Endpoint{
Name: "ssh-test",
URL: "https://example.com",
SSH: &SSH{
Username: test.username,
Password: test.password,
},
Conditions: []Condition{Condition("[STATUS] == 0")},
}
err := endpoint.ValidateAndSetDefaults()
if err != test.expectedErr {
t.Errorf("expected error %v, got %v", test.expectedErr, err)
}
})
}
}
func TestEndpoint_ValidateAndSetDefaultsWithSimpleErrors(t *testing.T) {
scenarios := []struct {
endpoint *Endpoint
@ -680,6 +737,55 @@ func TestIntegrationEvaluateHealthForDNS(t *testing.T) {
}
}
func TestIntegrationEvaluateHealthForSSH(t *testing.T) {
tests := []struct {
name string
endpoint Endpoint
conditions []Condition
success bool
}{
{
name: "ssh-success",
endpoint: Endpoint{
Name: "ssh-success",
URL: "ssh://localhost",
SSH: &SSH{
Username: "test",
Password: "test",
},
Body: "{ \"command\": \"uptime\" }",
},
conditions: []Condition{Condition("[STATUS] == 0")},
success: true,
},
{
name: "ssh-failure",
endpoint: Endpoint{
Name: "ssh-failure",
URL: "ssh://localhost",
SSH: &SSH{
Username: "test",
Password: "test",
},
Body: "{ \"command\": \"uptime\" }",
},
conditions: []Condition{Condition("[STATUS] == 1")},
success: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.endpoint.ValidateAndSetDefaults()
test.endpoint.Conditions = test.conditions
result := test.endpoint.EvaluateHealth()
if result.Success != test.success {
t.Errorf("Expected success to be %v, but was %v", test.success, result.Success)
}
})
}
}
func TestIntegrationEvaluateHealthForICMP(t *testing.T) {
endpoint := Endpoint{
Name: "icmp-test",