diff --git a/assets/src/generated/graphql.ts b/assets/src/generated/graphql.ts index 84d58d22ce..7b3d7f7767 100644 --- a/assets/src/generated/graphql.ts +++ b/assets/src/generated/graphql.ts @@ -4846,6 +4846,8 @@ export type PolicyConstraintEdge = { /** Configuration for applying policy enforcement to a stack */ export type PolicyEngine = { __typename?: 'PolicyEngine'; + /** the maximum allowed severity without failing the stack run */ + maxSeverity?: Maybe; /** the policy engine to use with this stack */ type: PolicyEngineType; }; diff --git a/charts/controller/crds/deployments.plural.sh_infrastructurestacks.yaml b/charts/controller/crds/deployments.plural.sh_infrastructurestacks.yaml index 62d6331385..f3fa1b5c5a 100644 --- a/charts/controller/crds/deployments.plural.sh_infrastructurestacks.yaml +++ b/charts/controller/crds/deployments.plural.sh_infrastructurestacks.yaml @@ -8376,6 +8376,29 @@ spec: - observabilityProviderRef type: object type: array + policyEngine: + description: PolicyEngine is a configuration for applying policy enforcement + to a stack. + properties: + maxSeverity: + description: MaxSeverity is the maximum allowed severity without + failing the stack run + enum: + - UNKNOWN + - LOW + - MEDIUM + - HIGH + - CRITICAL + - NONE + type: string + type: + description: Type is the policy engine to use with this stack + enum: + - TRIVY + type: string + required: + - type + type: object projectRef: description: |- ProjectRef references project this stack belongs to. diff --git a/go/client/client.go b/go/client/client.go index 7b5d2ad41e..2809dffac2 100644 --- a/go/client/client.go +++ b/go/client/client.go @@ -3617,7 +3617,8 @@ func (t *InfrastructureStackStatusFragment) GetStatus() *StackStatus { } type PolicyEngineFragment struct { - Type PolicyEngineType "json:\"type\" graphql:\"type\"" + Type PolicyEngineType "json:\"type\" graphql:\"type\"" + MaxSeverity *VulnSeverity "json:\"maxSeverity,omitempty\" graphql:\"maxSeverity\"" } func (t *PolicyEngineFragment) GetType() *PolicyEngineType { @@ -3626,6 +3627,12 @@ func (t *PolicyEngineFragment) GetType() *PolicyEngineType { } return &t.Type } +func (t *PolicyEngineFragment) GetMaxSeverity() *VulnSeverity { + if t == nil { + t = &PolicyEngineFragment{} + } + return t.MaxSeverity +} type InfrastructureStackFragment struct { ID *string "json:\"id,omitempty\" graphql:\"id\"" @@ -4299,6 +4306,7 @@ type StackViolationCauseFragment struct { Start int64 "json:\"start\" graphql:\"start\"" End int64 "json:\"end\" graphql:\"end\"" Resource string "json:\"resource\" graphql:\"resource\"" + Filename *string "json:\"filename,omitempty\" graphql:\"filename\"" Lines []*StackViolationCauseLineFragment "json:\"lines,omitempty\" graphql:\"lines\"" } @@ -4320,6 +4328,12 @@ func (t *StackViolationCauseFragment) GetResource() string { } return t.Resource } +func (t *StackViolationCauseFragment) GetFilename() *string { + if t == nil { + t = &StackViolationCauseFragment{} + } + return t.Filename +} func (t *StackViolationCauseFragment) GetLines() []*StackViolationCauseLineFragment { if t == nil { t = &StackViolationCauseFragment{} @@ -26503,6 +26517,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -26535,6 +26550,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } @@ -26912,6 +26928,7 @@ fragment UserFragment on User { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } ` @@ -27275,6 +27292,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -27307,6 +27325,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } @@ -27580,6 +27599,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -27612,6 +27632,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } @@ -27885,6 +27906,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -27917,6 +27939,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } @@ -28154,6 +28177,7 @@ fragment UserFragment on User { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } ` @@ -28354,6 +28378,7 @@ fragment UserFragment on User { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } ` @@ -28609,6 +28634,7 @@ fragment UserFragment on User { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } ` @@ -29278,6 +29304,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -29310,6 +29337,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } @@ -29587,6 +29615,7 @@ fragment GroupFragment on Group { } fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment RunStepFragment on RunStep { id @@ -29619,6 +29648,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ... StackViolationCauseLineFragment } diff --git a/go/client/graph/stack.graphql b/go/client/graph/stack.graphql index ad46b85b1f..83869d0452 100644 --- a/go/client/graph/stack.graphql +++ b/go/client/graph/stack.graphql @@ -24,6 +24,7 @@ fragment InfrastructureStackStatusFragment on InfrastructureStack { fragment PolicyEngineFragment on PolicyEngine { type + maxSeverity } fragment InfrastructureStackFragment on InfrastructureStack { @@ -125,6 +126,7 @@ fragment StackViolationCauseFragment on StackViolationCause { start end resource + filename lines { ...StackViolationCauseLineFragment } } diff --git a/go/client/models_gen.go b/go/client/models_gen.go index 03f3e31804..1b2798a40b 100644 --- a/go/client/models_gen.go +++ b/go/client/models_gen.go @@ -4016,6 +4016,8 @@ type PolicyConstraintEdge struct { type PolicyEngine struct { // the policy engine to use with this stack Type PolicyEngineType `json:"type"` + // the maximum allowed severity without failing the stack run + MaxSeverity *VulnSeverity `json:"maxSeverity,omitempty"` } type PolicyEngineAttributes struct { diff --git a/go/controller/api/v1alpha1/infrastructurestack_types.go b/go/controller/api/v1alpha1/infrastructurestack_types.go index efeaa851b8..ee7fdf22dc 100644 --- a/go/controller/api/v1alpha1/infrastructurestack_types.go +++ b/go/controller/api/v1alpha1/infrastructurestack_types.go @@ -138,6 +138,10 @@ type InfrastructureStackSpec struct { // stack Type (except [console.StackTypeCustom]). // +kubebuilder:validation:Optional Variables *runtime.RawExtension `json:"variables,omitempty"` + + // PolicyEngine is a configuration for applying policy enforcement to a stack. + // +kubebuilder:validation:Optional + PolicyEngine *PolicyEngine `json:"policyEngine,omitempty"` } type StackFile struct { @@ -244,3 +248,26 @@ type ObservableMetric struct { // +kubebuilder:validation:Required ObservabilityProviderRef corev1.ObjectReference `json:"observabilityProviderRef"` } + +type PolicyEngine struct { + // Type is the policy engine to use with this stack + // +kubebuilder:validation:Enum=TRIVY + // +kubebuilder:validation:Required + Type console.PolicyEngineType `json:"type"` + + // MaxSeverity is the maximum allowed severity without failing the stack run + // +kubebuilder:validation:Enum=UNKNOWN;LOW;MEDIUM;HIGH;CRITICAL;NONE + // +kubebuilder:validation:Optional + MaxSeverity *console.VulnSeverity `json:"maxSeverity,omitempty"` +} + +func (in *PolicyEngine) Attributes() *console.PolicyEngineAttributes { + if in == nil { + return nil + } + + return &console.PolicyEngineAttributes{ + Type: in.Type, + MaxSeverity: in.MaxSeverity, + } +} diff --git a/go/controller/api/v1alpha1/zz_generated.deepcopy.go b/go/controller/api/v1alpha1/zz_generated.deepcopy.go index 8efaafbef0..77aae74f42 100644 --- a/go/controller/api/v1alpha1/zz_generated.deepcopy.go +++ b/go/controller/api/v1alpha1/zz_generated.deepcopy.go @@ -2484,6 +2484,11 @@ func (in *InfrastructureStackSpec) DeepCopyInto(out *InfrastructureStackSpec) { *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } + if in.PolicyEngine != nil { + in, out := &in.PolicyEngine, &out.PolicyEngine + *out = new(PolicyEngine) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfrastructureStackSpec. @@ -3885,6 +3890,26 @@ func (in *PluralSinkConfiguration) DeepCopy() *PluralSinkConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyEngine) DeepCopyInto(out *PolicyEngine) { + *out = *in + if in.MaxSeverity != nil { + in, out := &in.MaxSeverity, &out.MaxSeverity + *out = new(client.VulnSeverity) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyEngine. +func (in *PolicyEngine) DeepCopy() *PolicyEngine { + if in == nil { + return nil + } + out := new(PolicyEngine) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PrAutomation) DeepCopyInto(out *PrAutomation) { *out = *in diff --git a/go/controller/config/crd/bases/deployments.plural.sh_infrastructurestacks.yaml b/go/controller/config/crd/bases/deployments.plural.sh_infrastructurestacks.yaml index 62d6331385..f3fa1b5c5a 100644 --- a/go/controller/config/crd/bases/deployments.plural.sh_infrastructurestacks.yaml +++ b/go/controller/config/crd/bases/deployments.plural.sh_infrastructurestacks.yaml @@ -8376,6 +8376,29 @@ spec: - observabilityProviderRef type: object type: array + policyEngine: + description: PolicyEngine is a configuration for applying policy enforcement + to a stack. + properties: + maxSeverity: + description: MaxSeverity is the maximum allowed severity without + failing the stack run + enum: + - UNKNOWN + - LOW + - MEDIUM + - HIGH + - CRITICAL + - NONE + type: string + type: + description: Type is the policy engine to use with this stack + enum: + - TRIVY + type: string + required: + - type + type: object projectRef: description: |- ProjectRef references project this stack belongs to. diff --git a/go/controller/docs/api.md b/go/controller/docs/api.md index 67c8b19184..225285904c 100644 --- a/go/controller/docs/api.md +++ b/go/controller/docs/api.md @@ -56,6 +56,7 @@ _Appears in:_ | --- | --- | --- | --- | | `model` _string_ | Model is the LLM model name to use. | | Optional: {}
| | `toolModel` _string_ | Model to use for tool calling, which is less frequent and often requires more advanced reasoning | | Optional: {}
| +| `embeddingModel` _string_ | Model to use for generating embeddings | | Optional: {}
| | `baseUrl` _string_ | A custom base url to use, for reimplementations of the same API scheme (for instance Together.ai uses the OpenAI API spec) | | Optional: {}
| | `tokenSecretRef` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#secretkeyselector-v1-core)_ | TokenSecretRef is a reference to the local secret holding the token to access
the configured AI provider. | | Required: {}
| @@ -77,6 +78,7 @@ _Appears in:_ | `tools` _[Tools](#tools)_ | | | Optional: {}
| | `provider` _[AiProvider](#aiprovider)_ | Provider defines which of the supported LLM providers should be used. | OPENAI | Enum: [OPENAI ANTHROPIC OLLAMA AZURE BEDROCK VERTEX]
Optional: {}
| | `toolProvider` _[AiProvider](#aiprovider)_ | Provider to use for tool calling, in case you want to use a different LLM more optimized to those tasks | | Enum: [OPENAI ANTHROPIC OLLAMA AZURE BEDROCK VERTEX]
Optional: {}
| +| `embeddingProvider` _[AiProvider](#aiprovider)_ | Provider to use for generating embeddings. Oftentimes foundational model providers do not have embeddings models, and it's better to simply use OpenAI. | | Enum: [OPENAI ANTHROPIC OLLAMA AZURE BEDROCK VERTEX]
Optional: {}
| | `openAI` _[AIProviderSettings](#aiprovidersettings)_ | OpenAI holds the OpenAI provider configuration. | | Optional: {}
| | `anthropic` _[AIProviderSettings](#aiprovidersettings)_ | Anthropic holds the Anthropic provider configuration. | | Optional: {}
| | `ollama` _[OllamaSettings](#ollamasettings)_ | Ollama holds configuration for a self-hosted Ollama deployment, more details available at https://github.com/ollama/ollama | | Optional: {}
| @@ -104,6 +106,7 @@ _Appears in:_ | `apiVersion` _string_ | The azure openai Data plane - inference api version to use, defaults to 2024-10-01-preview or the latest available | | Optional: {}
| | `model` _string_ | The OpenAi Model you wish to use. If not specified, Plural will provide a default | | Optional: {}
| | `toolModel` _string_ | Model to use for tool calling, which is less frequent and often requires more advanced reasoning | | Optional: {}
| +| `embeddingModel` _string_ | Model to use for generating embeddings | | Optional: {}
| | `tokenSecretRef` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#secretkeyselector-v1-core)_ | TokenSecretRef is a reference to the local secret holding the token to access
the configured AI provider. | | Required: {}
| @@ -821,6 +824,8 @@ _Appears in:_ | `ai` _[AISettings](#aisettings)_ | AI settings specifies a configuration for LLM provider clients | | Optional: {}
| | `logging` _[LoggingSettings](#loggingsettings)_ | Settings for connections to log aggregation datastores | | Optional: {}
| | `cost` _[CostSettings](#costsettings)_ | Settings for managing Plural's cost management features | | Optional: {}
| +| `deploymentRepositoryRef` _[NamespacedName](#namespacedname)_ | pointer to the deployment GIT repository to use | | Optional: {}
| +| `scaffoldsRepositoryRef` _[NamespacedName](#namespacedname)_ | pointer to the Scaffolds GIT repository to use | | Optional: {}
| #### ElasticsearchConnection @@ -1255,6 +1260,7 @@ _Appears in:_ | `observableMetrics` _[ObservableMetric](#observablemetric) array_ | | | Optional: {}
| | `tags` _object (keys:string, values:string)_ | Tags used to filter stacks. | | Optional: {}
| | `variables` _[RawExtension](https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime#RawExtension)_ | Variables represents a file with variables in the stack run environment.
It will be automatically passed to the specific tool depending on the
stack Type (except [console.StackTypeCustom]). | | Optional: {}
| +| `policyEngine` _[PolicyEngine](#policyengine)_ | PolicyEngine is a configuration for applying policy enforcement to a stack. | | Optional: {}
| #### JobSpec @@ -1390,6 +1396,7 @@ with the addition of kubebuilder/json annotations for better schema support. _Appears in:_ +- [DeploymentSettingsSpec](#deploymentsettingsspec) - [ServiceHelm](#servicehelm) | Field | Description | Default | Validation | @@ -1969,6 +1976,23 @@ _Appears in:_ | `urgent` _boolean_ | Whether to immediately deliver the notification via SMTP | | Optional: {}
| +#### PolicyEngine + + + + + + + +_Appears in:_ +- [InfrastructureStackSpec](#infrastructurestackspec) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `type` _[PolicyEngineType](#policyenginetype)_ | Type is the policy engine to use with this stack | | Enum: [TRIVY]
Required: {}
| +| `maxSeverity` _[VulnSeverity](#vulnseverity)_ | MaxSeverity is the maximum allowed severity without failing the stack run | | Enum: [UNKNOWN LOW MEDIUM HIGH CRITICAL NONE]
Optional: {}
| + + #### PrAutomation diff --git a/go/controller/internal/controller/infrastructurestack_controller.go b/go/controller/internal/controller/infrastructurestack_controller.go index 9383a8a5d6..37472d83c5 100644 --- a/go/controller/internal/controller/infrastructurestack_controller.go +++ b/go/controller/internal/controller/infrastructurestack_controller.go @@ -307,6 +307,7 @@ func (r *InfrastructureStackReconciler) getStackAttributes( Configuration: r.stackConfigurationAttributes(stack.Spec.Configuration), Approval: stack.Spec.Approval, Files: make([]*console.StackFileAttributes, 0), + PolicyEngine: stack.Spec.PolicyEngine.Attributes(), } if stack.Spec.ScmConnectionRef != nil { diff --git a/go/controller/internal/test/mocks/ConsoleClient_mock.go b/go/controller/internal/test/mocks/ConsoleClient_mock.go index d83fed6fdd..7feb9f110a 100644 --- a/go/controller/internal/test/mocks/ConsoleClient_mock.go +++ b/go/controller/internal/test/mocks/ConsoleClient_mock.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. +// Code generated by mockery v2.45.1. DO NOT EDIT. package mocks diff --git a/lib/console/graphql/deployments/stack.ex b/lib/console/graphql/deployments/stack.ex index 361c195476..b4f445431e 100644 --- a/lib/console/graphql/deployments/stack.ex +++ b/lib/console/graphql/deployments/stack.ex @@ -263,7 +263,8 @@ defmodule Console.GraphQl.Deployments.Stack do @desc "Configuration for applying policy enforcement to a stack" object :policy_engine do - field :type, non_null(:policy_engine_type), description: "the policy engine to use with this stack" + field :type, non_null(:policy_engine_type), description: "the policy engine to use with this stack" + field :max_severity, :vuln_severity, description: "the maximum allowed severity without failing the stack run" end object :stack_hook do diff --git a/plural/helm/console/crds/deployments.plural.sh_infrastructurestacks.yaml b/plural/helm/console/crds/deployments.plural.sh_infrastructurestacks.yaml index 62d6331385..f3fa1b5c5a 100644 --- a/plural/helm/console/crds/deployments.plural.sh_infrastructurestacks.yaml +++ b/plural/helm/console/crds/deployments.plural.sh_infrastructurestacks.yaml @@ -8376,6 +8376,29 @@ spec: - observabilityProviderRef type: object type: array + policyEngine: + description: PolicyEngine is a configuration for applying policy enforcement + to a stack. + properties: + maxSeverity: + description: MaxSeverity is the maximum allowed severity without + failing the stack run + enum: + - UNKNOWN + - LOW + - MEDIUM + - HIGH + - CRITICAL + - NONE + type: string + type: + description: Type is the policy engine to use with this stack + enum: + - TRIVY + type: string + required: + - type + type: object projectRef: description: |- ProjectRef references project this stack belongs to. diff --git a/schema/schema.graphql b/schema/schema.graphql index 22f4365cac..6732403214 100644 --- a/schema/schema.graphql +++ b/schema/schema.graphql @@ -2093,6 +2093,9 @@ type StackConfiguration { type PolicyEngine { "the policy engine to use with this stack" type: PolicyEngineType! + + "the maximum allowed severity without failing the stack run" + maxSeverity: VulnSeverity } type StackHook {