Skip to content

Commit

Permalink
move service to separate pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
nieomylnieja committed Oct 4, 2023
1 parent eb60608 commit cd68f03
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 71 deletions.
17 changes: 13 additions & 4 deletions manifest/v1alpha/alert.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package v1alpha

import "github.com/nobl9/nobl9-go/manifest"
import (
"github.com/nobl9/nobl9-go/manifest"
)

//go:generate go run ../../scripts/generate-object-impl.go Alert

Expand All @@ -22,9 +24,9 @@ type AlertMetadata struct {

// AlertSpec represents content of Alert's Spec
type AlertSpec struct {
AlertPolicy AlertPolicyMetadata `json:"alertPolicy"`
SLO SLOMetadata `json:"slo"`
Service ServiceMetadata `json:"service"`
AlertPolicy AlertObjectMetadata `json:"alertPolicy"`
SLO AlertObjectMetadata `json:"slo"`
Service AlertObjectMetadata `json:"service"`
Objective AlertObjective `json:"objective"`
Severity string `json:"severity" validate:"required,severity" example:"High"`
Status string `json:"status" example:"Resolved"`
Expand All @@ -41,3 +43,10 @@ type AlertObjective struct {
Name string `json:"name" validate:"omitempty"`
DisplayName string `json:"displayName" validate:"omitempty"`
}

type AlertObjectMetadata struct {
Name string `json:"name"`
DisplayName string `json:"displayName,omitempty"`
Project string `json:"project,omitempty"`
Labels Labels `json:"labels,omitempty"`
}
3 changes: 2 additions & 1 deletion manifest/v1alpha/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
"github.com/nobl9/nobl9-go/manifest/v1alpha/project"
"github.com/nobl9/nobl9-go/manifest/v1alpha/service"
)

type unmarshalFunc func(v interface{}) error
Expand Down Expand Up @@ -45,7 +46,7 @@ func parseObject(kind manifest.Kind, unmarshal unmarshalFunc) (manifest.Object,
//exhaustive:enforce
switch kind {
case manifest.KindService:
return genericParseObject[v1alpha.Service](unmarshal)
return genericParseObject[service.Service](unmarshal)
case manifest.KindSLO:
return genericParseObject[v1alpha.SLO](unmarshal)
case manifest.KindProject:
Expand Down
20 changes: 10 additions & 10 deletions manifest/v1alpha/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import (

//go:generate go run ../../../scripts/generate-object-impl.go Project

// New creates a new Project based on provided Metadata nad Spec.
func New(metadata Metadata, spec Spec) Project {
return Project{
APIVersion: manifest.VersionV1alpha.String(),
Kind: manifest.KindProject,
Metadata: metadata,
Spec: spec,
}
}

// Project is the primary grouping primitive for manifest.Object.
// Most objects are scoped to a certain Project.
type Project struct {
Expand All @@ -19,16 +29,6 @@ type Project struct {
ManifestSource string `json:"manifestSrc,omitempty"`
}

// New creates a new Project based on provided Metadata nad Spec.
func New(metadata Metadata, spec Spec) Project {
return Project{
APIVersion: manifest.VersionV1alpha.String(),
Kind: manifest.KindProject,
Metadata: metadata,
Spec: spec,
}
}

// Metadata provides identity information for Project.
type Metadata struct {
Name string `json:"name" validate:"required,objectName" example:"name"`
Expand Down
42 changes: 0 additions & 42 deletions manifest/v1alpha/service.go

This file was deleted.

2 changes: 2 additions & 0 deletions manifest/v1alpha/service/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package service defines Service object definitions.
package service
11 changes: 11 additions & 0 deletions manifest/v1alpha/service/example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: n9/v1alpha
kind: Service
metadata:
name: my-service
displayName: My Service
project: default
labels:
team: [ green, orange ]
region: [ eu-central-1 ]
spec:
description: Example Service
53 changes: 53 additions & 0 deletions manifest/v1alpha/service/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package service_test

import (
"context"
"log"

"github.com/nobl9/nobl9-go/internal/examples"
"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
"github.com/nobl9/nobl9-go/manifest/v1alpha/service"
)

func ExampleService() {
// Create the object:
myService := service.New(
service.Metadata{
Name: "my-service",
DisplayName: "My Service",
Project: "default",
Labels: v1alpha.Labels{
"team": []string{"green", "orange"},
"region": []string{"eu-central-1"},
},
},
service.Spec{
Description: "Example service",
},
)
// Verify the object:
if err := myService.Validate(); err != nil {
log.Fatal("service validation failed, err: %w", err)
}
// Apply the object:
client := examples.GetOfflineEchoClient()
if err := client.ApplyObjects(context.Background(), []manifest.Object{myService}, false); err != nil {
log.Fatal("failed to apply service, err: %w", err)
}
// Output:
// apiVersion: n9/v1alpha
// kind: Service
// metadata:
// name: my-service
// displayName: My Service
// project: default
// labels:
// region:
// - eu-central-1
// team:
// - green
// - orange
// spec:
// description: Example service
}
49 changes: 49 additions & 0 deletions manifest/v1alpha/service/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package service

import (
"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
)

//go:generate go run ../../../scripts/generate-object-impl.go Service

// New creates a new Service based on provided Metadata nad Spec.
func New(metadata Metadata, spec Spec) Service {
return Service{
APIVersion: manifest.VersionV1alpha.String(),
Kind: manifest.KindService,
Metadata: metadata,
Spec: spec,
}
}

// Service struct which mapped one to one with kind: service yaml definition
type Service struct {
APIVersion string `json:"apiVersion"`
Kind manifest.Kind `json:"kind"`
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status *Status `json:"status,omitempty"`

Organization string `json:"organization,omitempty"`
ManifestSource string `json:"manifestSrc,omitempty"`
}

// Metadata provides identity information for Service.
type Metadata struct {
Name string `json:"name" validate:"required,objectName"`
DisplayName string `json:"displayName,omitempty" validate:"omitempty,min=0,max=63"`
Project string `json:"project,omitempty" validate:"objectName"`
Labels v1alpha.Labels `json:"labels,omitempty" validate:"omitempty,labels"`
}

// Status holds dynamic fields returned when the Service is fetched from Nobl9 platform.
// Status is not part of the static object definition.
type Status struct {
SloCount int `json:"sloCount"`
}

// Spec holds detailed information specific to Service.
type Spec struct {
Description string `json:"description" validate:"description" example:"Bleeding edge web app"`
}

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

14 changes: 14 additions & 0 deletions manifest/v1alpha/service/test_data/expected_error.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Validation for Service 'MY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICE' in project 'MY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECT' has failed for the following fields:
- 'metadata.name' with value 'MY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICEMY SERVICE...':
- length must be between 1 and 63
- a DNS-1123 compliant name must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
- 'metadata.displayName' with value 'my-servicemy-servicemy-servicemy-servicemy-servicemy-servicemy-servicemy-servicemy-servicemy-service':
- length must be between 0 and 63
- 'metadata.project' with value 'MY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECTMY PROJECT...':
- length must be between 1 and 63
- a DNS-1123 compliant name must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
- 'metadata.labels' with value '{"L O L":["dip","dip"]}':
- label key 'L O L' does not match the regex: ^\p{L}([_\-0-9\p{L}]*[0-9\p{L}])?$
- 'spec.description' with value 'llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll...':
- length must be between 0 and 1050
Manifest source: /home/me/service.yaml
44 changes: 44 additions & 0 deletions manifest/v1alpha/service/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package service

import (
"github.com/nobl9/nobl9-go/manifest/v1alpha"
"github.com/nobl9/nobl9-go/validation"
)

func validate(s Service) error {
v := validation.RulesForStruct(
validation.RulesForField[string](
"metadata.name",
func() string { return s.Metadata.Name },
).
With(
validation.StringRequired(),
validation.StringIsDNSSubdomain()),
validation.RulesForField[string](
"metadata.displayName",
func() string { return s.Metadata.DisplayName },
).
With(validation.StringLength(0, 63)),
validation.RulesForField[string](
"metadata.project",
func() string { return s.Metadata.Project },
).
With(
validation.StringRequired(),
validation.StringIsDNSSubdomain()),
validation.RulesForField[v1alpha.Labels](
"metadata.labels",
func() v1alpha.Labels { return s.Metadata.Labels },
).
With(v1alpha.ValidationRule()),
validation.RulesForField[string](
"spec.description",
func() string { return s.Spec.Description },
).
With(validation.StringDescription()),
)
if errs := v.Validate(); len(errs) > 0 {
return v1alpha.NewObjectError(s, errs)
}
return nil
}
34 changes: 34 additions & 0 deletions manifest/v1alpha/service/validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package service

import (
_ "embed"
"strings"
"testing"

"github.com/stretchr/testify/assert"

"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
)

//go:embed test_data/expected_error.txt
var expectedError string

func TestValidate_AllErrors(t *testing.T) {
err := validate(Service{
Kind: manifest.KindService,
Metadata: Metadata{
Name: strings.Repeat("MY SERVICE", 20),
DisplayName: strings.Repeat("my-service", 10),
Project: strings.Repeat("MY PROJECT", 20),
Labels: v1alpha.Labels{
"L O L": []string{"dip", "dip"},
},
},
Spec: Spec{
Description: strings.Repeat("l", 2000),
},
ManifestSource: "/home/me/service.yaml",
})
assert.Equal(t, expectedError, err.Error())
}
1 change: 1 addition & 0 deletions manifest/v1alpha/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,7 @@ func areSumoLogicTimesliceValuesEqual(sloSpec SLOSpec) bool {

// haveAzureMonitorCountMetricSpecTheSameResourceIDAndMetricNamespace checks if good/bad query has the same resourceID
// and metricNamespace as total query
// nolint: gocognit
func haveAzureMonitorCountMetricSpecTheSameResourceIDAndMetricNamespace(sloSpec SLOSpec) bool {
for _, objective := range sloSpec.Objectives {
if objective.CountMetrics == nil {
Expand Down
Loading

0 comments on commit cd68f03

Please sign in to comment.