diff --git a/AGENT_VERSION b/AGENT_VERSION index efd57dbd25..3e4ce3f27f 100644 --- a/AGENT_VERSION +++ b/AGENT_VERSION @@ -1 +1 @@ -v0.6.22 \ No newline at end of file +v0.6.24 \ No newline at end of file diff --git a/assets/src/generated/graphql.ts b/assets/src/generated/graphql.ts index 452c9624fd..14a0395133 100644 --- a/assets/src/generated/graphql.ts +++ b/assets/src/generated/graphql.ts @@ -11715,6 +11715,8 @@ export type SentinelCheckIntegrationTestConfiguration = { __typename?: 'SentinelCheckIntegrationTestConfiguration'; /** a list of custom test cases to run for this check */ cases?: Maybe>>; + /** default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources) */ + default?: Maybe; /** the distro to run the check on */ distro?: Maybe; /** the format of the job */ @@ -11734,6 +11736,8 @@ export type SentinelCheckIntegrationTestConfiguration = { export type SentinelCheckIntegrationTestConfigurationAttributes = { /** a list of custom test cases to run for this check */ cases?: InputMaybe>>; + /** default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources) */ + default?: InputMaybe; /** the distro to run the check on */ distro?: InputMaybe; /** the format of the job output */ @@ -11750,6 +11754,37 @@ export type SentinelCheckIntegrationTestConfigurationAttributes = { tags?: InputMaybe; }; +export type SentinelCheckIntegrationTestDefaultAttributes = { + /** whether to ignore disable the default built-in test cases, in case you'd prefer to just use custom cases. */ + ignore?: InputMaybe; + /** annotations to apply to created namespaces, temporary namespaces are used for all test cases */ + namespaceAnnotations?: InputMaybe; + /** labels to apply to created namespaces, temporary namespaces are used for all test cases */ + namespaceLabels?: InputMaybe; + /** container image registry for test deployments */ + registry?: InputMaybe; + /** annotations to apply to test deployments, useful if you need to opt out of policy enforcement */ + resourceAnnotations?: InputMaybe; + /** labels to apply to test deployments, useful if you need to opt out of policy enforcement */ + resourceLabels?: InputMaybe; +}; + +export type SentinelCheckIntegrationTestDefaultConfiguration = { + __typename?: 'SentinelCheckIntegrationTestDefaultConfiguration'; + /** whether to ignore default namespace/deployment labels and annotations */ + ignore?: Maybe; + /** annotations to apply to created namespaces */ + namespaceAnnotations?: Maybe; + /** labels to apply to created namespaces */ + namespaceLabels?: Maybe; + /** container image registry for test deployments */ + registry?: Maybe; + /** annotations to apply to test deployments */ + resourceAnnotations?: Maybe; + /** labels to apply to test deployments */ + resourceLabels?: Maybe; +}; + export type SentinelCheckKubernetesConfiguration = { __typename?: 'SentinelCheckKubernetesConfiguration'; /** the api group to use when fetching this resource */ diff --git a/charts/console-rapid/charts/controller-0.0.169.tgz b/charts/console-rapid/charts/controller-0.0.169.tgz index ca803b0f34..5e8ea474e5 100644 Binary files a/charts/console-rapid/charts/controller-0.0.169.tgz and b/charts/console-rapid/charts/controller-0.0.169.tgz differ diff --git a/charts/console-rapid/charts/kas-0.3.1.tgz b/charts/console-rapid/charts/kas-0.3.1.tgz index 29e26bfdfa..ba53757dd1 100644 Binary files a/charts/console-rapid/charts/kas-0.3.1.tgz and b/charts/console-rapid/charts/kas-0.3.1.tgz differ diff --git a/charts/console/charts/controller-0.0.169.tgz b/charts/console/charts/controller-0.0.169.tgz index 33516b28e8..29ad3f870b 100644 Binary files a/charts/console/charts/controller-0.0.169.tgz and b/charts/console/charts/controller-0.0.169.tgz differ diff --git a/charts/console/charts/kas-0.3.1.tgz b/charts/console/charts/kas-0.3.1.tgz index ebfe9ad572..9bcfacc889 100644 Binary files a/charts/console/charts/kas-0.3.1.tgz and b/charts/console/charts/kas-0.3.1.tgz differ diff --git a/charts/console/templates/git-server.yaml b/charts/console/templates/git-server.yaml index 18f5f00808..6b56fdaef6 100644 --- a/charts/console/templates/git-server.yaml +++ b/charts/console/templates/git-server.yaml @@ -1,4 +1,4 @@ -{{- if .Values.gitServer.enabled }} +{{- if or .Values.gitServer.enabled .Values.console.config.airgap }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/charts/console/templates/secrets.yaml b/charts/console/templates/secrets.yaml index 785040a305..d560ccd9af 100644 --- a/charts/console/templates/secrets.yaml +++ b/charts/console/templates/secrets.yaml @@ -80,6 +80,12 @@ data: {{ if .Values.console.config.agentHelmValues }} CONSOLE_AGENT_HELM_VALUES: {{ .Values.console.config.agentHelmValues | toYaml | b64enc | quote }} {{ end }} +{{ if .Values.console.config.licenseKey }} + CONSOLE_LICENSE_KEY: {{ .Values.console.config.licenseKey | b64enc | quote }} +{{ end }} +{{ if .Values.console.config.adminEmails }} + CONSOLE_ADMIN_EMAILS: {{ .Values.console.config.adminEmails | join "," | b64enc | quote }} +{{ end }} {{ if .Values.cloud.pgRootCert }} --- apiVersion: v1 diff --git a/charts/console/values.yaml b/charts/console/values.yaml index e361f6f61e..95c45daec8 100644 --- a/charts/console/values.yaml +++ b/charts/console/values.yaml @@ -75,6 +75,12 @@ console: # agentHelmValues is used to configure the helm values for the agent on bootstrap. To configure them post-install, utilize the DeploymentSettings CR in our management cluster API. agentHelmValues: ~ + + # licenseKey is used to configure the license key for the Plural Console for airgapped installations. + licenseKey: ~ + + # adminEmails is a list of emails which will be auto-configured as admins in the console. + adminEmails: [] # customOidc is used to configure custom oidc authentication for the console. customOidc: diff --git a/charts/controller/crds/deployments.plural.sh_sentinels.yaml b/charts/controller/crds/deployments.plural.sh_sentinels.yaml index 82233568b0..ee05700957 100644 --- a/charts/controller/crds/deployments.plural.sh_sentinels.yaml +++ b/charts/controller/crds/deployments.plural.sh_sentinels.yaml @@ -188,6 +188,52 @@ spec: - type type: object type: array + default: + description: Default configures default test cases and + global behavior (e.g. namespace labels and annotations + for created resources). + properties: + ignore: + description: Ignore disables default integration + test cases, useful if you'd prefer to just use + custom test cases exclusively. + type: boolean + namespaceAnnotations: + additionalProperties: + type: string + description: NamespaceAnnotations annotations to + apply to created namespaces (test cases run in + temporary namespaces to ensure cleanup is seamless). + type: object + namespaceLabels: + additionalProperties: + type: string + description: NamespaceLabels labels to apply to + created namespaces (test cases run in temporary + namespaces to ensure cleanup is seamless). + type: object + registry: + description: Registry container image registry for + test deployments. Image names an tags will still + be preserved + type: string + resourceAnnotations: + additionalProperties: + type: string + description: ResourceAnnotations annotations to + apply to test resources within a namespace (this + is useful if you need to sidestep policy enforcement + for test resources). + type: object + resourceLabels: + additionalProperties: + type: string + description: ResourceLabels labels to apply to test + resources within a namespace (this is useful if + you need to sidestep policy enforcement for test + resources). + type: object + type: object distro: description: the distro to run the check on enum: @@ -243,7 +289,10 @@ spec: type: string type: object jobSpec: - description: the job to run for this check + description: The job to run for this check. We expect + there to at least be one container named `default` + that includes the sentinel go test code. It's also + recommended to not allow retries on the job. properties: annotations: additionalProperties: diff --git a/config/prod.exs b/config/prod.exs index 2ac3591cae..7854180d03 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -2,6 +2,10 @@ import Config config :console, :initialize, true +config :hackney, + max_connections: 150, + max_per_host: 20 + config :console, ConsoleWeb.Endpoint, adapter: Bandit.PhoenixAdapter, http: [ diff --git a/go/client/models_gen.go b/go/client/models_gen.go index cad18b41d9..79e9113a7d 100644 --- a/go/client/models_gen.go +++ b/go/client/models_gen.go @@ -7105,6 +7105,8 @@ type SentinelCheckIntegrationTestConfiguration struct { Format SentinelRunJobFormat `json:"format"` // the gotestsum configuration to use for this check Gotestsum *SentinelCheckGotestsumConfiguration `json:"gotestsum,omitempty"` + // default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources) + Default *SentinelCheckIntegrationTestDefaultConfiguration `json:"default,omitempty"` // a list of custom test cases to run for this check Cases []*SentinelCheckIntegrationTestCaseConfiguration `json:"cases,omitempty"` } @@ -7126,6 +7128,38 @@ type SentinelCheckIntegrationTestConfigurationAttributes struct { Format SentinelRunJobFormat `json:"format"` // the gotestsum configuration to use for this check Gotestsum *SentinelCheckGotestsumAttributes `json:"gotestsum,omitempty"` + // default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources) + Default *SentinelCheckIntegrationTestDefaultAttributes `json:"default,omitempty"` +} + +type SentinelCheckIntegrationTestDefaultAttributes struct { + // whether to ignore disable the default built-in test cases, in case you'd prefer to just use custom cases. + Ignore *bool `json:"ignore,omitempty"` + // labels to apply to created namespaces, temporary namespaces are used for all test cases + NamespaceLabels *string `json:"namespaceLabels,omitempty"` + // annotations to apply to created namespaces, temporary namespaces are used for all test cases + NamespaceAnnotations *string `json:"namespaceAnnotations,omitempty"` + // container image registry for test deployments + Registry *string `json:"registry,omitempty"` + // annotations to apply to test deployments, useful if you need to opt out of policy enforcement + ResourceAnnotations *string `json:"resourceAnnotations,omitempty"` + // labels to apply to test deployments, useful if you need to opt out of policy enforcement + ResourceLabels *string `json:"resourceLabels,omitempty"` +} + +type SentinelCheckIntegrationTestDefaultConfiguration struct { + // whether to ignore default namespace/deployment labels and annotations + Ignore *bool `json:"ignore,omitempty"` + // labels to apply to created namespaces + NamespaceLabels map[string]any `json:"namespaceLabels,omitempty"` + // annotations to apply to created namespaces + NamespaceAnnotations map[string]any `json:"namespaceAnnotations,omitempty"` + // container image registry for test deployments + Registry *string `json:"registry,omitempty"` + // annotations to apply to test deployments + ResourceAnnotations map[string]any `json:"resourceAnnotations,omitempty"` + // labels to apply to test deployments + ResourceLabels map[string]any `json:"resourceLabels,omitempty"` } type SentinelCheckKubernetesConfiguration struct { diff --git a/go/controller/api/v1alpha1/sentinel_types.go b/go/controller/api/v1alpha1/sentinel_types.go index 36a113a68f..ac877a5750 100644 --- a/go/controller/api/v1alpha1/sentinel_types.go +++ b/go/controller/api/v1alpha1/sentinel_types.go @@ -71,7 +71,8 @@ type SentinelCheckIntegrationTestConfiguration struct { //+kubebuilder:validation:Enum=PLAINTEXT;JUNIT Format console.SentinelRunJobFormat `json:"format"` - // the job to run for this check + // The job to run for this check. We expect there to at least be one container named `default` that includes the sentinel go test code. It's also recommended to not allow retries on the job. + // +kubebuilder:validation:Optional Job *JobSpec `json:"jobSpec,omitempty"` // the configuration for the gotestsum test runner for this check @@ -80,9 +81,11 @@ type SentinelCheckIntegrationTestConfiguration struct { // the distro to run the check on //+kubebuilder:validation:Enum=GENERIC;EKS;AKS;GKE;RKE;K3S;OPENSHIFT + //+kubebuilder:validation:Optional Distro *console.ClusterDistro `json:"distro,omitempty"` // the cluster tags to select where to run this job + // +kubebuilder:validation:Optional Tags map[string]string `json:"tags,omitempty"` // RepositoryRef references a Git repository to use for this integration test. @@ -90,11 +93,45 @@ type SentinelCheckIntegrationTestConfiguration struct { RepositoryRef *corev1.ObjectReference `json:"repositoryRef,omitempty"` // The git location to use for this integration test. + // +kubebuilder:validation:Optional Git *GitRef `json:"git,omitempty"` + // Default configures default test cases and global behavior (e.g. namespace labels and annotations for created resources). + // +kubebuilder:validation:Optional + Default *SentinelCheckIntegrationTestDefault `json:"default,omitempty"` + + // A list of custom test cases to run for this check. These can provide yaml-configurable targeted cases of things like coredns, load balancers, pvcs, etc. + // +kubebuilder:validation:Optional Cases []SentinelCheckIntegrationTestCase `json:"cases,omitempty"` } +// SentinelCheckIntegrationTestDefault configures default integration test behavior: built-in test cases and labels/annotations applied to created namespaces and deployments. +type SentinelCheckIntegrationTestDefault struct { + // Ignore disables default integration test cases, useful if you'd prefer to just use custom test cases exclusively. + // +kubebuilder:validation:Optional + Ignore *bool `json:"ignore,omitempty"` + + // NamespaceLabels labels to apply to created namespaces (test cases run in temporary namespaces to ensure cleanup is seamless). + // +kubebuilder:validation:Optional + NamespaceLabels map[string]string `json:"namespaceLabels,omitempty"` + + // NamespaceAnnotations annotations to apply to created namespaces (test cases run in temporary namespaces to ensure cleanup is seamless). + // +kubebuilder:validation:Optional + NamespaceAnnotations map[string]string `json:"namespaceAnnotations,omitempty"` + + // Registry container image registry for test deployments. Image names an tags will still be preserved + // +kubebuilder:validation:Optional + Registry *string `json:"registry,omitempty"` + + // ResourceAnnotations annotations to apply to test resources within a namespace (this is useful if you need to sidestep policy enforcement for test resources). + // +kubebuilder:validation:Optional + ResourceAnnotations map[string]string `json:"resourceAnnotations,omitempty"` + + // ResourceLabels labels to apply to test resources within a namespace (this is useful if you need to sidestep policy enforcement for test resources). + // +kubebuilder:validation:Optional + ResourceLabels map[string]string `json:"resourceLabels,omitempty"` +} + type SentinelCheckIntegrationTestCase struct { // Type the type of test case to run //+kubebuilder:validation:Enum=COREDNS;LOADBALANCER;RAW;PVC diff --git a/go/controller/api/v1alpha1/zz_generated.deepcopy.go b/go/controller/api/v1alpha1/zz_generated.deepcopy.go index 6ed074267e..e3deb2ebf2 100644 --- a/go/controller/api/v1alpha1/zz_generated.deepcopy.go +++ b/go/controller/api/v1alpha1/zz_generated.deepcopy.go @@ -7523,6 +7523,11 @@ func (in *SentinelCheckIntegrationTestConfiguration) DeepCopyInto(out *SentinelC *out = new(GitRef) (*in).DeepCopyInto(*out) } + if in.Default != nil { + in, out := &in.Default, &out.Default + *out = new(SentinelCheckIntegrationTestDefault) + (*in).DeepCopyInto(*out) + } if in.Cases != nil { in, out := &in.Cases, &out.Cases *out = make([]SentinelCheckIntegrationTestCase, len(*in)) @@ -7542,6 +7547,59 @@ func (in *SentinelCheckIntegrationTestConfiguration) DeepCopy() *SentinelCheckIn return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SentinelCheckIntegrationTestDefault) DeepCopyInto(out *SentinelCheckIntegrationTestDefault) { + *out = *in + if in.Ignore != nil { + in, out := &in.Ignore, &out.Ignore + *out = new(bool) + **out = **in + } + if in.NamespaceLabels != nil { + in, out := &in.NamespaceLabels, &out.NamespaceLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NamespaceAnnotations != nil { + in, out := &in.NamespaceAnnotations, &out.NamespaceAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Registry != nil { + in, out := &in.Registry, &out.Registry + *out = new(string) + **out = **in + } + if in.ResourceAnnotations != nil { + in, out := &in.ResourceAnnotations, &out.ResourceAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ResourceLabels != nil { + in, out := &in.ResourceLabels, &out.ResourceLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SentinelCheckIntegrationTestDefault. +func (in *SentinelCheckIntegrationTestDefault) DeepCopy() *SentinelCheckIntegrationTestDefault { + if in == nil { + return nil + } + out := new(SentinelCheckIntegrationTestDefault) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SentinelCheckKubernetesConfiguration) DeepCopyInto(out *SentinelCheckKubernetesConfiguration) { *out = *in diff --git a/go/controller/config/crd/bases/deployments.plural.sh_sentinels.yaml b/go/controller/config/crd/bases/deployments.plural.sh_sentinels.yaml index 82233568b0..ee05700957 100644 --- a/go/controller/config/crd/bases/deployments.plural.sh_sentinels.yaml +++ b/go/controller/config/crd/bases/deployments.plural.sh_sentinels.yaml @@ -188,6 +188,52 @@ spec: - type type: object type: array + default: + description: Default configures default test cases and + global behavior (e.g. namespace labels and annotations + for created resources). + properties: + ignore: + description: Ignore disables default integration + test cases, useful if you'd prefer to just use + custom test cases exclusively. + type: boolean + namespaceAnnotations: + additionalProperties: + type: string + description: NamespaceAnnotations annotations to + apply to created namespaces (test cases run in + temporary namespaces to ensure cleanup is seamless). + type: object + namespaceLabels: + additionalProperties: + type: string + description: NamespaceLabels labels to apply to + created namespaces (test cases run in temporary + namespaces to ensure cleanup is seamless). + type: object + registry: + description: Registry container image registry for + test deployments. Image names an tags will still + be preserved + type: string + resourceAnnotations: + additionalProperties: + type: string + description: ResourceAnnotations annotations to + apply to test resources within a namespace (this + is useful if you need to sidestep policy enforcement + for test resources). + type: object + resourceLabels: + additionalProperties: + type: string + description: ResourceLabels labels to apply to test + resources within a namespace (this is useful if + you need to sidestep policy enforcement for test + resources). + type: object + type: object distro: description: the distro to run the check on enum: @@ -243,7 +289,10 @@ spec: type: string type: object jobSpec: - description: the job to run for this check + description: The job to run for this check. We expect + there to at least be one container named `default` + that includes the sentinel go test code. It's also + recommended to not allow retries on the job. properties: annotations: additionalProperties: diff --git a/go/controller/docs/api.md b/go/controller/docs/api.md index f412f9b147..9de6304b3e 100644 --- a/go/controller/docs/api.md +++ b/go/controller/docs/api.md @@ -4161,13 +4161,35 @@ _Appears in:_ | Field | Description | Default | Validation | | --- | --- | --- | --- | | `format` _[SentinelRunJobFormat](#sentinelrunjobformat)_ | the test output format of the job | | Enum: [PLAINTEXT JUNIT]
Required: \{\}
| -| `jobSpec` _[JobSpec](#jobspec)_ | the job to run for this check | | | +| `jobSpec` _[JobSpec](#jobspec)_ | The job to run for this check. We expect there to at least be one container named `default` that includes the sentinel go test code. It's also recommended to not allow retries on the job. | | Optional: \{\}
| | `gotestsum` _[SentinelCheckGotestsumConfiguration](#sentinelcheckgotestsumconfiguration)_ | the configuration for the gotestsum test runner for this check | | Optional: \{\}
| -| `distro` _[ClusterDistro](#clusterdistro)_ | the distro to run the check on | | Enum: [GENERIC EKS AKS GKE RKE K3S OPENSHIFT]
| -| `tags` _object (keys:string, values:string)_ | the cluster tags to select where to run this job | | | +| `distro` _[ClusterDistro](#clusterdistro)_ | the distro to run the check on | | Enum: [GENERIC EKS AKS GKE RKE K3S OPENSHIFT]
Optional: \{\}
| +| `tags` _object (keys:string, values:string)_ | the cluster tags to select where to run this job | | Optional: \{\}
| | `repositoryRef` _[ObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectreference-v1-core)_ | RepositoryRef references a Git repository to use for this integration test. | | Optional: \{\}
| -| `git` _[GitRef](#gitref)_ | The git location to use for this integration test. | | | -| `cases` _[SentinelCheckIntegrationTestCase](#sentinelcheckintegrationtestcase) array_ | | | | +| `git` _[GitRef](#gitref)_ | The git location to use for this integration test. | | Optional: \{\}
| +| `default` _[SentinelCheckIntegrationTestDefault](#sentinelcheckintegrationtestdefault)_ | Default configures default test cases and global behavior (e.g. namespace labels and annotations for created resources). | | Optional: \{\}
| +| `cases` _[SentinelCheckIntegrationTestCase](#sentinelcheckintegrationtestcase) array_ | A list of custom test cases to run for this check. These can provide yaml-configurable targeted cases of things like coredns, load balancers, pvcs, etc. | | Optional: \{\}
| + + +#### SentinelCheckIntegrationTestDefault + + + +SentinelCheckIntegrationTestDefault configures default integration test behavior: built-in test cases and labels/annotations applied to created namespaces and deployments. + + + +_Appears in:_ +- [SentinelCheckIntegrationTestConfiguration](#sentinelcheckintegrationtestconfiguration) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `ignore` _boolean_ | Ignore disables default integration test cases, useful if you'd prefer to just use custom test cases exclusively. | | Optional: \{\}
| +| `namespaceLabels` _object (keys:string, values:string)_ | NamespaceLabels labels to apply to created namespaces (test cases run in temporary namespaces to ensure cleanup is seamless). | | Optional: \{\}
| +| `namespaceAnnotations` _object (keys:string, values:string)_ | NamespaceAnnotations annotations to apply to created namespaces (test cases run in temporary namespaces to ensure cleanup is seamless). | | Optional: \{\}
| +| `registry` _string_ | Registry container image registry for test deployments. Image names an tags will still be preserved | | Optional: \{\}
| +| `resourceAnnotations` _object (keys:string, values:string)_ | ResourceAnnotations annotations to apply to test resources within a namespace (this is useful if you need to sidestep policy enforcement for test resources). | | Optional: \{\}
| +| `resourceLabels` _object (keys:string, values:string)_ | ResourceLabels labels to apply to test resources within a namespace (this is useful if you need to sidestep policy enforcement for test resources). | | Optional: \{\}
| #### SentinelCheckKubernetesConfiguration diff --git a/go/controller/internal/controller/sentinel_controller.go b/go/controller/internal/controller/sentinel_controller.go index ef1edd1f65..a94f7ef580 100644 --- a/go/controller/internal/controller/sentinel_controller.go +++ b/go/controller/internal/controller/sentinel_controller.go @@ -340,6 +340,14 @@ func (r *SentinelReconciler) buildIntegrationTestConfiguration(ctx context.Conte } } + if integrationTest.Default != nil { + defaultAttr, err := r.buildIntegrationTestDefaultAttributes(integrationTest.Default) + if err != nil { + return nil, err + } + config.Default = defaultAttr + } + if len(integrationTest.Cases) > 0 { cases, err := r.buildIntegrationTestCases(integrationTest.Cases) if err != nil { @@ -444,6 +452,42 @@ func (r *SentinelReconciler) buildLoadbalancerTestCaseAttributes(lb *v1alpha1.Se return lbAttr, nil } +func (r *SentinelReconciler) buildIntegrationTestDefaultAttributes(d *v1alpha1.SentinelCheckIntegrationTestDefault) (*console.SentinelCheckIntegrationTestDefaultAttributes, error) { + attr := &console.SentinelCheckIntegrationTestDefaultAttributes{ + Ignore: d.Ignore, + Registry: d.Registry, + } + if len(d.NamespaceLabels) > 0 { + b, err := json.Marshal(d.NamespaceLabels) + if err != nil { + return nil, err + } + attr.NamespaceLabels = lo.ToPtr(string(b)) + } + if len(d.NamespaceAnnotations) > 0 { + b, err := json.Marshal(d.NamespaceAnnotations) + if err != nil { + return nil, err + } + attr.NamespaceAnnotations = lo.ToPtr(string(b)) + } + if len(d.ResourceAnnotations) > 0 { + b, err := json.Marshal(d.ResourceAnnotations) + if err != nil { + return nil, err + } + attr.ResourceAnnotations = lo.ToPtr(string(b)) + } + if len(d.ResourceLabels) > 0 { + b, err := json.Marshal(d.ResourceLabels) + if err != nil { + return nil, err + } + attr.ResourceLabels = lo.ToPtr(string(b)) + } + return attr, nil +} + func (r *SentinelReconciler) getGitAttributes(sentinel *v1alpha1.Sentinel) *console.GitRefAttributes { if sentinel.Spec.Git == nil { return nil diff --git a/lib/console/ai/provider/anthropic.ex b/lib/console/ai/provider/anthropic.ex index 4836c85a1d..94b04de835 100644 --- a/lib/console/ai/provider/anthropic.ex +++ b/lib/console/ai/provider/anthropic.ex @@ -27,7 +27,7 @@ defmodule Console.AI.Anthropic do @max_tokens 8_000 @base_headers [{"content-type", "application/json"}] - @options [recv_timeout: :timer.minutes(5), timeout: :timer.minutes(5)] + @options [recv_timeout: :timer.minutes(5), timeout: :timer.minutes(5), hackney: [pool: :ai_pool]] defmodule Content do @type t :: %__MODULE__{} diff --git a/lib/console/ai/provider/openai.ex b/lib/console/ai/provider/openai.ex index cdc777c32c..0d14d199b7 100644 --- a/lib/console/ai/provider/openai.ex +++ b/lib/console/ai/provider/openai.ex @@ -21,7 +21,7 @@ defmodule Console.AI.OpenAI do @type t :: %__MODULE__{} - @options [recv_timeout: :timer.minutes(5), timeout: :timer.minutes(5)] + @options [recv_timeout: :timer.minutes(5), timeout: :timer.minutes(5), hackney: [pool: :ai_pool]] defmodule ToolCall do @type t :: %__MODULE__{} diff --git a/lib/console/application.ex b/lib/console/application.ex index 6e0ca4e832..c4d0522e25 100644 --- a/lib/console/application.ex +++ b/lib/console/application.ex @@ -30,6 +30,7 @@ defmodule Console.Application do {Registry, [keys: :unique, name: Console.Deployments.Helm.Agent.registry()]}, {Registry, [keys: :unique, name: Console.AI.MCP.Agent.registry()]}, {Registry, [keys: :unique, name: Console.AI.Agents]}, + :hackney_pool.child_spec(:ai_pool, [max_connections: 100, max_per_host: 100]), {Cluster.Supervisor, [topologies, [name: Console.ClusterSupervisor]]}, Console.Bootstrapper, Console.Deployments.Git.Supervisor, diff --git a/lib/console/deployments/init.ex b/lib/console/deployments/init.ex index 8697fa9c0f..60bf85ee55 100644 --- a/lib/console/deployments/init.ex +++ b/lib/console/deployments/init.ex @@ -23,6 +23,16 @@ defmodule Console.Deployments.Init do |> Map.put(:url, Git.artifacts_url()) |> Git.create_repository(bot) end) + |> add_operation(:settings, fn %{deploy_repo: drepo, artifacts_repo: arepo} -> + maybe_ai(%{ + name: "global", + artifact_repository_id: arepo.id, + deployer_repository_id: drepo.id, + }) + |> maybe_observability() + |> maybe_agent_helm_values() + |> Settings.create() + end) |> add_operation(:cluster, fn _ -> Clusters.create_cluster(%{ name: Console.conf(:cluster_name), @@ -50,16 +60,6 @@ defmodule Console.Deployments.Init do |> Repo.update() %{provider: provider} -> {:ok, provider} end) - |> add_operation(:settings, fn %{deploy_repo: drepo, artifacts_repo: arepo} -> - maybe_ai(%{ - name: "global", - artifact_repository_id: arepo.id, - deployer_repository_id: drepo.id, - }) - |> maybe_observability() - |> maybe_agent_helm_values() - |> Settings.create() - end) |> add_operation(:context, fn _ -> maybe_setup_context(bot) end) |> add_operation(:secret, fn _ -> ensure_secret(Console.cloud?()) end) |> execute() diff --git a/lib/console/graphql/deployments/sentinel.ex b/lib/console/graphql/deployments/sentinel.ex index 70be5d2c30..35f5f6c0de 100644 --- a/lib/console/graphql/deployments/sentinel.ex +++ b/lib/console/graphql/deployments/sentinel.ex @@ -62,6 +62,16 @@ defmodule Console.GraphQl.Deployments.Sentinel do field :tags, :json, description: "the cluster tags to select where to run this job" field :format, non_null(:sentinel_run_job_format), description: "the format of the job output" field :gotestsum, :sentinel_check_gotestsum_attributes, description: "the gotestsum configuration to use for this check" + field :default, :sentinel_check_integration_test_default_attributes, description: "default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources)" + end + + input_object :sentinel_check_integration_test_default_attributes do + field :ignore, :boolean, description: "whether to ignore disable the default built-in test cases, in case you'd prefer to just use custom cases." + field :namespace_labels, :json, description: "labels to apply to created namespaces, temporary namespaces are used for all test cases" + field :namespace_annotations, :json, description: "annotations to apply to created namespaces, temporary namespaces are used for all test cases" + field :registry, :string, description: "container image registry for test deployments" + field :resource_annotations, :json, description: "annotations to apply to test deployments, useful if you need to opt out of policy enforcement" + field :resource_labels, :json, description: "labels to apply to test deployments, useful if you need to opt out of policy enforcement" end input_object :sentinel_run_job_update_attributes do @@ -174,9 +184,19 @@ defmodule Console.GraphQl.Deployments.Sentinel do field :tags, :map, description: "the cluster tags to select where to run this job" field :format, non_null(:sentinel_run_job_format), description: "the format of the job" field :gotestsum, :sentinel_check_gotestsum_configuration, description: "the gotestsum configuration to use for this check" + field :default, :sentinel_check_integration_test_default_configuration, description: "default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources)" field :cases, list_of(:sentinel_check_integration_test_case_configuration), description: "a list of custom test cases to run for this check" end + object :sentinel_check_integration_test_default_configuration do + field :ignore, :boolean, description: "whether to ignore default namespace/deployment labels and annotations" + field :namespace_labels, :map, description: "labels to apply to created namespaces" + field :namespace_annotations, :map, description: "annotations to apply to created namespaces" + field :registry, :string, description: "container image registry for test deployments" + field :resource_annotations, :map, description: "annotations to apply to test deployments" + field :resource_labels, :map, description: "labels to apply to test deployments" + end + object :sentinel_check_gotestsum_configuration do field :p, :string, description: "the value of the p flag for gotestsum" field :parallel, :string, description: "the value of the parallel flag for gotestsum" diff --git a/lib/console/schema/sentinel.ex b/lib/console/schema/sentinel.ex index 1b8693321f..fdc522ead7 100644 --- a/lib/console/schema/sentinel.ex +++ b/lib/console/schema/sentinel.ex @@ -65,6 +65,16 @@ defmodule Console.Schema.Sentinel do field :parallel, :string end + embeds_one :default, DefaultConfiguration, on_replace: :update do + field :ignore, :boolean, default: false + field :namespace_labels, :map + field :namespace_annotations, :map + + field :registry, :string + field :resource_annotations, :map + field :resource_labels, :map + end + embeds_many :cases, IntegrationTestCase, on_replace: :delete do field :type, IntegrationTestCaseType field :name, :string @@ -198,6 +208,7 @@ defmodule Console.Schema.Sentinel do |> cast_embed(:git) |> cast_embed(:gotestsum, with: &gotestsum_changeset/2) |> cast_embed(:cases, with: &integration_test_case_changeset/2) + |> cast_embed(:default, with: &default_changeset/2) |> validate_required(~w(format)a) end @@ -216,6 +227,11 @@ defmodule Console.Schema.Sentinel do |> validate_required(~w(type name)a) end + defp default_changeset(model, attrs) do + model + |> cast(attrs, ~w(ignore namespace_labels namespace_annotations registry resource_annotations resource_labels)a) + end + defp coredns_changeset(model, attrs) do model |> cast(attrs, ~w(dial_fqdns delay retries)a) diff --git a/lib/console/schema/sentinel_run_job.ex b/lib/console/schema/sentinel_run_job.ex index 314b2506dd..ef09727ae2 100644 --- a/lib/console/schema/sentinel_run_job.ex +++ b/lib/console/schema/sentinel_run_job.ex @@ -29,8 +29,8 @@ defmodule Console.Schema.SentinelRunJob do embeds_one :git, Service.Git, on_replace: :update - belongs_to :repository, GitRepository - belongs_to :cluster, Cluster + belongs_to :repository, GitRepository + belongs_to :cluster, Cluster belongs_to :sentinel_run, SentinelRun timestamps() diff --git a/priv/agent-chart.tgz b/priv/agent-chart.tgz index cd41895115..124718660c 100644 Binary files a/priv/agent-chart.tgz and b/priv/agent-chart.tgz differ diff --git a/schema/schema.graphql b/schema/schema.graphql index 948aebfdf0..66ec937837 100644 --- a/schema/schema.graphql +++ b/schema/schema.graphql @@ -2547,6 +2547,29 @@ input SentinelCheckIntegrationTestConfigurationAttributes { "the gotestsum configuration to use for this check" gotestsum: SentinelCheckGotestsumAttributes + + "default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources)" + default: SentinelCheckIntegrationTestDefaultAttributes +} + +input SentinelCheckIntegrationTestDefaultAttributes { + "whether to ignore disable the default built-in test cases, in case you'd prefer to just use custom cases." + ignore: Boolean + + "labels to apply to created namespaces, temporary namespaces are used for all test cases" + namespaceLabels: Json + + "annotations to apply to created namespaces, temporary namespaces are used for all test cases" + namespaceAnnotations: Json + + "container image registry for test deployments" + registry: String + + "annotations to apply to test deployments, useful if you need to opt out of policy enforcement" + resourceAnnotations: Json + + "labels to apply to test deployments, useful if you need to opt out of policy enforcement" + resourceLabels: Json } input SentinelRunJobUpdateAttributes { @@ -2772,10 +2795,33 @@ type SentinelCheckIntegrationTestConfiguration { "the gotestsum configuration to use for this check" gotestsum: SentinelCheckGotestsumConfiguration + "default configuration for integration test runs: default test cases and global behavior (e.g. namespace labels and annotations for created resources)" + default: SentinelCheckIntegrationTestDefaultConfiguration + "a list of custom test cases to run for this check" cases: [SentinelCheckIntegrationTestCaseConfiguration] } +type SentinelCheckIntegrationTestDefaultConfiguration { + "whether to ignore default namespace\/deployment labels and annotations" + ignore: Boolean + + "labels to apply to created namespaces" + namespaceLabels: Map + + "annotations to apply to created namespaces" + namespaceAnnotations: Map + + "container image registry for test deployments" + registry: String + + "annotations to apply to test deployments" + resourceAnnotations: Map + + "labels to apply to test deployments" + resourceLabels: Map +} + type SentinelCheckGotestsumConfiguration { "the value of the p flag for gotestsum" p: String diff --git a/test/console/deployments/sentinel_test.exs b/test/console/deployments/sentinel_test.exs index 332122fd0e..f969f1ded3 100644 --- a/test/console/deployments/sentinel_test.exs +++ b/test/console/deployments/sentinel_test.exs @@ -101,6 +101,18 @@ defmodule Console.Deployments.SentinelTest do assert refetch(sentinel).last_run_at end + test "it can run a sentinel with a crontab" do + user = insert(:user) + project = insert(:project, write_bindings: [%{user_id: user.id}]) + sentinel = insert(:sentinel, project: project, crontab: "*/5 * * * *") + + {:ok, run} = Sentinels.run_sentinel(sentinel.id, user) + + assert run.sentinel_id == sentinel.id + + assert refetch(sentinel).next_run_at + end + test "non project readers cannot run a sentinel" do user = insert(:user) project = insert(:project)