Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
> ### Note: The purpose of this fork is to build images of the IncidentIO access plugin that are on par with the latest Teleport version. Once the plugin is officialy released we will move to the official version.

## Building The Plugin:
1. Sync the fork with the desired release version from the upstream.
2. Update the `TELEPORT_VERSION` argument in the file `integrations/access/Dockerfile` with the relevant version.
3. From `integrations/access/incidentio`, run the command `make docker-build`.
4. Tag the image, e.g. `docker tag "146628656107.dkr.ecr.us-west-2.amazonaws.com/gravitational/teleport-plugin-incidentio:<version>" bringg/teleport-plugin-incidentio:<version>`
5. Push the image: `docker push bringg/teleport-plugin-incidentio:<version>`

------------

Teleport provides connectivity, authentication, access controls and audit for infrastructure.

Here is why you might use Teleport:
Expand Down
9 changes: 5 additions & 4 deletions integrations/access/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ ARG BASE_IMAGE=gcr.io/distroless/static-debian12
# Extract the built tarball to reduce the final image size
FROM --platform=${BUILDPLATFORM} alpine:3.20.0 as extractor

ARG TARGETARCH
ARG TARGETOS
ARG ARTIFACT_NAME=plugin # Should be something like 'access-slack' or 'event-handler'
ARG TELEPORT_VERSION=0.0.0 # Should be the version without 'v' prefix
ARG ARTIFACT_NAME=access-incidentio
ARG TELEPORT_VERSION=17.3.2
ARG TARGETOS=linux
ARG TARGETARCH=arm64
ARG FILENAME=teleport-${ARTIFACT_NAME}-v${TELEPORT_VERSION}-${TARGETOS}-${TARGETARCH}-bin.tar.gz # Optional override


WORKDIR /extraction
COPY *${TARGETARCH}*.tar.gz /plugin.tar.gz
COPY "${FILENAME}" /plugin.tar.gz
Expand Down
3 changes: 3 additions & 0 deletions integrations/access/incidentio/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ACCESS_PLUGIN = incidentio

include ../common.mk
1 change: 1 addition & 0 deletions integrations/access/incidentio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Teleport IncidentIO access request plugin
119 changes: 119 additions & 0 deletions integrations/access/incidentio/alert_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Teleport
* Copyright (C) 2023 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package incidentio

import (
"context"
"encoding/json"
"io"
"log"
"net/http"
"net/http/httptest"
"testing"

"github.com/gravitational/trace"
"github.com/stretchr/testify/assert"

"github.com/gravitational/teleport/api/types"
)

func TestCreateAlert(t *testing.T) {
recievedReq := ""
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
bodyBytes, err := io.ReadAll(req.Body)
if err != nil {
log.Fatal(err)
}
recievedReq = string(bodyBytes)
}))
defer func() { testServer.Close() }()

c, err := NewAlertClient(ClientConfig{
AlertSourceEndpoint: testServer.URL,
ClusterName: "someClusterName",
})
assert.NoError(t, err)

_, err = c.CreateAlert(context.Background(), "someRequestID", RequestData{
User: "someUser",
Roles: []string{"role1", "role2"},
RequestReason: "someReason",
SystemAnnotations: types.Labels{
types.TeleportNamespace + types.ReqAnnotationNotifySchedulesLabel: {"responder@example.com", "bb4d9938-c3c2-455d-aaab-727aa701c0d8"},
},
})
assert.NoError(t, err)

expected := AlertBody{
Title: "Access request from someUser",
DeduplicationKey: "teleport-access-request/someRequestID",
Description: "Access request from someUser",
Status: "firing",
Metadata: map[string]string{
"request_id": "someRequestID",
},
}
var got AlertBody
err = json.Unmarshal([]byte(recievedReq), &got)
assert.NoError(t, err)

assert.Equal(t, expected, got)
}

func TestResolveAlert(t *testing.T) {
recievedReq := ""
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
bodyBytes, err := io.ReadAll(req.Body)
if err != nil {
log.Fatal(err)
}
recievedReq = string(bodyBytes)
}))
defer func() { testServer.Close() }()

c, err := NewAlertClient(ClientConfig{
AlertSourceEndpoint: testServer.URL,
ClusterName: "someClusterName",
})
assert.NoError(t, err)

err = c.ResolveAlert(context.Background(), "someAlertID", Resolution{
Tag: ResolvedApproved,
Reason: "someReason",
})

assert.NoError(t, err)

assert.Equal(t, `{"message":"Access request resolved: approved","description":"Access request has been approved","deduplication_key":"teleport-access-request/someAlertID","status":"resolved","metadata":{"request_id":"someAlertID"}}`, recievedReq)
}

func TestCreateAlertError(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusForbidden)
}))
defer func() { testServer.Close() }()

c, err := NewAlertClient(ClientConfig{
AlertSourceEndpoint: testServer.URL,
})
assert.NoError(t, err)

_, err = c.CreateAlert(context.Background(), "someRequestID", RequestData{})
assert.True(t, trace.IsAccessDenied(err))
}
70 changes: 70 additions & 0 deletions integrations/access/incidentio/api_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Teleport
* Copyright (C) 2023 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package incidentio

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetSchedule(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/v2/schedules/someRequestID" {
res.WriteHeader(http.StatusOK)
} else {
res.WriteHeader(http.StatusBadRequest)
}
}))
defer func() { testServer.Close() }()

c, err := NewAPIClient(ClientConfig{
APIEndpoint: testServer.URL,
APIKey: "someAPIKey",
ClusterName: "someClusterName",
})
assert.NoError(t, err)

_, err = c.GetOnCall(context.Background(), "someRequestID")
assert.NoError(t, err)
}

func TestHealthCheck(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/v2/schedules" {
res.WriteHeader(http.StatusOK)
} else {
res.WriteHeader(http.StatusBadRequest)
}
}))
defer func() { testServer.Close() }()

c, err := NewAPIClient(ClientConfig{
APIEndpoint: testServer.URL,
APIKey: "someAPIKey",
ClusterName: "someClusterName",
})
assert.NoError(t, err)

err = c.CheckHealth(context.Background())
assert.NoError(t, err)
}
Loading