Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

feat: Move commonly used modules from keptn/keptn into sub-packages of go-utils #483

Merged
merged 7 commits into from
Jun 28, 2022
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: Test
run: go test -race -v ./...
run: go test -v ./...
29 changes: 20 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ module github.com/keptn/go-utils
go 1.17

require (
github.com/avast/retry-go v3.0.0+incompatible
github.com/benbjohnson/clock v1.3.0
github.com/cloudevents/sdk-go/observability/opentelemetry/v2 v2.0.0-20211001212819-74757a691209
github.com/cloudevents/sdk-go/v2 v2.9.0
github.com/cloudevents/sdk-go/v2 v2.10.0
github.com/google/uuid v1.3.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/nats-io/nats-server/v2 v2.8.4
github.com/nats-io/nats.go v1.16.0
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.1
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
go.opentelemetry.io/otel v1.2.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0
go.opentelemetry.io/otel v1.7.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0
go.opentelemetry.io/otel/sdk v1.2.0
go.opentelemetry.io/otel/trace v1.2.0
go.opentelemetry.io/otel/trace v1.7.0
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/api v0.22.11
k8s.io/apimachinery v0.22.11
Expand All @@ -25,32 +31,37 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/go-logr/logr v1.2.2 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.14.4 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a // indirect
github.com/nats-io/nkeys v0.3.0 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/onsi/gomega v1.15.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 // indirect
go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect
go.opentelemetry.io/otel/metric v0.25.0 // indirect
go.opentelemetry.io/otel/metric v0.30.0 // indirect
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.0 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
60 changes: 46 additions & 14 deletions go.sum

Large diffs are not rendered by default.

238 changes: 238 additions & 0 deletions pkg/api/utils/internal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
package api

import (
"github.com/benbjohnson/clock"
"github.com/keptn/go-utils/pkg/api/models"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"net/http"
"time"
)

// InternalAPISet is an implementation of APISet
// which can be used from within the Keptn control plane
type InternalAPISet struct {
apimap InClusterAPIMappings
httpClient *http.Client
apiHandler *InternalAPIHandler
authHandler *AuthHandler
eventHandler *EventHandler
logHandler *LogHandler
projectHandler *ProjectHandler
resourceHandler *ResourceHandler
secretHandler *SecretHandler
sequenceControlHandler *SequenceControlHandler
serviceHandler *ServiceHandler
stageHandler *StageHandler
uniformHandler *UniformHandler
shipyardControlHandler *ShipyardControllerHandler
}

// InternalService is used to enumerate internal Keptn services
type InternalService int

const (
ConfigurationService InternalService = iota

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported const ConfigurationService should have comment (or a comment on this block) or be unexported

ShipyardController
ApiService

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
const ApiService should be APIService

SecretService
MongoDBDatastore
)

// InClusterAPIMappings maps a keptn service name to its reachable domain name
type InClusterAPIMappings map[InternalService]string

// DefaultInClusterAPIMappings gives you the default InClusterAPIMappings
var DefaultInClusterAPIMappings = InClusterAPIMappings{
ConfigurationService: "configuration-service:8080",
ShipyardController: "shipyard-controller:8080",
ApiService: "api-service:8080",
SecretService: "secret-service:8080",
MongoDBDatastore: "mongodb-datastore:8080",
}

// NewInternal creates a new InternalAPISet usable for calling keptn services from within the control plane
func NewInternal(client *http.Client, apiMappings ...InClusterAPIMappings) (*InternalAPISet, error) {
var apimap InClusterAPIMappings
if len(apiMappings) > 0 {
apimap = apiMappings[0]
} else {
apimap = DefaultInClusterAPIMappings
}

if client == nil {
client = &http.Client{}
}

as := &InternalAPISet{}
as.httpClient = client

as.apiHandler = &InternalAPIHandler{
shipyardControllerApiHandler: &APIHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
},
}

as.authHandler = &AuthHandler{
BaseURL: apimap[ApiService],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.logHandler = &LogHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: getClientTransport(as.httpClient.Transport)},
Scheme: "http",
LogCache: []models.LogEntry{},
TheClock: clock.New(),
SyncInterval: 1 * time.Minute,
}

as.eventHandler = &EventHandler{
BaseURL: apimap[MongoDBDatastore],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}

as.projectHandler = &ProjectHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}

as.resourceHandler = &ResourceHandler{
BaseURL: apimap[ConfigurationService],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.secretHandler = &SecretHandler{
BaseURL: apimap[SecretService],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.sequenceControlHandler = &SequenceControlHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.serviceHandler = &ServiceHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.shipyardControlHandler = &ShipyardControllerHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: wrapOtelTransport(getClientTransport(as.httpClient.Transport))},
Scheme: "http",
}
as.stageHandler = &StageHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: otelhttp.NewTransport(as.httpClient.Transport)},
Scheme: "http",
}
as.uniformHandler = &UniformHandler{
BaseURL: apimap[ShipyardController],
HTTPClient: &http.Client{Transport: getClientTransport(as.httpClient.Transport)},
Scheme: "http",
}
return as, nil
}

// APIV1 retrieves the APIHandler
func (c *InternalAPISet) APIV1() APIV1Interface {
return c.apiHandler
}

// AuthV1 retrieves the AuthHandler
func (c *InternalAPISet) AuthV1() AuthV1Interface {
return c.authHandler
}

// EventsV1 retrieves the EventHandler
func (c *InternalAPISet) EventsV1() EventsV1Interface {
return c.eventHandler
}

// LogsV1 retrieves the LogHandler
func (c *InternalAPISet) LogsV1() LogsV1Interface {
return c.logHandler
}

// ProjectsV1 retrieves the ProjectHandler
func (c *InternalAPISet) ProjectsV1() ProjectsV1Interface {
return c.projectHandler
}

// ResourcesV1 retrieves the ResourceHandler
func (c *InternalAPISet) ResourcesV1() ResourcesV1Interface {
return c.resourceHandler
}

// SecretsV1 retrieves the SecretHandler
func (c *InternalAPISet) SecretsV1() SecretsV1Interface {
return c.secretHandler
}

// SequencesV1 retrieves the SequenceControlHandler
func (c *InternalAPISet) SequencesV1() SequencesV1Interface {
return c.sequenceControlHandler
}

// ServicesV1 retrieves the ServiceHandler
func (c *InternalAPISet) ServicesV1() ServicesV1Interface {
return c.serviceHandler
}

// StagesV1 retrieves the StageHandler
func (c *InternalAPISet) StagesV1() StagesV1Interface {
return c.stageHandler
}

// UniformV1 retrieves the UniformHandler
func (c *InternalAPISet) UniformV1() UniformV1Interface {
return c.uniformHandler
}

// ShipyardControlV1 retrieves the ShipyardControllerHandler
func (c *InternalAPISet) ShipyardControlV1() ShipyardControlV1Interface {
return c.shipyardControlHandler
}

// InternalAPIHandler is used instead of APIHandler from go-utils because we cannot support
// (unauthenticated) internal calls to the api-service at the moment. So this implementation
// will panic as soon as a client wants to call these methods
type InternalAPIHandler struct {
shipyardControllerApiHandler *APIHandler

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
struct field shipyardControllerApiHandler should be shipyardControllerAPIHandler

}

func (i *InternalAPIHandler) SendEvent(event models.KeptnContextExtendedCE) (*models.EventContext, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.SendEvent should have comment or be unexported

panic("SendEvent() is not not supported for internal usage")
}

func (i *InternalAPIHandler) TriggerEvaluation(project string, stage string, service string, evaluation models.Evaluation) (*models.EventContext, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.TriggerEvaluation should have comment or be unexported

return i.shipyardControllerApiHandler.TriggerEvaluation(project, stage, service, evaluation)
}

func (i *InternalAPIHandler) CreateProject(project models.CreateProject) (string, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.CreateProject should have comment or be unexported

return i.shipyardControllerApiHandler.CreateProject(project)
}

func (i *InternalAPIHandler) UpdateProject(project models.CreateProject) (string, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.UpdateProject should have comment or be unexported

return i.shipyardControllerApiHandler.UpdateProject(project)
}

func (i *InternalAPIHandler) DeleteProject(project models.Project) (*models.DeleteProjectResponse, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.DeleteProject should have comment or be unexported

return i.shipyardControllerApiHandler.DeleteProject(project)
}

func (i *InternalAPIHandler) CreateService(project string, service models.CreateService) (string, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.CreateService should have comment or be unexported

return i.shipyardControllerApiHandler.CreateService(project, service)
}

func (i *InternalAPIHandler) DeleteService(project string, service string) (*models.DeleteServiceResponse, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.DeleteService should have comment or be unexported

return i.shipyardControllerApiHandler.DeleteService(project, service)
}

func (i *InternalAPIHandler) GetMetadata() (*models.Metadata, *models.Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported method InternalAPIHandler.GetMetadata should have comment or be unexported

panic("GetMetadata() is not not supported for internal usage")
}
51 changes: 51 additions & 0 deletions pkg/api/utils/internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package api

import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)

func TestApiSetInternalMappings(t *testing.T) {
t.Run("TestInternalAPISet - Default API Mappings", func(t *testing.T) {
internal, err := NewInternal(nil)
require.Nil(t, err)
require.NotNil(t, internal)
assert.Equal(t, DefaultInClusterAPIMappings[MongoDBDatastore], internal.EventsV1().(*EventHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ApiService], internal.AuthV1().(*AuthHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.APIV1().(*InternalAPIHandler).shipyardControllerApiHandler.BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.ShipyardControlV1().(*ShipyardControllerHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.UniformV1().(*UniformHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.LogsV1().(*LogHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.SequencesV1().(*SequenceControlHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.StagesV1().(*StageHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[SecretService], internal.SecretsV1().(*SecretHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ConfigurationService], internal.ResourcesV1().(*ResourceHandler).BaseURL)
assert.Equal(t, DefaultInClusterAPIMappings[ShipyardController], internal.ProjectsV1().(*ProjectHandler).BaseURL)
})

t.Run("TestInternalAPISet - Override Mappings", func(t *testing.T) {
overrideMappings := InClusterAPIMappings{
ConfigurationService: "special-configuration-service:8080",
ShipyardController: "special-shipyard-controller:8080",
ApiService: "speclial-api-service:8080",
SecretService: "special-secret-service:8080",
MongoDBDatastore: "special-monogodb-datastore:8080",
}
internal, err := NewInternal(nil, overrideMappings)
require.Nil(t, err)
require.NotNil(t, internal)
assert.Equal(t, overrideMappings[MongoDBDatastore], internal.EventsV1().(*EventHandler).BaseURL)
assert.Equal(t, overrideMappings[ApiService], internal.AuthV1().(*AuthHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.APIV1().(*InternalAPIHandler).shipyardControllerApiHandler.BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.ShipyardControlV1().(*ShipyardControllerHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.UniformV1().(*UniformHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.LogsV1().(*LogHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.SequencesV1().(*SequenceControlHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.StagesV1().(*StageHandler).BaseURL)
assert.Equal(t, overrideMappings[SecretService], internal.SecretsV1().(*SecretHandler).BaseURL)
assert.Equal(t, overrideMappings[ConfigurationService], internal.ResourcesV1().(*ResourceHandler).BaseURL)
assert.Equal(t, overrideMappings[ShipyardController], internal.ProjectsV1().(*ProjectHandler).BaseURL)
})

}
Loading