Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jobs v2 #1527

Closed
wants to merge 16 commits into from
Closed

Jobs v2 #1527

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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ ui/scripts/
Chart.lock
chart/charts/
.downloads
tmp/
ginkgo.report
__debug*
test-results.xml
19 changes: 13 additions & 6 deletions api/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ type Context struct {
db *gorm.DB
pool *pgxpool.Pool
cache map[string]any
duty *dutyCtx.Context
}

func (ctx *Context) Duty() dutyCtx.Context {
return dutyCtx.NewContext(gocontext.Background()).
if ctx.duty != nil {
return *ctx.duty
}
duty := dutyCtx.NewContext(gocontext.Background()).
WithDB(ctx.db, ctx.pool).
WithKubernetes(ctx.Kubernetes).
WithNamespace(ctx.Namespace).
WithObject(ctx.Canary.ObjectMeta)
ctx.duty = &duty
return *ctx.duty
}

func (ctx *Context) DB() *gorm.DB {
Expand Down Expand Up @@ -250,17 +256,18 @@ func (ctx *KubernetesContext) Clone() *KubernetesContext {
}
}

func New(client *kommons.Client, kubernetes kubernetes.Interface, db *gorm.DB, pool *pgxpool.Pool, canary v1.Canary) *Context {
func New(ctx dutyCtx.Context, canary v1.Canary) *Context {
if canary.Namespace == "" {
canary.Namespace = "default"
}

return &Context{
db: db,
pool: pool,
duty: &ctx,
db: ctx.DB(),
pool: ctx.Pool(),
Context: gocontext.Background(),
Kommons: client,
Kubernetes: kubernetes,
Kommons: ctx.Kommons(),
Kubernetes: ctx.Kubernetes(),
Namespace: canary.GetNamespace(),
Canary: canary,
Environment: make(map[string]interface{}),
Expand Down
1 change: 1 addition & 0 deletions api/v1/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const (
OnTransformMarkHealthy = "MarkHealthy"
OnTransformMarkUnhealthy = "MarkUnhealthy"
OnTransformIgnore = "Ignore"
)

type checkContext interface {
Expand Down
115 changes: 19 additions & 96 deletions api/v1/component_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package v1

import (
"fmt"
"strings"

"github.com/flanksource/duty/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +kubebuilder:object:root=true

type Component struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Expand Down Expand Up @@ -40,12 +38,12 @@ type ComponentSpec struct {
// Create new child components
Components []ComponentSpecObject `json:"components,omitempty"`
// Lookup and associcate other components with this component
Selectors ResourceSelectors `json:"selectors,omitempty"`
ComponentChecks ComponentChecks `json:"checks,omitempty"`
Selectors types.ResourceSelectors `json:"selectors,omitempty"`
ComponentChecks ComponentChecks `json:"checks,omitempty"`
// Lookup and associate config items with this component
Configs []Config `json:"configs,omitempty"`
Configs types.ConfigQueries `json:"configs,omitempty"`
//
Summary *Summary `json:"summary,omitempty"`
Summary *types.Summary `json:"summary,omitempty"`
// Only applies when using lookup, when specified the components and properties
// specified under ForEach will be templated using the components returned by the lookup
// ${.properties} can be used to reference the properties of the component
Expand All @@ -69,13 +67,13 @@ func (c ComponentSpec) String() string {
type ForEach struct {
Components []ComponentSpec `json:"components,omitempty"`
// Properties are created once the full component tree is created, property lookup functions
// can return a map of coomponent name => properties to allow for bulk property lookups
// can return a map of component name => properties to allow for bulk property lookups
// being applied to multiple components in the tree
Properties Properties `json:"properties,omitempty"`
Configs []Config `json:"configs,omitempty"`
Selectors ResourceSelectors `json:"selectors,omitempty"`
Relationships []RelationshipSpec `json:"relationships,omitempty"`
ComponentChecks ComponentChecks `json:"checks,omitempty"`
Properties Properties `json:"properties,omitempty"`
Configs []types.ConfigQuery `json:"configs,omitempty"`
Selectors types.ResourceSelectors `json:"selectors,omitempty"`
Relationships []RelationshipSpec `json:"relationships,omitempty"`
ComponentChecks types.ComponentChecks `json:"checks,omitempty"`
}

func (f *ForEach) IsEmpty() bool {
Expand All @@ -86,59 +84,8 @@ func (f *ForEach) String() string {
return fmt.Sprintf("ForEach(components=%d, properties=%d)", len(f.Components), len(f.Properties))
}

type Summary struct {
Healthy int `json:"healthy,omitempty"`
Unhealthy int `json:"unhealthy,omitempty"`
Warning int `json:"warning,omitempty"`
Info int `json:"info,omitempty"`
Incidents map[string]map[string]int `json:"incidents,omitempty"`
Insights map[string]map[string]int `json:"insights,omitempty"`
}

func (s Summary) String() string {
str := ""
if s.Unhealthy > 0 {
str += fmt.Sprintf("unhealthy=%d ", s.Unhealthy)
}
if s.Warning > 0 {
str += fmt.Sprintf("warning=%d ", s.Warning)
}
if s.Healthy > 0 {
str += fmt.Sprintf("healthy=%d ", s.Healthy)
}
return strings.TrimSpace(str)
}

func (s Summary) GetStatus() ComponentPropertyStatus {
if s.Unhealthy > 0 {
return ComponentPropertyStatusUnhealthy
} else if s.Warning > 0 {
return ComponentPropertyStatusWarning
} else if s.Healthy > 0 {
return ComponentPropertyStatusHealthy
}
return "unknown"
}

func (s Summary) Add(b Summary) Summary {
if b.Healthy > 0 && b.Unhealthy > 0 {
s.Warning += 1
} else if b.Unhealthy > 0 {
s.Unhealthy += 1
} else if b.Healthy > 0 {
s.Healthy += 1
}
if b.Warning > 0 {
s.Warning += b.Warning
}
if b.Info > 0 {
s.Info += b.Info
}
return s
}

type ComponentStatus struct {
Status ComponentPropertyStatus `json:"status,omitempty"`
Status types.ComponentStatus `json:"status,omitempty"`
}

type RelationshipSpec struct {
Expand All @@ -147,32 +94,8 @@ type RelationshipSpec struct {
Ref string `json:"ref,omitempty"`
}

type ComponentPropertyStatus string

var (
ComponentPropertyStatusHealthy ComponentPropertyStatus = "healthy"
ComponentPropertyStatusUnhealthy ComponentPropertyStatus = "unhealthy"
ComponentPropertyStatusWarning ComponentPropertyStatus = "warning"
ComponentPropertyStatusError ComponentPropertyStatus = "error"
ComponentPropertyStatusInfo ComponentPropertyStatus = "info"
)

type Owner string

type Text struct {
Tooltip string `json:"tooltip,omitempty"`
Icon string `json:"icon,omitempty"`
Text string `json:"text,omitempty"`
Label string `json:"label,omitempty"`
}

type Link struct {
// e.g. documentation, support, playbook
Type string `json:"type,omitempty"`
URL string `json:"url,omitempty"`
Text `json:",inline"`
}

type Properties []Property

type Property struct {
Expand All @@ -186,13 +109,13 @@ type Property struct {
Type string `json:"type,omitempty"`
Color string `json:"color,omitempty"`
// e.g. milliseconds, bytes, millicores, epoch etc.
Unit string `json:"unit,omitempty"`
Value int64 `json:"value,omitempty"`
Max *int64 `json:"max,omitempty"`
Min *int64 `json:"min,omitempty"`
Status string `json:"status,omitempty"`
LastTransition string `json:"lastTransition,omitempty"`
Links []Link `json:"links,omitempty"`
Unit string `json:"unit,omitempty"`
Value int64 `json:"value,omitempty"`
Max *int64 `json:"max,omitempty"`
Min *int64 `json:"min,omitempty"`
Status string `json:"status,omitempty"`
LastTransition string `json:"lastTransition,omitempty"`
Links []types.Link `json:"links,omitempty"`
// +kubebuilder:validation:XPreserveUnknownFields
Lookup *CanarySpec `json:"lookup,omitempty"`
ConfigLookup *ConfigLookup `json:"configLookup,omitempty"`
Expand All @@ -215,7 +138,7 @@ func (p *Property) String() string {
type ConfigLookup struct {
ID string `json:"id,omitempty"`
// Lookup a config by it
Config *Config `json:"config,omitempty"`
Config *types.ConfigQuery `json:"config,omitempty"`
// A JSONPath expression to lookup the value in the config
Field string `json:"field,omitempty"`
// Apply transformations to the value
Expand Down
91 changes: 0 additions & 91 deletions api/v1/db_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,55 +22,8 @@ const (
nvarcharType = "NVARCHAR(MAX)"
)

type ResourceSelectors []ResourceSelector

type ComponentChecks []ComponentCheck

func (rs ResourceSelectors) Value() (driver.Value, error) {
if len(rs) == 0 {
return []byte("[]"), nil
}
return json.Marshal(rs)
}

func (rs *ResourceSelectors) Scan(val interface{}) error {
if val == nil {
*rs = ResourceSelectors{}
return nil
}
var ba []byte
switch v := val.(type) {
case []byte:
ba = v
default:
return errors.New(fmt.Sprint("Failed to unmarshal ResourceSelectors value:", val))
}
return json.Unmarshal(ba, rs)
}

// GormDataType gorm common data type
func (rs ResourceSelectors) GormDataType() string {
return "resourceSelectors"
}

// GormDBDataType gorm db data type
func (ResourceSelectors) GormDBDataType(db *gorm.DB, field *schema.Field) string {
switch db.Dialector.Name() {
case SqliteType:
return jsonType
case PostgresType:
return jsonbType
case SQLServerType:
return nvarcharType
}
return ""
}

func (rs ResourceSelectors) GormValue(ctx context.Context, db *gorm.DB) clause.Expr {
data, _ := json.Marshal(rs)
return gorm.Expr("?", string(data))
}

func (cs ComponentChecks) Value() (driver.Value, error) {
if len(cs) == 0 {
return []byte("[]"), nil
Expand Down Expand Up @@ -115,47 +68,3 @@ func (cs ComponentChecks) GormValue(ctx context.Context, db *gorm.DB) clause.Exp
data, _ := json.Marshal(cs)
return gorm.Expr("?", string(data))
}

// Scan scan value into Jsonb, implements sql.Scanner interface
func (s Summary) Value() (driver.Value, error) {
return json.Marshal(s)
}

// Scan scan value into Jsonb, implements sql.Scanner interface
func (s *Summary) Scan(val interface{}) error {
if val == nil {
*s = Summary{}
return nil
}
var ba []byte
switch v := val.(type) {
case []byte:
ba = v
default:
return errors.New(fmt.Sprint("Failed to unmarshal properties value:", val))
}
err := json.Unmarshal(ba, s)
return err
}

// GormDataType gorm common data type
func (Summary) GormDataType() string {
return "summary"
}

func (Summary) GormDBDataType(db *gorm.DB, field *schema.Field) string {
switch db.Dialector.Name() {
case SqliteType:
return text
case PostgresType:
return jsonbType
case SQLServerType:
return nvarcharType
}
return ""
}

func (s Summary) GormValue(ctx context.Context, db *gorm.DB) clause.Expr {
data, _ := json.Marshal(s)
return gorm.Expr("?", data)
}
24 changes: 22 additions & 2 deletions api/v1/system_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package v1
import (
"fmt"

"github.com/flanksource/commons/hash"
"github.com/flanksource/duty/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -30,9 +32,12 @@ type TopologySpec struct {
// being applied to multiple components in the tree
Properties Properties `json:"properties,omitempty"`
// Lookup and associate config items with this component
Configs []Config `json:"configs,omitempty"`
Configs []types.ConfigQuery `json:"configs,omitempty"`
}

func (s Topology) String() string {
return fmt.Sprintf("%s/%s", s.Namespace, s.Name)
}
func (s Topology) IsEmpty() bool {
return len(s.Spec.Properties) == 0 && len(s.Spec.Components) == 0 && s.Name == ""
}
Expand Down Expand Up @@ -62,11 +67,16 @@ type NamespaceSelector struct {
}

type ComponentCheck struct {
Selector ResourceSelector `json:"selector,omitempty"`
Selector types.ResourceSelector `json:"selector,omitempty"`
// +kubebuilder:validation:XPreserveUnknownFields
Inline *CanarySpec `json:"inline,omitempty"`
}

func (c ComponentCheck) Hash() string {
h, _ := hash.JSONMD5Hash(c)
return h
}

type Config struct {
ID []string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Expand All @@ -75,6 +85,16 @@ type Config struct {
Tags map[string]string `json:"tags,omitempty"`
}

func (c Config) ToDuty() types.ConfigQuery {
return types.ConfigQuery{
ID: c.ID,
Type: c.Type,
Name: c.Name,
Namespace: c.Namespace,
Tags: c.Tags,
}
}

func (c Config) String() string {
s := c.Type
if c.Namespace != "" {
Expand Down
Loading