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

Commit

Permalink
Merge branch 'develop' into patch/impactedEntitiesTypo
Browse files Browse the repository at this point in the history
  • Loading branch information
bacherfl authored Jan 21, 2020
2 parents a22c637 + dc59c46 commit 127cf0a
Show file tree
Hide file tree
Showing 24 changed files with 769 additions and 187 deletions.
3 changes: 1 addition & 2 deletions pkg/api/utils/apiServiceUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import (
"crypto/tls"
"encoding/json"
"fmt"
"github.com/keptn/go-utils/pkg/api/models"
"io/ioutil"
"net/http"

"github.com/keptn/go-utils/pkg/api/models"
)

// APIService represents the interface for accessing the configuration service
Expand Down
12 changes: 9 additions & 3 deletions pkg/api/utils/resourceUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ func (r *ResourceHandler) getHTTPClient() *http.Client {
return r.HTTPClient
}

// CreateServiceResources creates a service resource
func (r *ResourceHandler) CreateServiceResources(project string, stage string, service string, resources []*models.Resource) (*models.EventContext, *models.Error) {
// CreateResources creates a resource for the specified entity
func (r *ResourceHandler) CreateResources(project string, stage string, service string, resources []*models.Resource) (*models.EventContext, *models.Error) {

copiedResources := make([]*models.Resource, len(resources), len(resources))
for i, val := range resources {
Expand All @@ -86,5 +86,11 @@ func (r *ResourceHandler) CreateServiceResources(project string, stage string, s
return nil, buildErrorResponse(err.Error())
}

return post(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+service+"/resource", requestStr, r)
if project != "" && stage != "" && service != "" {
return post(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+service+"/resource", requestStr, r)
} else if project != "" && stage != "" && service == "" {
return post(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource", requestStr, r)
} else {
return post(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", requestStr, r)
}
}
84 changes: 84 additions & 0 deletions pkg/configuration-service/utils/sliUtils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package utils

import (
"strings"

"github.com/keptn/go-utils/pkg/configuration-service/models"
"gopkg.in/yaml.v2"
)

// SLIConfig represents the struct of a SLI file
type SLIConfig struct {
Indicators map[string]string `json:"indicators" yaml:"indicators"`
}

// GetSLIConfiguration retrieves the SLI configuration for a service considering SLI configuration on stage and project level.
// First, the configuration of project-level is retrieved, which is then overridden by configuration on stage level,
// overridden by configuration on service level.
func (r *ResourceHandler) GetSLIConfiguration(project string, stage string, service string, resourceURI string) (map[string]string, error) {
var res *models.Resource
var err error
SLIs := make(map[string]string)

// get sli config from project
if project != "" {
res, err = r.GetProjectResource(project, resourceURI)
if err != nil {
// return error except "resource not found" type
if !strings.Contains(err.Error(), "resource not found") {
return nil, err
}
}
SLIs, err = addResourceContentToSLIMap(SLIs, res)
if err != nil {
return nil, err
}
}

// get sli config from stage
if project != "" && stage != "" {
res, err = r.GetStageResource(project, stage, resourceURI)
if err != nil {
// return error except "resource not found" type
if !strings.Contains(err.Error(), "resource not found") {
return nil, err
}
}
SLIs, err = addResourceContentToSLIMap(SLIs, res)
if err != nil {
return nil, err
}
}

// get sli config from service
if project != "" && stage != "" && service != "" {
res, err = r.GetServiceResource(project, stage, service, resourceURI)
if err != nil {
// return error except "resource not found" type
if !strings.Contains(err.Error(), "resource not found") {
return nil, err
}
}
SLIs, err = addResourceContentToSLIMap(SLIs, res)
if err != nil {
return nil, err
}
}

return SLIs, nil
}

func addResourceContentToSLIMap(SLIs map[string]string, resource *models.Resource) (map[string]string, error) {
if resource != nil {
sliConfig := SLIConfig{}
err := yaml.Unmarshal([]byte(resource.ResourceContent), &sliConfig)
if err != nil {
return nil, err
}

for key, value := range sliConfig.Indicators {
SLIs[key] = value
}
}
return SLIs, nil
}
60 changes: 60 additions & 0 deletions pkg/configuration-service/utils/sliUtils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package utils

import (
"testing"

"github.com/keptn/go-utils/pkg/configuration-service/models"
)

// TestAddResourceContentToSLIMap
func TestAddResourceContentToSLIMap(t *testing.T) {
SLIs := make(map[string]string)
resource := &models.Resource{}
resourceURI := "provider/sli.yaml"
resource.ResourceURI = &resourceURI
resource.ResourceContent = `---
indicators:
error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
`
SLIs, _ = addResourceContentToSLIMap(SLIs, resource)

if len(SLIs) != 5 {
t.Errorf("Unexpected lenght of SLI map")
}
}

// TestAddResourceContentToSLIMap
func TestAddMultipleResourceContentToSLIMap(t *testing.T) {
SLIs := make(map[string]string)
resource := &models.Resource{}
resourceURI := "provider/sli.yaml"
resource.ResourceURI = &resourceURI
resource.ResourceContent = `---
indicators:
error_rate: "not defined"
response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
`
SLIs, _ = addResourceContentToSLIMap(SLIs, resource)

resource.ResourceContent = `---
indicators:
error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
failure_rate: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)"
`
SLIs, _ = addResourceContentToSLIMap(SLIs, resource)

if len(SLIs) != 6 {
t.Errorf("Unexpected length of SLI map")
}

if SLIs["error_rate"] != "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" {
t.Errorf("Unexpected value of error_rate SLI")
}
}
32 changes: 27 additions & 5 deletions pkg/events/keptnEvents.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ type ConfigurationChangeEventData struct {
// FileChangesUmbrellaChart provides new content for the umbrella chart.
// The key value pairs represent the URI within the chart (i.e. the key) and the new content (i.e. the value).
FileChangesUmbrellaChart map[string]string `json:"fileChangesUmbrellaChart,omitempty"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

// Canary describes the new configuration in a canary release
Expand All @@ -122,6 +124,8 @@ type DeploymentFinishedEventData struct {
Tag string `json:"tag"`
// Image of the new deployed artifact
Image string `json:"image"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

// TestsFinishedEventData represents the data for a test finished event
Expand All @@ -140,6 +144,10 @@ type TestsFinishedEventData struct {
Start string `json:"start"`
// End indicates the end timestamp of the tests
End string `json:"end"`
// Labels contains labels
Labels map[string]string `json:"labels"`
// Result shows the status of the test
Result string `json:"result"`
}

// StartEvaluationEventData represents the data for a test finished event
Expand All @@ -158,6 +166,8 @@ type StartEvaluationEventData struct {
Start string `json:"start"`
// End indicates the end timestamp of the tests
End string `json:"end"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

// EvaluationDoneEventData contains information about evaluation results
Expand All @@ -175,13 +185,16 @@ type EvaluationDoneEventData struct {
TestStrategy string `json:"teststrategy"`
// DeploymentStrategy is the deployment strategy
DeploymentStrategy string `json:"deploymentstrategy"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

type EvaluationDetails struct {
TimeStart string `json:"timeStart"`
TimeEnd string `json:"timeEnd"`
Result string `json:"result"`
Score float64 `json:"score"`
SLOFileContent string `json:"sloFileContent"`
IndicatorResults []*SLIEvaluationResult `json:"indicatorResults"`
}

Expand All @@ -198,15 +211,16 @@ type SLIResult struct {
}

type SLIEvaluationResult struct {
Score float64 `json:"score"`
Value *SLIResult `json:"value"`
Violations []*SLIViolation `json:"violations"`
Status string `json:"status"` // pass | warning | fail
Score float64 `json:"score"`
Value *SLIResult `json:"value"`
Targets []*SLITarget `json:"targets"`
Status string `json:"status"` // pass | warning | fail
}

type SLIViolation struct {
type SLITarget struct {
Criteria string `json:"criteria"`
TargetValue float64 `json:"targetValue"`
Violated bool `json:"violated"`
}

// ProblemEventData represents the data for describing a problem
Expand All @@ -231,6 +245,8 @@ type ProblemEventData struct {
Stage string `json:"stage,omitempty"`
// Service is the name of the new service
Service string `json:"service,omitempty"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

// ConfigureMonitoringEventData represents the data necessary to configure monitoring for a service
Expand Down Expand Up @@ -261,8 +277,11 @@ type InternalGetSLIEventData struct {
TestStrategy string `json:"teststrategy"`
// DeploymentStrategy is the deployment strategy
DeploymentStrategy string `json:"deploymentstrategy"`
Deployment string `json:"deployment"`
Indicators []string `json:"indicators"`
CustomFilters []*SLIFilter `json:"customFilters"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}

// InternalGetSLIDoneEventData contains a list of SLIs and their values
Expand All @@ -280,4 +299,7 @@ type InternalGetSLIDoneEventData struct {
IndicatorValues []*SLIResult `json:"indicatorValues"`
// DeploymentStrategy is the deployment strategy
DeploymentStrategy string `json:"deploymentstrategy"`
Deployment string `json:"deployment"`
// Labels contains labels
Labels map[string]string `json:"labels"`
}
19 changes: 19 additions & 0 deletions pkg/mongodb-datastore/models/contenttype.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions pkg/mongodb-datastore/models/data.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 127cf0a

Please sign in to comment.