From ed1bdb1afd07a1baab3dda6ced1898b62b47b700 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 7 Oct 2025 13:25:50 -0500 Subject: [PATCH 01/90] wip Signed-off-by: Michael Montgomery --- .../v1alpha1/cloudconnectedmode_types.go | 110 +++++++ pkg/apis/cloudconnectedmode/v1alpha1/doc.go | 8 + .../v1alpha1/groupversion_info.go | 21 ++ .../cloudconnectedmode/v1alpha1/webhook.go | 104 +++++++ .../v1alpha1/webhook_test.go | 157 ++++++++++ .../v1alpha1/zz_generated.deepcopy.go | 289 ++++++++++++++++++ 6 files changed, 689 insertions(+) create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/doc.go create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/webhook.go create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go create mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go b/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go new file mode 100644 index 00000000000..187e9e2fc00 --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go @@ -0,0 +1,110 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + eslabel "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/label" + kblabel "github.com/elastic/cloud-on-k8s/v3/pkg/controller/kibana/label" +) + +const ( + // Kind is inferred from the struct name using reflection in SchemeBuilder.Register() + // we duplicate it as a constant here for practical purposes. + Kind = "CloudConnectedMode" + + unknownVersion = 0 +) + +func init() { + SchemeBuilder.Register(&CloudConnectedMode{}, &CloudConnectedModeList{}) +} + +// +kubebuilder:object:root=true + +// CloudConnectedMode represents a CloudConnectedMode resource in a Kubernetes cluster. +// +kubebuilder:resource:categories=elastic,shortName=ccm +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.readyCount",description="Resources configured" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +type CloudConnectedMode struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CloudConnectedModeSpec `json:"spec,omitempty"` + Status CloudConnectedModeStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// CloudConnectedModeList contains a list of CloudConnectedMode resources. +type CloudConnectedModeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []CloudConnectedMode `json:"items"` +} + +type CloudConnectedModeSpec struct { + ResourceSelector metav1.LabelSelector `json:"resourceSelector,omitempty"` + // Deprecated: SecureSettings only applies to Elasticsearch and is deprecated. It must be set per application instead. + // SecureSettings []commonv1.SecretSource `json:"secureSettings,omitempty"` + // Elasticsearch ElasticsearchConfigPolicySpec `json:"elasticsearch,omitempty"` + // Kibana KibanaConfigPolicySpec `json:"kibana,omitempty"` +} + +type ResourceType string + +const ( + ElasticsearchResourceType ResourceType = eslabel.Type + // KibanaResourceType ResourceType = kblabel.Type +) + +type CloudConnectedModeStatus struct { + // Resources is the number of resources to be configured. + Resources int `json:"resources,omitempty"` + // Ready is the number of resources successfully configured. + Ready int `json:"ready,omitempty"` + // Errors is the number of resources which have an incorrect configuration + Errors int `json:"errors,omitempty"` + // ReadyCount is a human representation of the number of resources successfully configured. + ReadyCount string `json:"readyCount,omitempty"` + // ObservedGeneration is the most recent generation observed for this CloudConnectedMode. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +func NewStatus(scp CloudConnectedMode) CloudConnectedModeStatus { + status := CloudConnectedModeStatus{ + // Details: map[ResourceType]map[string]ResourcePolicyStatus{}, + // Phase: ReadyPhase, + ObservedGeneration: scp.Generation, + } + // status.setReadyCount() + return status +} + +// Update updates the policy status from its resources statuses. +func (s *CloudConnectedModeStatus) Update() { +} + +// IsDegraded returns true when the CloudConnectedModeStatus resource is degraded compared to the previous status. +// func (s CloudConnectedModeStatus) IsDegraded(prev CloudConnectedModeStatus) bool { +// return prev.Phase == ReadyPhase && s.Phase != ReadyPhase && s.Phase != ApplyingChangesPhase +// } + +// IsMarkedForDeletion returns true if the CloudConnectedMode resource is going to be deleted. +func (p *CloudConnectedMode) IsMarkedForDeletion() bool { + return !p.DeletionTimestamp.IsZero() +} + +func (s CloudConnectedModeStatus) getResourceStatusKey(nsn types.NamespacedName) string { + return nsn.String() +} diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/doc.go b/pkg/apis/cloudconnectedmode/v1alpha1/doc.go new file mode 100644 index 00000000000..1c7886a5150 --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/doc.go @@ -0,0 +1,8 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +// Package v1alpha1 contains API schema definitions for managing StackConfigPolicy resources. +// +kubebuilder:object:generate=true +// +groupName=cloudconnected.k8s.elastic.co +package v1alpha1 diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go b/pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go new file mode 100644 index 00000000000..316f2716a0b --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go @@ -0,0 +1,21 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "cloudconnected.k8s.elastic.co", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go b/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go new file mode 100644 index 00000000000..fb70058ec87 --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go @@ -0,0 +1,104 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" + + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/webhook/admission" + ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" +) + +const ( + // webhookPath is the HTTP path for the CloudConnected validating webhook. + webhookPath = "/validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes" + SpecSecureSettingsDeprecated = "spec.SecureSettings is deprecated, secure settings must be set per application" +) + +var ( + groupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: Kind} + validationLog = ulog.Log.WithName("ccm-v1alpha1-validation") + + defaultChecks = []func(*CloudConnectedMode) field.ErrorList{ + checkNoUnknownFields, + checkNameLength, + validSettings, + } +) + +// +kubebuilder:webhook:path=/validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes,mutating=false,failurePolicy=ignore,groups=cloudconnected.k8s.elastic.co,resources=cloudconnectedmodes,verbs=create;update,versions=v1alpha1,name=elastic-ccm-validation-v1alpha1.k8s.elastic.co,sideEffects=None,admissionReviewVersions=v1,matchPolicy=Exact + +var _ admission.Validator = &CloudConnectedMode{} + +// ValidateCreate is called by the validating webhook to validate the create operation. +// Satisfies the webhook.Validator interface. +func (p *CloudConnectedMode) ValidateCreate() (admission.Warnings, error) { + validationLog.V(1).Info("Validate create", "name", p.Name) + return p.validate() +} + +// ValidateDelete is called by the validating webhook to validate the delete operation. +// Satisfies the webhook.Validator interface. +func (p *CloudConnectedMode) ValidateDelete() (admission.Warnings, error) { + validationLog.V(1).Info("Validate delete", "name", p.Name) + return nil, nil +} + +// ValidateUpdate is called by the validating webhook to validate the update operation. +// Satisfies the webhook.Validator interface. +func (p *CloudConnectedMode) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) { + validationLog.V(1).Info("Validate update", "name", p.Name) + return p.validate() +} + +// WebhookPath returns the HTTP path used by the validating webhook. +func (p *CloudConnectedMode) WebhookPath() string { + return webhookPath +} + +func (p *CloudConnectedMode) validate() (admission.Warnings, error) { + var errors field.ErrorList + + for _, dc := range defaultChecks { + if err := dc(p); err != nil { + errors = append(errors, err...) + } + } + + if len(errors) > 0 { + validationLog.V(1).Info("failed validation", "errors", errors) + return nil, apierrors.NewInvalid(groupKind, p.Name, errors) + } + return nil, nil +} + +func (p *CloudConnectedMode) GetWarnings() []string { + if p == nil { + return nil + } + return nil +} + +// func checkNoUnknownFields(policy *CloudConnectedMode) field.ErrorList { +// return commonv1.NoUnknownFields(policy, policy.ObjectMeta) +// } + +// func checkNameLength(policy *CloudConnectedMode) field.ErrorList { +// return commonv1.CheckNameLength(policy) +// } + +func validSettings(policy *CloudConnectedMode) field.ErrorList { + settingsCount := 0 + if settingsCount == 0 { + return field.ErrorList{field.Required(field.NewPath("spec").Child("elasticsearch"), "One out of Elasticsearch or Kibana settings is mandatory, both must not be empty")} + } + return nil +} diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go b/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go new file mode 100644 index 00000000000..8aae68bbd2b --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go @@ -0,0 +1,157 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1_test + +import ( + "encoding/json" + "strings" + "testing" + + "github.com/stretchr/testify/require" + admissionv1 "k8s.io/api/admission/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + policyv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/stackconfigpolicy/v1alpha1" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/test" +) + +func TestWebhook(t *testing.T) { + testCases := []test.ValidationWebhookTestCase{ + { + Name: "create-valid", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.Spec.Elasticsearch.SecretMounts = []policyv1alpha1.SecretMount{ + { + SecretName: "test1", + MountPath: "/usr/test1", + }, + { + SecretName: "test2", + MountPath: "/usr/test2", + }, + } + return serialize(t, m) + }, + Check: test.ValidationWebhookSucceeded, + }, + { + Name: "create-valid-kibana", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.Spec.Elasticsearch = policyv1alpha1.ElasticsearchConfigPolicySpec{} + m.Spec.Kibana = policyv1alpha1.KibanaConfigPolicySpec{ + Config: &commonv1.Config{Data: map[string]interface{}{"a": "b"}}, + } + return serialize(t, m) + }, + Check: test.ValidationWebhookSucceeded, + }, + { + Name: "unknown-field", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.SetAnnotations(map[string]string{ + corev1.LastAppliedConfigAnnotation: `{ + "metadata":{"name": "scp", "namespace": "default", "uid": "e7a18cfb-b017-475c-8da2-1ec941b1f285", "creationTimestamp":"2020-03-24T13:43:20Z" }, + "spec":{"unknown": "blurb"} + }`, + }) + return serialize(t, m) + }, + Check: test.ValidationWebhookFailed( + `"unknown": unknown field found in the kubectl.kubernetes.io/last-applied-configuration annotation is unknown`, + ), + }, + { + Name: "long-name", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.SetName(strings.Repeat("x", 100)) + return serialize(t, m) + }, + Check: test.ValidationWebhookFailed( + `metadata.name: Too long: may not be more than 36 bytes`, + ), + }, + { + Name: "no-settings", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.Spec.Elasticsearch = policyv1alpha1.ElasticsearchConfigPolicySpec{ + SnapshotRepositories: nil, + SnapshotLifecyclePolicies: &commonv1.Config{Data: nil}, + ClusterSettings: &commonv1.Config{Data: map[string]interface{}{}}, + } + return serialize(t, m) + }, + Check: test.ValidationWebhookFailed( + "One out of Elasticsearch or Kibana settings is mandatory, both must not be empty", + ), + }, + { + Name: "create-duplicate-mountpaths", + Operation: admissionv1.Create, + Object: func(t *testing.T, uid string) []byte { + t.Helper() + m := mkStackConfigPolicy(uid) + m.Spec.Elasticsearch.SecretMounts = []policyv1alpha1.SecretMount{ + { + SecretName: "test1", + MountPath: "/usr/test", + }, + { + SecretName: "test2", + MountPath: "/usr/test", + }, + } + return serialize(t, m) + }, + Check: test.ValidationWebhookFailed( + "SecretMounts cannot have duplicate mount paths", + ), + }, + } + + validator := &policyv1alpha1.StackConfigPolicy{} + gvk := metav1.GroupVersionKind{Group: policyv1alpha1.GroupVersion.Group, Version: policyv1alpha1.GroupVersion.Version, Kind: policyv1alpha1.Kind} + test.RunValidationWebhookTests(t, gvk, validator, testCases...) +} + +func mkStackConfigPolicy(uid string) *policyv1alpha1.StackConfigPolicy { + return &policyv1alpha1.StackConfigPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-policy-test", + UID: types.UID(uid), + }, + Spec: policyv1alpha1.StackConfigPolicySpec{ + Elasticsearch: policyv1alpha1.ElasticsearchConfigPolicySpec{ + ClusterSettings: &commonv1.Config{Data: map[string]interface{}{"a": "b"}}, + }, + }, + } +} + +func serialize(t *testing.T, policy *policyv1alpha1.StackConfigPolicy) []byte { + t.Helper() + + objBytes, err := json.Marshal(policy) + require.NoError(t, err) + + return objBytes +} diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..c5ddcf72048 --- /dev/null +++ b/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,289 @@ +//go:build !ignore_autogenerated + +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ElasticsearchConfigPolicySpec) DeepCopyInto(out *ElasticsearchConfigPolicySpec) { + *out = *in + if in.ClusterSettings != nil { + in, out := &in.ClusterSettings, &out.ClusterSettings + *out = (*in).DeepCopy() + } + if in.SnapshotRepositories != nil { + in, out := &in.SnapshotRepositories, &out.SnapshotRepositories + *out = (*in).DeepCopy() + } + if in.SnapshotLifecyclePolicies != nil { + in, out := &in.SnapshotLifecyclePolicies, &out.SnapshotLifecyclePolicies + *out = (*in).DeepCopy() + } + if in.SecurityRoleMappings != nil { + in, out := &in.SecurityRoleMappings, &out.SecurityRoleMappings + *out = (*in).DeepCopy() + } + if in.IndexLifecyclePolicies != nil { + in, out := &in.IndexLifecyclePolicies, &out.IndexLifecyclePolicies + *out = (*in).DeepCopy() + } + if in.IngestPipelines != nil { + in, out := &in.IngestPipelines, &out.IngestPipelines + *out = (*in).DeepCopy() + } + in.IndexTemplates.DeepCopyInto(&out.IndexTemplates) + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = (*in).DeepCopy() + } + if in.SecretMounts != nil { + in, out := &in.SecretMounts, &out.SecretMounts + *out = make([]SecretMount, len(*in)) + copy(*out, *in) + } + if in.SecureSettings != nil { + in, out := &in.SecureSettings, &out.SecureSettings + *out = make([]v1.SecretSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticsearchConfigPolicySpec. +func (in *ElasticsearchConfigPolicySpec) DeepCopy() *ElasticsearchConfigPolicySpec { + if in == nil { + return nil + } + out := new(ElasticsearchConfigPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IndexTemplates) DeepCopyInto(out *IndexTemplates) { + *out = *in + if in.ComponentTemplates != nil { + in, out := &in.ComponentTemplates, &out.ComponentTemplates + *out = (*in).DeepCopy() + } + if in.ComposableIndexTemplates != nil { + in, out := &in.ComposableIndexTemplates, &out.ComposableIndexTemplates + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IndexTemplates. +func (in *IndexTemplates) DeepCopy() *IndexTemplates { + if in == nil { + return nil + } + out := new(IndexTemplates) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KibanaConfigPolicySpec) DeepCopyInto(out *KibanaConfigPolicySpec) { + *out = *in + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = (*in).DeepCopy() + } + if in.SecureSettings != nil { + in, out := &in.SecureSettings, &out.SecureSettings + *out = make([]v1.SecretSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KibanaConfigPolicySpec. +func (in *KibanaConfigPolicySpec) DeepCopy() *KibanaConfigPolicySpec { + if in == nil { + return nil + } + out := new(KibanaConfigPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyStatusError) DeepCopyInto(out *PolicyStatusError) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyStatusError. +func (in *PolicyStatusError) DeepCopy() *PolicyStatusError { + if in == nil { + return nil + } + out := new(PolicyStatusError) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePolicyStatus) DeepCopyInto(out *ResourcePolicyStatus) { + *out = *in + out.Error = in.Error +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePolicyStatus. +func (in *ResourcePolicyStatus) DeepCopy() *ResourcePolicyStatus { + if in == nil { + return nil + } + out := new(ResourcePolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretMount) DeepCopyInto(out *SecretMount) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretMount. +func (in *SecretMount) DeepCopy() *SecretMount { + if in == nil { + return nil + } + out := new(SecretMount) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StackConfigPolicy) DeepCopyInto(out *StackConfigPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicy. +func (in *StackConfigPolicy) DeepCopy() *StackConfigPolicy { + if in == nil { + return nil + } + out := new(StackConfigPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *StackConfigPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StackConfigPolicyList) DeepCopyInto(out *StackConfigPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]StackConfigPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicyList. +func (in *StackConfigPolicyList) DeepCopy() *StackConfigPolicyList { + if in == nil { + return nil + } + out := new(StackConfigPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *StackConfigPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StackConfigPolicySpec) DeepCopyInto(out *StackConfigPolicySpec) { + *out = *in + in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) + if in.SecureSettings != nil { + in, out := &in.SecureSettings, &out.SecureSettings + *out = make([]v1.SecretSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Elasticsearch.DeepCopyInto(&out.Elasticsearch) + in.Kibana.DeepCopyInto(&out.Kibana) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicySpec. +func (in *StackConfigPolicySpec) DeepCopy() *StackConfigPolicySpec { + if in == nil { + return nil + } + out := new(StackConfigPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StackConfigPolicyStatus) DeepCopyInto(out *StackConfigPolicyStatus) { + *out = *in + if in.ResourcesStatuses != nil { + in, out := &in.ResourcesStatuses, &out.ResourcesStatuses + *out = make(map[string]ResourcePolicyStatus, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Details != nil { + in, out := &in.Details, &out.Details + *out = make(map[ResourceType]map[string]ResourcePolicyStatus, len(*in)) + for key, val := range *in { + var outVal map[string]ResourcePolicyStatus + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = make(map[string]ResourcePolicyStatus, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + (*out)[key] = outVal + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicyStatus. +func (in *StackConfigPolicyStatus) DeepCopy() *StackConfigPolicyStatus { + if in == nil { + return nil + } + out := new(StackConfigPolicyStatus) + in.DeepCopyInto(out) + return out +} From b439a1b8b146da3ef4275b9ea8f3d1ed47044485 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Sun, 30 Nov 2025 20:47:01 -0600 Subject: [PATCH 02/90] Adding skeleton Signed-off-by: Michael Montgomery --- NOTICE.txt | 384 +++++++++--------- cmd/manager/main.go | 5 + config/crds/v1/all-crds.yaml | 133 ++++++ ...ed.k8s.elastic.co_cloudconnectedmodes.yaml | 133 ++++++ config/crds/v1/resources/kustomization.yaml | 1 + config/webhook/manifests.yaml | 21 + .../eck-operator-crds/templates/all-crds.yaml | 140 +++++++ docs/reference/api-reference/main.md | 79 ++++ .../v1alpha1/cloudconnectedmode_types.go | 4 - .../cloudconnectedmode/v1alpha1/webhook.go | 20 +- .../v1alpha1/zz_generated.deepcopy.go | 226 +---------- .../cloudconnectedmode/controller.go | 229 +++++++++++ pkg/controller/common/scheme/scheme.go | 2 + 13 files changed, 964 insertions(+), 413 deletions(-) create mode 100644 config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml create mode 100644 pkg/controller/cloudconnectedmode/controller.go diff --git a/NOTICE.txt b/NOTICE.txt index d9b8df59afd..2fe7c3ca302 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -14,7 +14,7 @@ Version : v1.0.2 Time : 2025-05-07T20:15:06Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/dario.cat/mergo@v1.0.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/dario.cat/mergo@v1.0.2/LICENSE: Copyright (c) 2013 Dario Castañé. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -52,7 +52,7 @@ Version : v0.7.4 Time : 2025-07-10T02:38:34Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/!kim!machine!gun/automemlimit@v0.7.4/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!kim!machine!gun/automemlimit@v0.7.4/LICENSE: MIT License @@ -83,7 +83,7 @@ Version : v3.3.0 Time : 2024-08-29T20:12:44Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -112,7 +112,7 @@ Version : v4.0.0 Time : 2020-05-24T15:15:11Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/blang/semver/v4@v4.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/blang/semver/v4@v4.0.0/LICENSE: The MIT License @@ -144,7 +144,7 @@ Version : v1.1.2-0.20180830191138-d8f796af33cc Time : 2018-08-30T19:11:38Z Licence : ISC -Contents of probable licence file $GOMODCACHE/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: ISC License @@ -169,7 +169,7 @@ Version : v0.8.9-0.20250307075119-2a22403faaea Time : 2025-03-07T07:51:19Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-ucfg@v0.8.9-0.20250307075119-2a22403faaea/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-ucfg@v0.8.9-0.20250307075119-2a22403faaea/LICENSE: Apache License Version 2.0, January 2004 @@ -380,7 +380,7 @@ Version : v1.0.0 Time : 2017-03-27T23:54:44Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/ghodss/yaml@v1.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/ghodss/yaml@v1.0.0/LICENSE: The MIT License (MIT) @@ -440,7 +440,7 @@ Version : v0.5.14 Time : 2025-07-28T20:15:32Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/gkampitakis/go-snaps@v0.5.14/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/go-snaps@v0.5.14/LICENSE: MIT License @@ -471,7 +471,7 @@ Version : v1.4.3 Time : 2025-05-19T04:56:57Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v1.4.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/logr@v1.4.3/LICENSE: Apache License Version 2.0, January 2004 @@ -682,7 +682,7 @@ Version : v1.1.1 Time : 2024-06-23T16:27:23Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/go-test/deep@v1.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-test/deep@v1.1.1/LICENSE: MIT License @@ -713,7 +713,7 @@ Version : v1.0.3 Time : 2024-09-21T13:43:45Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/gobuffalo/flect@v1.0.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gobuffalo/flect@v1.0.3/LICENSE: The MIT License (MIT) @@ -744,7 +744,7 @@ Version : v0.7.0 Time : 2025-01-14T18:15:44Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/google/go-cmp@v0.7.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/go-cmp@v0.7.0/LICENSE: Copyright (c) 2017 The Go Authors. All rights reserved. @@ -781,7 +781,7 @@ Version : v0.20.6 Time : 2025-06-13T21:51:07Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/go-containerregistry@v0.20.6/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/go-containerregistry@v0.20.6/LICENSE: Apache License @@ -992,7 +992,7 @@ Version : v1.6.0 Time : 2024-01-23T18:54:04Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/google/uuid@v1.6.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/uuid@v1.6.0/LICENSE: Copyright (c) 2009,2014 Google Inc. All rights reserved. @@ -1029,7 +1029,7 @@ Version : v1.1.1 Time : 2021-03-11T20:17:12Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: Mozilla Public License, version 2.0 @@ -1392,7 +1392,7 @@ Version : v2.0.7 Time : 2023-09-21T18:26:40Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: Copyright (c) 2014 HashiCorp, Inc. @@ -1766,7 +1766,7 @@ Version : v1.21.0 Time : 2025-09-01T15:28:10Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/vault/api@v1.21.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/vault/api@v1.21.0/LICENSE: Copyright (c) 2015 HashiCorp, Inc. @@ -2141,7 +2141,7 @@ Version : v1.8.10 Time : 2025-04-09T19:30:57Z Licence : BSD-2-Clause -Contents of probable licence file $GOMODCACHE/github.com/magiconair/properties@v1.8.10/LICENSE.md: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/magiconair/properties@v1.8.10/LICENSE.md: Copyright (c) 2013-2020, Frank Schroeder @@ -2175,7 +2175,7 @@ Version : v0.9.1 Time : 2020-01-14T19:47:44Z Licence : BSD-2-Clause -Contents of probable licence file $GOMODCACHE/github.com/pkg/errors@v0.9.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pkg/errors@v0.9.1/LICENSE: Copyright (c) 2015, Dave Cheney All rights reserved. @@ -2208,7 +2208,7 @@ Version : v1.0.1-0.20181226105442-5d4384ee4fb2 Time : 2018-12-26T10:54:42Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: Copyright (c) 2013, Patrick Mezard All rights reserved. @@ -2245,7 +2245,7 @@ Version : v1.23.2 Time : 2025-09-05T14:03:59Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golang@v1.23.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/client_golang@v1.23.2/LICENSE: Apache License Version 2.0, January 2004 @@ -2456,7 +2456,7 @@ Version : v0.66.1 Time : 2025-09-05T07:53:47Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.66.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/common@v0.66.1/LICENSE: Apache License Version 2.0, January 2004 @@ -2667,7 +2667,7 @@ Version : v0.3.1 Time : 2024-06-25T00:17:20Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/sethvargo/go-password@v0.3.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sethvargo/go-password@v0.3.1/LICENSE: Copyright 2017 Seth Vargo @@ -2697,7 +2697,7 @@ Version : v1.10.1 Time : 2025-09-01T16:19:51Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/spf13/cobra@v1.10.1/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/cobra@v1.10.1/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -2881,7 +2881,7 @@ Version : v1.0.10 Time : 2025-09-02T06:08:29Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/spf13/pflag@v1.0.10/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/pflag@v1.0.10/LICENSE: Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -2919,7 +2919,7 @@ Version : v1.21.0 Time : 2025-09-08T16:56:14Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/spf13/viper@v1.21.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/viper@v1.21.0/LICENSE: The MIT License (MIT) @@ -2949,7 +2949,7 @@ Version : v1.11.1 Time : 2025-08-27T10:46:31Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/stretchr/testify@v1.11.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stretchr/testify@v1.11.1/LICENSE: MIT License @@ -2980,7 +2980,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasticsearch/v2@v2.7.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmelasticsearch/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3191,7 +3191,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp/v2@v2.7.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmhttp/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3402,7 +3402,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmzap/v2@v2.7.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmzap/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3613,7 +3613,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/v2@v2.7.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3824,7 +3824,7 @@ Version : v1.6.0 Time : 2024-09-23T17:47:22Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.uber.org/automaxprocs@v1.6.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/automaxprocs@v1.6.0/LICENSE: Copyright (c) 2017 Uber Technologies, Inc. @@ -3852,7 +3852,7 @@ Version : v1.27.0 Time : 2024-02-20T20:55:06Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.27.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE: Copyright (c) 2016-2017 Uber Technologies, Inc. @@ -3881,7 +3881,7 @@ Version : v0.42.0 Time : 2025-09-08T15:14:28Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.42.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/crypto@v0.42.0/LICENSE: Copyright 2009 The Go Authors. @@ -3918,7 +3918,7 @@ Version : v0.0.0-20240808152545-0cdaa3abc0fa Time : 2024-08-08T15:25:45Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: Copyright 2009 The Go Authors. @@ -3955,7 +3955,7 @@ Version : v3.0.1 Time : 2022-05-27T08:35:30Z Licence : MIT -Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v3@v3.0.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/yaml.v3@v3.0.1/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -4015,7 +4015,7 @@ Version : v0.34.1 Time : 2025-09-10T04:39:36Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/api@v0.34.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/api@v0.34.1/LICENSE: Apache License @@ -4227,7 +4227,7 @@ Version : v0.34.1 Time : 2025-08-16T07:57:26Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/apimachinery@v0.34.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apimachinery@v0.34.1/LICENSE: Apache License @@ -4439,7 +4439,7 @@ Version : v0.34.1 Time : 2025-09-10T04:55:33Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/client-go@v0.34.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/client-go@v0.34.1/LICENSE: Apache License @@ -4651,7 +4651,7 @@ Version : v2.130.1 Time : 2024-06-20T00:51:19Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/klog/v2@v2.130.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/klog/v2@v2.130.1/LICENSE: Apache License Version 2.0, January 2004 @@ -4852,7 +4852,7 @@ Version : v0.0.0-20250604170112-4c0f3b243397 Time : 2025-06-04T17:01:12Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: Apache License @@ -5064,7 +5064,7 @@ Version : v0.22.1 Time : 2025-09-05T13:19:27Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/controller-runtime@v0.22.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/LICENSE: Apache License Version 2.0, January 2004 @@ -5275,7 +5275,7 @@ Version : v0.19.0 Time : 2025-08-28T05:51:10Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5492,7 +5492,7 @@ Version : v0.24.0 Time : 2025-05-07T15:31:15Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/cel.dev/expr@v0.24.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/cel.dev/expr@v0.24.0/LICENSE: Apache License @@ -5704,7 +5704,7 @@ Version : v1.1.1 Time : 2021-02-04T20:06:53Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: Apache License @@ -5916,7 +5916,7 @@ Version : v3.3.0 Time : 2024-08-27T21:33:28Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: Copyright (C) 2014-2019, Matt Butcher and Matt Farina @@ -5945,7 +5945,7 @@ Version : v4.13.0 Time : 2023-05-19T05:49:53Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: Copyright (c) 2012-2023 The ANTLR Project. All rights reserved. @@ -5983,7 +5983,7 @@ Version : v1.0.0 Time : 2018-08-24T02:57:28Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/armon/go-radix@v1.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/armon/go-radix@v1.0.0/LICENSE: The MIT License (MIT) @@ -6013,7 +6013,7 @@ Version : v0.0.0-20160902184237-e75332964ef5 Time : 2016-09-02T18:42:37Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: The MIT License (MIT) @@ -6043,7 +6043,7 @@ Version : v1.0.1 Time : 2019-07-31T12:00:54Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/beorn7/perks@v1.0.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/beorn7/perks@v1.0.1/LICENSE: Copyright (C) 2013 Blake Mizerany @@ -6073,7 +6073,7 @@ Version : v4.3.0 Time : 2024-01-02T22:56:19Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: The MIT License (MIT) @@ -6103,7 +6103,7 @@ Version : v2.3.0 Time : 2024-04-04T20:00:10Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: Copyright (c) 2016 Caleb Spare @@ -6135,7 +6135,7 @@ Version : v0.16.3 Time : 2024-12-12T14:42:49Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: Apache License @@ -6347,7 +6347,7 @@ Version : v28.2.2+incompatible Time : 2025-05-30T09:39:08Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/docker/cli@v28.2.2+incompatible/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/cli@v28.2.2+incompatible/LICENSE: Apache License @@ -6548,7 +6548,7 @@ Version : v2.8.3+incompatible Time : 2023-10-02T17:09:30Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: Apache License Version 2.0, January 2004 @@ -6760,7 +6760,7 @@ Version : v0.9.3 Time : 2025-03-14T11:52:36Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: Copyright (c) 2016 David Calavera @@ -6790,7 +6790,7 @@ Version : v1.15.2 Time : 2025-03-25T02:52:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: Apache License @@ -7002,7 +7002,7 @@ Version : v1.0.2 Time : 2024-03-25T02:36:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: Apache License @@ -7214,7 +7214,7 @@ Version : v3.12.2 Time : 2025-02-26T09:20:34Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: Copyright (c) 2012,2013 Ernest Micklei @@ -7245,7 +7245,7 @@ Version : v5.6.0+incompatible Time : 2021-10-20T18:47:23Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7280,7 +7280,7 @@ Version : v5.9.11 Time : 2025-01-28T17:43:52Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7315,7 +7315,7 @@ Version : v1.18.0 Time : 2024-10-03T07:06:28Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/fatih/color@v1.18.0/LICENSE.md: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fatih/color@v1.18.0/LICENSE.md: The MIT License (MIT) @@ -7345,7 +7345,7 @@ Version : v1.0.4 Time : 2023-03-12T10:31:09Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) @@ -7374,7 +7374,7 @@ Version : v1.14.6 Time : 2023-08-01T06:27:26Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/frankban/quicktest@v1.14.6/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/frankban/quicktest@v1.14.6/LICENSE: MIT License @@ -7405,7 +7405,7 @@ Version : v1.9.0 Time : 2025-04-04T15:13:49Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: Copyright © 2012 The Go Authors. All rights reserved. Copyright © fsnotify Authors. All rights reserved. @@ -7440,7 +7440,7 @@ Version : v2.9.0 Time : 2025-07-14T04:00:34Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: MIT License @@ -7470,7 +7470,7 @@ Version : v0.3.2 Time : 2025-02-02T10:01:22Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: MIT License @@ -7501,7 +7501,7 @@ Version : v1.3.2 Time : 2023-02-18T11:30:13Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: Copyright (c) 2012-2016 The go-diff Authors. All rights reserved. @@ -7531,7 +7531,7 @@ Version : v4.1.1 Time : 2025-06-23T23:41:10Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: Apache License @@ -7743,7 +7743,7 @@ Version : v1.2.2 Time : 2021-12-14T08:00:35Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-logr/stdr@v1.2.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/stdr@v1.2.2/LICENSE: Apache License Version 2.0, January 2004 @@ -7954,7 +7954,7 @@ Version : v1.3.0 Time : 2023-11-03T09:58:42Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-logr/zapr@v1.3.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/zapr@v1.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -8165,7 +8165,7 @@ Version : v0.21.0 Time : 2024-03-09T18:18:34Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: Apache License @@ -8377,7 +8377,7 @@ Version : v0.21.0 Time : 2024-03-09T18:23:36Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: Apache License @@ -8589,7 +8589,7 @@ Version : v0.23.0 Time : 2024-03-09T18:11:11Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/go-openapi/swag@v0.23.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/swag@v0.23.0/LICENSE: Apache License @@ -8801,7 +8801,7 @@ Version : v3.0.0 Time : 2023-09-14T01:46:41Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -8830,7 +8830,7 @@ Version : v2.4.0 Time : 2025-07-15T08:59:08Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: The MIT License (MIT) @@ -8861,7 +8861,7 @@ Version : v1.18.0 Time : 2025-05-29T05:13:29Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/goccy/go-yaml@v1.18.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/goccy/go-yaml@v1.18.0/LICENSE: MIT License @@ -8892,7 +8892,7 @@ Version : v1.3.2 Time : 2021-01-10T08:01:47Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/gogo/protobuf@v1.3.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gogo/protobuf@v1.3.2/LICENSE: Copyright (c) 2013, The GoGo Authors. All rights reserved. @@ -8937,7 +8937,7 @@ Version : v1.5.4 Time : 2024-03-06T06:45:40Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/golang/protobuf@v1.5.4/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/golang/protobuf@v1.5.4/LICENSE: Copyright 2010 The Go Authors. All rights reserved. @@ -8975,7 +8975,7 @@ Version : v1.1.3 Time : 2024-08-21T16:26:17Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/btree@v1.1.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/btree@v1.1.3/LICENSE: Apache License @@ -9187,7 +9187,7 @@ Version : v0.26.0 Time : 2025-07-14T20:45:46Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/cel-go@v0.26.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/cel-go@v0.26.0/LICENSE: Apache License @@ -9430,7 +9430,7 @@ Version : v0.7.0 Time : 2025-06-26T15:23:00Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/gnostic-models@v0.7.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/gnostic-models@v0.7.0/LICENSE: Apache License @@ -9643,7 +9643,7 @@ Version : v1.2.0 Time : 2020-08-04T22:43:24Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/gofuzz@v1.2.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/gofuzz@v1.2.0/LICENSE: Apache License @@ -9855,7 +9855,7 @@ Version : v0.0.0-20241029153458-d1b30febd7db Time : 2024-10-29T15:34:58Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: Apache License @@ -10067,7 +10067,7 @@ Version : v1.5.4-0.20250319132907-e064f32e3674 Time : 2025-03-19T13:29:07Z Licence : BSD-2-Clause -Contents of probable licence file $GOMODCACHE/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. @@ -10099,7 +10099,7 @@ Version : v2.26.3 Time : 2025-03-04T17:40:45Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: Copyright (c) 2015, Gengo, Inc. All rights reserved. @@ -10136,7 +10136,7 @@ Version : v1.1.0 Time : 2020-07-14T15:51:01Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/errwrap@v1.1.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/errwrap@v1.1.0/LICENSE: Mozilla Public License, version 2.0 @@ -10500,7 +10500,7 @@ Version : v0.5.2 Time : 2021-02-03T18:51:13Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: Mozilla Public License, version 2.0 @@ -10873,7 +10873,7 @@ Version : v1.6.3 Time : 2024-04-01T20:03:54Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: Copyright (c) 2017 HashiCorp, Inc. @@ -10902,7 +10902,7 @@ Version : v0.7.8 Time : 2025-06-18T14:25:10Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: Copyright (c) 2015 HashiCorp, Inc. @@ -11277,7 +11277,7 @@ Version : v1.0.2 Time : 2019-12-10T09:55:28Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: Mozilla Public License, version 2.0 @@ -11650,7 +11650,7 @@ Version : v0.2.0 Time : 2025-03-06T22:34:24Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: Copyright (c) 2020 HashiCorp, Inc. @@ -12025,7 +12025,7 @@ Version : v0.1.2 Time : 2021-11-22T19:44:14Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: Mozilla Public License, version 2.0 @@ -12398,7 +12398,7 @@ Version : v1.0.7 Time : 2024-09-19T09:47:04Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: Copyright (c) 2016 HashiCorp, Inc. @@ -12783,7 +12783,7 @@ Version : v1.0.1-vault-7 Time : 2024-11-07T22:23:56Z Licence : MPL-2.0 -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: Mozilla Public License, version 2.0 @@ -13147,7 +13147,7 @@ Version : v1.5.0 Time : 2024-06-06T08:07:36Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/huandu/xstrings@v1.5.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/huandu/xstrings@v1.5.0/LICENSE: The MIT License (MIT) @@ -13179,7 +13179,7 @@ Version : v1.1.0 Time : 2022-11-27T22:01:53Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -13390,7 +13390,7 @@ Version : v1.0.0 Time : 2019-12-14T22:12:22Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/josharian/intern@v1.0.0/license.md: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/josharian/intern@v1.0.0/license.md: MIT License @@ -13421,7 +13421,7 @@ Version : v1.1.12 Time : 2021-09-11T02:17:26Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.12/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/json-iterator/go@v1.1.12/LICENSE: MIT License @@ -13452,7 +13452,7 @@ Version : v1.18.0 Time : 2025-02-19T09:26:03Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/klauspost/compress@v1.18.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/klauspost/compress@v1.18.0/LICENSE: Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. @@ -13766,7 +13766,7 @@ Version : v0.3.1 Time : 2022-08-29T23:03:05Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/kr/pretty@v0.3.1/License: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kr/pretty@v0.3.1/License: Copyright 2012 Keith Rarick @@ -13795,7 +13795,7 @@ Version : v0.2.0 Time : 2020-02-14T20:31:06Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/kr/text@v0.2.0/License: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kr/text@v0.2.0/License: Copyright 2012 Keith Rarick @@ -13824,7 +13824,7 @@ Version : v1.1.0 Time : 2019-05-05T01:16:37Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/kylelemons/godebug@v1.1.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kylelemons/godebug@v1.1.0/LICENSE: Apache License @@ -14036,7 +14036,7 @@ Version : v0.7.7 Time : 2021-02-06T19:00:08Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mailru/easyjson@v0.7.7/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mailru/easyjson@v0.7.7/LICENSE: Copyright (c) 2016 Mail.Ru Group @@ -14053,7 +14053,7 @@ Version : v1.1.1 Time : 2023-11-03T01:37:02Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/maruel/natural@v1.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/maruel/natural@v1.1.1/LICENSE: Apache License Version 2.0, January 2004 @@ -14264,7 +14264,7 @@ Version : v0.1.14 Time : 2025-01-10T08:29:27Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mattn/go-colorable@v0.1.14/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mattn/go-colorable@v0.1.14/LICENSE: The MIT License (MIT) @@ -14295,7 +14295,7 @@ Version : v0.0.20 Time : 2023-10-17T07:28:21Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mattn/go-isatty@v0.0.20/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mattn/go-isatty@v0.0.20/LICENSE: Copyright (c) Yasuhiro MATSUMOTO @@ -14314,7 +14314,7 @@ Version : v1.2.0 Time : 2021-05-05T17:08:07Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/copystructure@v1.2.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/copystructure@v1.2.0/LICENSE: The MIT License (MIT) @@ -14345,7 +14345,7 @@ Version : v1.1.0 Time : 2019-01-27T04:21:35Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: The MIT License (MIT) @@ -14376,7 +14376,7 @@ Version : v1.5.0 Time : 2022-04-20T22:31:31Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: The MIT License (MIT) @@ -14407,7 +14407,7 @@ Version : v1.0.2 Time : 2021-05-03T23:34:11Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: The MIT License (MIT) @@ -14438,7 +14438,7 @@ Version : v0.5.0 Time : 2024-07-23T13:25:06Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/moby/spdystream@v0.5.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/moby/spdystream@v0.5.0/LICENSE: Apache License @@ -14650,7 +14650,7 @@ Version : v0.0.0-20180306012644-bacd9c7ef1dd Time : 2018-03-06T01:26:44Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: Apache License Version 2.0, January 2004 @@ -14861,7 +14861,7 @@ Version : v1.0.3-0.20250322232337-35a7c28c31ee Time : 2025-03-22T23:23:37Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: Apache License Version 2.0, January 2004 @@ -15113,7 +15113,7 @@ Version : v0.0.0-20140419014527-cca7078d478f Time : 2014-04-19T01:45:27Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: Copyright (c) 2014 The Go-FlowRate Authors. All rights reserved. @@ -15152,7 +15152,7 @@ Version : v1.4.8 Time : 2021-02-07T16:08:07Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/nxadm/tail@v1.4.8/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/nxadm/tail@v1.4.8/LICENSE: # The MIT License (MIT) @@ -15183,7 +15183,7 @@ Version : v1.16.5 Time : 2021-10-11T17:27:58Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo@v1.16.5/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/ginkgo@v1.16.5/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15213,7 +15213,7 @@ Version : v2.22.0 Time : 2024-11-21T01:19:21Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15243,7 +15243,7 @@ Version : v1.38.1 Time : 2025-08-22T13:45:44Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/onsi/gomega@v1.38.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/gomega@v1.38.1/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15273,7 +15273,7 @@ Version : v1.0.0 Time : 2020-05-14T01:46:00Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/opencontainers/go-digest@v1.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/opencontainers/go-digest@v1.0.0/LICENSE: Apache License @@ -15475,7 +15475,7 @@ Version : v1.1.1 Time : 2025-02-24T17:26:57Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/opencontainers/image-spec@v1.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/opencontainers/image-spec@v1.1.1/LICENSE: Apache License @@ -15676,7 +15676,7 @@ Version : v0.0.0-20210728143218-7b4eea64cf58 Time : 2021-07-28T14:32:18Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: BSD 3-Clause License @@ -15715,7 +15715,7 @@ Version : v2.2.4 Time : 2025-04-07T11:11:38Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: The MIT License (MIT) @@ -15747,7 +15747,7 @@ Version : v1.1.0 Time : 2021-12-11T19:29:36Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/prashantv/gostub@v1.1.0/LICENSE.md: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prashantv/gostub@v1.1.0/LICENSE.md: The MIT License (MIT) @@ -15778,7 +15778,7 @@ Version : v0.6.2 Time : 2025-04-11T05:38:16Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model@v0.6.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/client_model@v0.6.2/LICENSE: Apache License Version 2.0, January 2004 @@ -15989,7 +15989,7 @@ Version : v0.16.1 Time : 2025-04-19T15:43:08Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.16.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/procfs@v0.16.1/LICENSE: Apache License Version 2.0, January 2004 @@ -16200,7 +16200,7 @@ Version : v1.13.1 Time : 2024-09-23T11:44:11Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: Copyright (c) 2018 The Go Authors. All rights reserved. @@ -16237,7 +16237,7 @@ Version : v1.0.0 Time : 2019-01-24T19:22:32Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/ryanuber/go-glob@v1.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/ryanuber/go-glob@v1.0.0/LICENSE: The MIT License (MIT) @@ -16268,7 +16268,7 @@ Version : v0.11.0 Time : 2025-09-08T16:42:20Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: Copyright (c) 2023 Márk Sági-Kazár @@ -16297,7 +16297,7 @@ Version : v1.4.0 Time : 2024-04-12T14:15:38Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/shopspring/decimal@v1.4.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/shopspring/decimal@v1.4.0/LICENSE: The MIT License (MIT) @@ -16352,7 +16352,7 @@ Version : v1.9.3 Time : 2023-05-21T12:59:35Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/sirupsen/logrus@v1.9.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sirupsen/logrus@v1.9.3/LICENSE: The MIT License (MIT) @@ -16383,7 +16383,7 @@ Version : v0.3.1-0.20240121214520-5f936abd7ae8 Time : 2024-01-21T21:45:20Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: MIT License @@ -16414,7 +16414,7 @@ Version : v1.15.0 Time : 2025-09-08T16:25:29Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/github.com/spf13/afero@v1.15.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/afero@v1.15.0/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -16598,7 +16598,7 @@ Version : v1.10.0 Time : 2025-09-08T16:45:31Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/spf13/cast@v1.10.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/cast@v1.10.0/LICENSE: The MIT License (MIT) @@ -16628,7 +16628,7 @@ Version : v1.3.0 Time : 2023-03-27T23:57:07Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/stoewer/go-strcase@v1.3.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stoewer/go-strcase@v1.3.0/LICENSE: The MIT License (MIT) @@ -16659,7 +16659,7 @@ Version : v0.5.2 Time : 2024-02-29T09:57:51Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/stretchr/objx@v0.5.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stretchr/objx@v0.5.2/LICENSE: The MIT License @@ -16691,7 +16691,7 @@ Version : v1.6.0 Time : 2023-08-15T12:05:45Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/subosito/gotenv@v1.6.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/subosito/gotenv@v1.6.0/LICENSE: The MIT License (MIT) @@ -16722,7 +16722,7 @@ Version : v1.18.0 Time : 2024-10-02T03:45:20Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/tidwall/gjson@v1.18.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/gjson@v1.18.0/LICENSE: The MIT License (MIT) @@ -16752,7 +16752,7 @@ Version : v1.1.1 Time : 2021-10-08T14:36:13Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/tidwall/match@v1.1.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/match@v1.1.1/LICENSE: The MIT License (MIT) @@ -16782,7 +16782,7 @@ Version : v1.2.1 Time : 2022-10-01T20:21:24Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/tidwall/pretty@v1.2.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/pretty@v1.2.1/LICENSE: The MIT License (MIT) @@ -16812,7 +16812,7 @@ Version : v1.2.5 Time : 2022-08-05T01:15:59Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/tidwall/sjson@v1.2.5/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/sjson@v1.2.5/LICENSE: The MIT License (MIT) @@ -16843,7 +16843,7 @@ Version : v0.12.1 Time : 2025-01-30T22:58:54Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/github.com/vbatts/tar-split@v0.12.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/vbatts/tar-split@v0.12.1/LICENSE: Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA @@ -16881,7 +16881,7 @@ Version : v0.8.4 Time : 2020-01-17T18:31:28Z Licence : MIT -Contents of probable licence file $GOMODCACHE/github.com/x448/float16@v0.8.4/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/x448/float16@v0.8.4/LICENSE: MIT License @@ -16913,7 +16913,7 @@ Version : v1.5.1 Time : 2025-05-06T14:56:09Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.elastic.co/fastjson@v1.5.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/fastjson@v1.5.1/LICENSE: Copyright 2018 Elasticsearch BV @@ -16946,7 +16946,7 @@ Version : v1.1.0 Time : 2024-12-05T17:49:43Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17157,7 +17157,7 @@ Version : v0.61.0 Time : 2025-05-22T14:29:43Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17368,7 +17368,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17579,7 +17579,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17790,7 +17790,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18001,7 +18001,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18212,7 +18212,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18423,7 +18423,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18634,7 +18634,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18845,7 +18845,7 @@ Version : v1.5.0 Time : 2025-01-06T12:02:47Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: Apache License Version 2.0, January 2004 @@ -19056,7 +19056,7 @@ Version : v1.3.0 Time : 2023-10-24T16:28:03Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.uber.org/goleak@v1.3.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/goleak@v1.3.0/LICENSE: The MIT License (MIT) @@ -19087,7 +19087,7 @@ Version : v1.11.0 Time : 2023-03-29T23:00:37Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.11.0/LICENSE.txt: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/multierr@v1.11.0/LICENSE.txt: Copyright (c) 2017-2021 Uber Technologies, Inc. @@ -19116,7 +19116,7 @@ Version : v2.4.2 Time : 2025-06-02T16:37:17Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/go.yaml.in/yaml/v2@v2.4.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.yaml.in/yaml/v2@v2.4.2/LICENSE: Apache License Version 2.0, January 2004 @@ -19327,7 +19327,7 @@ Version : v3.0.4 Time : 2025-06-29T14:09:51Z Licence : MIT -Contents of probable licence file $GOMODCACHE/go.yaml.in/yaml/v3@v3.0.4/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.yaml.in/yaml/v3@v3.0.4/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -19387,7 +19387,7 @@ Version : v0.27.0 Time : 2025-08-07T14:51:59Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/mod@v0.27.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/mod@v0.27.0/LICENSE: Copyright 2009 The Go Authors. @@ -19424,7 +19424,7 @@ Version : v0.43.0 Time : 2025-08-07T19:56:06Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/net@v0.43.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/net@v0.43.0/LICENSE: Copyright 2009 The Go Authors. @@ -19461,7 +19461,7 @@ Version : v0.30.0 Time : 2025-04-30T15:42:02Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/oauth2@v0.30.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/oauth2@v0.30.0/LICENSE: Copyright 2009 The Go Authors. @@ -19498,7 +19498,7 @@ Version : v0.17.0 Time : 2025-08-13T14:47:05Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/sync@v0.17.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/sync@v0.17.0/LICENSE: Copyright 2009 The Go Authors. @@ -19535,7 +19535,7 @@ Version : v0.36.0 Time : 2025-09-05T15:44:06Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/sys@v0.36.0/LICENSE: Copyright 2009 The Go Authors. @@ -19572,7 +19572,7 @@ Version : v0.35.0 Time : 2025-09-08T03:32:07Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.35.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/term@v0.35.0/LICENSE: Copyright 2009 The Go Authors. @@ -19609,7 +19609,7 @@ Version : v0.29.0 Time : 2025-09-08T03:32:21Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/text@v0.29.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/text@v0.29.0/LICENSE: Copyright 2009 The Go Authors. @@ -19646,7 +19646,7 @@ Version : v0.12.0 Time : 2025-06-04T19:36:50Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.12.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/time@v0.12.0/LICENSE: Copyright 2009 The Go Authors. @@ -19683,7 +19683,7 @@ Version : v0.36.0 Time : 2025-08-07T20:42:58Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/tools@v0.36.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools@v0.36.0/LICENSE: Copyright 2009 The Go Authors. @@ -19720,7 +19720,7 @@ Version : v0.1.0-deprecated Time : 2025-06-12T15:17:39Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19757,7 +19757,7 @@ Version : v0.1.1-deprecated Time : 2025-06-13T18:44:18Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19794,7 +19794,7 @@ Version : v2.4.0 Time : 2023-08-14T02:23:48Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -20006,7 +20006,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20218,7 +20218,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20430,7 +20430,7 @@ Version : v1.72.1 Time : 2025-05-14T09:00:17Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/google.golang.org/grpc@v1.72.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/grpc@v1.72.1/LICENSE: Apache License @@ -20642,7 +20642,7 @@ Version : v1.36.8 Time : 2025-08-20T14:38:26Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/google.golang.org/protobuf@v1.36.8/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/protobuf@v1.36.8/LICENSE: Copyright (c) 2018 The Go Authors. All rights reserved. @@ -20679,7 +20679,7 @@ Version : v1.0.0-20201130134442-10cb98267c6c Time : 2020-11-30T13:44:42Z Licence : BSD-2-Clause -Contents of probable licence file $GOMODCACHE/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: Gocheck - A rich testing framework for Go @@ -20714,7 +20714,7 @@ Version : v4.12.0 Time : 2021-10-21T16:40:42Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -20749,7 +20749,7 @@ Version : v0.9.1 Time : 2018-03-26T17:23:32Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/gopkg.in/inf.v0@v0.9.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/inf.v0@v0.9.1/LICENSE: Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go Authors. All rights reserved. @@ -20787,7 +20787,7 @@ Version : v1.0.0-20141024135613-dd632973f1e7 Time : 2014-10-24T13:56:13Z Licence : BSD-3-Clause -Contents of probable licence file $GOMODCACHE/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: tomb - support for clean goroutine termination in Go. @@ -20826,7 +20826,7 @@ Version : v2.4.0 Time : 2020-11-17T15:46:20Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v2@v2.4.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/yaml.v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -21037,7 +21037,7 @@ Version : v3.0.3 Time : 2020-09-27T20:53:12Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/gotest.tools/v3@v3.0.3/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gotest.tools/v3@v3.0.3/LICENSE: Copyright 2018 gotest.tools authors @@ -21060,7 +21060,7 @@ Version : v1.0.1 Time : 2023-10-24T16:34:31Z Licence : BSD-2-Clause -Contents of probable licence file $GOMODCACHE/howett.net/plist@v1.0.1/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/howett.net/plist@v1.0.1/LICENSE: Copyright (c) 2013, Dustin L. Howett. All rights reserved. @@ -21128,7 +21128,7 @@ Version : v0.34.0 Time : 2025-08-27T20:41:17Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/apiextensions-apiserver@v0.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apiextensions-apiserver@v0.34.0/LICENSE: Apache License @@ -21340,7 +21340,7 @@ Version : v0.34.0 Time : 2025-08-27T20:24:55Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/apiserver@v0.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apiserver@v0.34.0/LICENSE: Apache License @@ -21552,7 +21552,7 @@ Version : v0.34.0 Time : 2025-08-27T20:05:46Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/code-generator@v0.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/code-generator@v0.34.0/LICENSE: Apache License @@ -21764,7 +21764,7 @@ Version : v0.34.0 Time : 2025-08-27T20:09:10Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/component-base@v0.34.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/component-base@v0.34.0/LICENSE: Apache License @@ -21976,7 +21976,7 @@ Version : v2.0.0-20250604051438-85fd79dbfd9f Time : 2025-06-04T05:14:38Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: Apache License @@ -22188,7 +22188,7 @@ Version : v0.0.0-20250710124328-f3f2b991d03b Time : 2025-07-10T12:43:28Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: Apache License @@ -22400,7 +22400,7 @@ Version : v0.31.2 Time : 2025-02-07T00:45:56Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: Apache License Version 2.0, January 2004 @@ -22611,7 +22611,7 @@ Version : v0.0.0-20241014173422-cfa47c3a1cc8 Time : 2024-10-14T17:34:22Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: Files other than internal/golang/* licensed under: @@ -22859,7 +22859,7 @@ Version : v1.0.0 Time : 2025-03-04T18:23:53Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/randfill@v1.0.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/randfill@v1.0.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23071,7 +23071,7 @@ Version : v6.3.0 Time : 2025-07-16T20:34:24Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23282,7 +23282,7 @@ Version : v1.6.0 Time : 2025-07-24T18:12:28Z Licence : Apache-2.0 -Contents of probable licence file $GOMODCACHE/sigs.k8s.io/yaml@v1.6.0/LICENSE: +Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/yaml@v1.6.0/LICENSE: The MIT License (MIT) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 20e446da730..17d77b8d850 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -46,6 +46,7 @@ import ( apmv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1" apmv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1beta1" beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" + ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" esv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1beta1" entv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/enterprisesearch/v1" @@ -62,6 +63,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling" esavalidation "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling/elasticsearch/validation" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/beat" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/cloudconnectedmode" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container" commonlicense "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" @@ -911,6 +913,7 @@ func registerControllers(mgr manager.Manager, params operator.Parameters, access {name: "Agent", registerFunc: agent.Add}, {name: "Maps", registerFunc: maps.Add}, {name: "StackConfigPolicy", registerFunc: stackconfigpolicy.Add}, + {name: "CloudConnectedMode", registerFunc: cloudconnectedmode.Add}, {name: "Logstash", registerFunc: logstash.Add}, } @@ -1001,6 +1004,7 @@ func garbageCollectSoftOwnedSecrets(ctx context.Context, k8sClient k8s.Client) { agentv1alpha1.Kind: &agentv1alpha1.Agent{}, emsv1alpha1.Kind: &emsv1alpha1.ElasticMapsServer{}, policyv1alpha1.Kind: &policyv1alpha1.StackConfigPolicy{}, + ccmv1alpha1.Kind: &ccmv1alpha1.CloudConnectedMode{}, logstashv1alpha1.Kind: &logstashv1alpha1.Logstash{}, }); err != nil { log.Error(err, "Orphan secrets garbage collection failed, will be attempted again at next operator restart.") @@ -1044,6 +1048,7 @@ func setupWebhook( &kbv1beta1.Kibana{}, &emsv1alpha1.ElasticMapsServer{}, &policyv1alpha1.StackConfigPolicy{}, + &ccmv1alpha1.CloudConnectedMode{}, } for _, obj := range webhookObjects { commonwebhook.SetupValidatingWebhookWithConfig(&commonwebhook.Config{ diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index bd4e0635e4e..980102ecad0 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2833,6 +2833,139 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: cloudconnectedmodes.cloudconnected.k8s.elastic.co +spec: + group: cloudconnected.k8s.elastic.co + names: + categories: + - elastic + kind: CloudConnectedMode + listKind: CloudConnectedModeList + plural: cloudconnectedmodes + shortNames: + - ccm + singular: cloudconnectedmode + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: CloudConnectedMode represents a CloudConnectedMode resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + status: + properties: + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this CloudConnectedMode. + format: int64 + type: integer + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 diff --git a/config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml b/config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml new file mode 100644 index 00000000000..851e7ea0ea3 --- /dev/null +++ b/config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml @@ -0,0 +1,133 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: cloudconnectedmodes.cloudconnected.k8s.elastic.co +spec: + group: cloudconnected.k8s.elastic.co + names: + categories: + - elastic + kind: CloudConnectedMode + listKind: CloudConnectedModeList + plural: cloudconnectedmodes + shortNames: + - ccm + singular: cloudconnectedmode + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: CloudConnectedMode represents a CloudConnectedMode resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + status: + properties: + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this CloudConnectedMode. + format: int64 + type: integer + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crds/v1/resources/kustomization.yaml b/config/crds/v1/resources/kustomization.yaml index 1c750971ee9..4f2546f79fa 100644 --- a/config/crds/v1/resources/kustomization.yaml +++ b/config/crds/v1/resources/kustomization.yaml @@ -8,4 +8,5 @@ resources: - agent.k8s.elastic.co_agents.yaml - maps.k8s.elastic.co_elasticmapsservers.yaml - stackconfigpolicy.k8s.elastic.co_stackconfigpolicies.yaml + - cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml - logstash.k8s.elastic.co_logstashes.yaml diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 53187308b68..22f8e027826 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -88,6 +88,27 @@ webhooks: resources: - beats sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes + failurePolicy: Ignore + matchPolicy: Exact + name: elastic-ccm-validation-v1alpha1.k8s.elastic.co + rules: + - apiGroups: + - cloudconnected.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - cloudconnectedmodes + sideEffects: None - admissionReviewVersions: - v1 clientConfig: diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 97707a8ba80..a92e55be5ec 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2854,6 +2854,146 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: cloudconnectedmodes.cloudconnected.k8s.elastic.co +spec: + group: cloudconnected.k8s.elastic.co + names: + categories: + - elastic + kind: CloudConnectedMode + listKind: CloudConnectedModeList + plural: cloudconnectedmodes + shortNames: + - ccm + singular: cloudconnectedmode + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: CloudConnectedMode represents a CloudConnectedMode resource in + a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + resourceSelector: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + status: + properties: + errors: + description: Errors is the number of resources which have an incorrect + configuration + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this CloudConnectedMode. + format: int64 + type: integer + ready: + description: Ready is the number of resources successfully configured. + type: integer + readyCount: + description: ReadyCount is a human representation of the number of + resources successfully configured. + type: string + resources: + description: Resources is the number of resources to be configured. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 6e9c95059f7..9822829c89a 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -16,6 +16,7 @@ applies_to: * [apm.k8s.elastic.co/v1beta1](#apmk8selasticcov1beta1) * [autoscaling.k8s.elastic.co/v1alpha1](#autoscalingk8selasticcov1alpha1) * [beat.k8s.elastic.co/v1beta1](#beatk8selasticcov1beta1) +* [cloudconnected.k8s.elastic.co/v1alpha1](#cloudconnectedk8selasticcov1alpha1) * [common.k8s.elastic.co/v1](#commonk8selasticcov1) * [common.k8s.elastic.co/v1alpha1](#commonk8selasticcov1alpha1) * [common.k8s.elastic.co/v1beta1](#commonk8selasticcov1beta1) @@ -391,6 +392,84 @@ BeatSpec defines the desired state of a Beat. +% TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors +## cloudconnected.k8s.elastic.co/v1alpha1 [#cloudconnectedk8selasticcov1alpha1] + +Package v1alpha1 contains API schema definitions for managing StackConfigPolicy resources. + +### Resource Types +- [CloudConnectedMode](#cloudconnectedmode) +- [CloudConnectedModeList](#cloudconnectedmodelist) + + + +### CloudConnectedMode [#cloudconnectedmode] + +CloudConnectedMode represents a CloudConnectedMode resource in a Kubernetes cluster. + +:::{admonition} Appears In: +* [CloudConnectedModeList](#cloudconnectedmodelist) + +::: + +| Field | Description | +| --- | --- | +| *`apiVersion`* __string__ | `cloudconnected.k8s.elastic.co/v1alpha1` | +| *`kind`* __string__ | `CloudConnectedMode` | +| *`metadata`* __[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | +| *`spec`* __[CloudConnectedModeSpec](#cloudconnectedmodespec)__ | | +| *`status`* __[CloudConnectedModeStatus](#cloudconnectedmodestatus)__ | | + + +### CloudConnectedModeList [#cloudconnectedmodelist] + +CloudConnectedModeList contains a list of CloudConnectedMode resources. + + + +| Field | Description | +| --- | --- | +| *`apiVersion`* __string__ | `cloudconnected.k8s.elastic.co/v1alpha1` | +| *`kind`* __string__ | `CloudConnectedModeList` | +| *`metadata`* __[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#listmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | +| *`items`* __[CloudConnectedMode](#cloudconnectedmode) array__ | | + + +### CloudConnectedModeSpec [#cloudconnectedmodespec] + + + +:::{admonition} Appears In: +* [CloudConnectedMode](#cloudconnectedmode) + +::: + +| Field | Description | +| --- | --- | +| *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | | + + +### CloudConnectedModeStatus [#cloudconnectedmodestatus] + + + +:::{admonition} Appears In: +* [CloudConnectedMode](#cloudconnectedmode) + +::: + +| Field | Description | +| --- | --- | +| *`resources`* __integer__ | Resources is the number of resources to be configured. | +| *`ready`* __integer__ | Ready is the number of resources successfully configured. | +| *`errors`* __integer__ | Errors is the number of resources which have an incorrect configuration | +| *`readyCount`* __string__ | ReadyCount is a human representation of the number of resources successfully configured. | +| *`observedGeneration`* __integer__ | ObservedGeneration is the most recent generation observed for this CloudConnectedMode. | + + + + + % TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors ## common.k8s.elastic.co/v1 [#commonk8selasticcov1] diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go b/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go index 187e9e2fc00..ca23b75145b 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go +++ b/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go @@ -5,14 +5,10 @@ package v1alpha1 import ( - "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" eslabel "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/label" - kblabel "github.com/elastic/cloud-on-k8s/v3/pkg/controller/kibana/label" ) const ( diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go b/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go index fb70058ec87..e45d0699570 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go +++ b/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go @@ -5,8 +5,6 @@ package v1alpha1 import ( - "fmt" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -87,18 +85,18 @@ func (p *CloudConnectedMode) GetWarnings() []string { return nil } -// func checkNoUnknownFields(policy *CloudConnectedMode) field.ErrorList { -// return commonv1.NoUnknownFields(policy, policy.ObjectMeta) -// } +func checkNoUnknownFields(policy *CloudConnectedMode) field.ErrorList { + return commonv1.NoUnknownFields(policy, policy.ObjectMeta) +} -// func checkNameLength(policy *CloudConnectedMode) field.ErrorList { -// return commonv1.CheckNameLength(policy) -// } +func checkNameLength(policy *CloudConnectedMode) field.ErrorList { + return commonv1.CheckNameLength(policy) +} func validSettings(policy *CloudConnectedMode) field.ErrorList { - settingsCount := 0 - if settingsCount == 0 { - return field.ErrorList{field.Required(field.NewPath("spec").Child("elasticsearch"), "One out of Elasticsearch or Kibana settings is mandatory, both must not be empty")} + // Validate that ResourceSelector is not empty + if policy.Spec.ResourceSelector.MatchLabels == nil && len(policy.Spec.ResourceSelector.MatchExpressions) == 0 { + return field.ErrorList{field.Required(field.NewPath("spec").Child("resourceSelector"), "ResourceSelector must be specified with either matchLabels or matchExpressions")} } return nil } diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go index c5ddcf72048..28166a227cb 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go @@ -9,182 +9,30 @@ package v1alpha1 import ( - "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ElasticsearchConfigPolicySpec) DeepCopyInto(out *ElasticsearchConfigPolicySpec) { - *out = *in - if in.ClusterSettings != nil { - in, out := &in.ClusterSettings, &out.ClusterSettings - *out = (*in).DeepCopy() - } - if in.SnapshotRepositories != nil { - in, out := &in.SnapshotRepositories, &out.SnapshotRepositories - *out = (*in).DeepCopy() - } - if in.SnapshotLifecyclePolicies != nil { - in, out := &in.SnapshotLifecyclePolicies, &out.SnapshotLifecyclePolicies - *out = (*in).DeepCopy() - } - if in.SecurityRoleMappings != nil { - in, out := &in.SecurityRoleMappings, &out.SecurityRoleMappings - *out = (*in).DeepCopy() - } - if in.IndexLifecyclePolicies != nil { - in, out := &in.IndexLifecyclePolicies, &out.IndexLifecyclePolicies - *out = (*in).DeepCopy() - } - if in.IngestPipelines != nil { - in, out := &in.IngestPipelines, &out.IngestPipelines - *out = (*in).DeepCopy() - } - in.IndexTemplates.DeepCopyInto(&out.IndexTemplates) - if in.Config != nil { - in, out := &in.Config, &out.Config - *out = (*in).DeepCopy() - } - if in.SecretMounts != nil { - in, out := &in.SecretMounts, &out.SecretMounts - *out = make([]SecretMount, len(*in)) - copy(*out, *in) - } - if in.SecureSettings != nil { - in, out := &in.SecureSettings, &out.SecureSettings - *out = make([]v1.SecretSource, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticsearchConfigPolicySpec. -func (in *ElasticsearchConfigPolicySpec) DeepCopy() *ElasticsearchConfigPolicySpec { - if in == nil { - return nil - } - out := new(ElasticsearchConfigPolicySpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IndexTemplates) DeepCopyInto(out *IndexTemplates) { - *out = *in - if in.ComponentTemplates != nil { - in, out := &in.ComponentTemplates, &out.ComponentTemplates - *out = (*in).DeepCopy() - } - if in.ComposableIndexTemplates != nil { - in, out := &in.ComposableIndexTemplates, &out.ComposableIndexTemplates - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IndexTemplates. -func (in *IndexTemplates) DeepCopy() *IndexTemplates { - if in == nil { - return nil - } - out := new(IndexTemplates) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KibanaConfigPolicySpec) DeepCopyInto(out *KibanaConfigPolicySpec) { - *out = *in - if in.Config != nil { - in, out := &in.Config, &out.Config - *out = (*in).DeepCopy() - } - if in.SecureSettings != nil { - in, out := &in.SecureSettings, &out.SecureSettings - *out = make([]v1.SecretSource, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KibanaConfigPolicySpec. -func (in *KibanaConfigPolicySpec) DeepCopy() *KibanaConfigPolicySpec { - if in == nil { - return nil - } - out := new(KibanaConfigPolicySpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PolicyStatusError) DeepCopyInto(out *PolicyStatusError) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyStatusError. -func (in *PolicyStatusError) DeepCopy() *PolicyStatusError { - if in == nil { - return nil - } - out := new(PolicyStatusError) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourcePolicyStatus) DeepCopyInto(out *ResourcePolicyStatus) { - *out = *in - out.Error = in.Error -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePolicyStatus. -func (in *ResourcePolicyStatus) DeepCopy() *ResourcePolicyStatus { - if in == nil { - return nil - } - out := new(ResourcePolicyStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretMount) DeepCopyInto(out *SecretMount) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretMount. -func (in *SecretMount) DeepCopy() *SecretMount { - if in == nil { - return nil - } - out := new(SecretMount) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackConfigPolicy) DeepCopyInto(out *StackConfigPolicy) { +func (in *CloudConnectedMode) DeepCopyInto(out *CloudConnectedMode) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) + out.Status = in.Status } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicy. -func (in *StackConfigPolicy) DeepCopy() *StackConfigPolicy { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedMode. +func (in *CloudConnectedMode) DeepCopy() *CloudConnectedMode { if in == nil { return nil } - out := new(StackConfigPolicy) + out := new(CloudConnectedMode) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *StackConfigPolicy) DeepCopyObject() runtime.Object { +func (in *CloudConnectedMode) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -192,31 +40,31 @@ func (in *StackConfigPolicy) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackConfigPolicyList) DeepCopyInto(out *StackConfigPolicyList) { +func (in *CloudConnectedModeList) DeepCopyInto(out *CloudConnectedModeList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]StackConfigPolicy, len(*in)) + *out = make([]CloudConnectedMode, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicyList. -func (in *StackConfigPolicyList) DeepCopy() *StackConfigPolicyList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeList. +func (in *CloudConnectedModeList) DeepCopy() *CloudConnectedModeList { if in == nil { return nil } - out := new(StackConfigPolicyList) + out := new(CloudConnectedModeList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *StackConfigPolicyList) DeepCopyObject() runtime.Object { +func (in *CloudConnectedModeList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -224,66 +72,32 @@ func (in *StackConfigPolicyList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackConfigPolicySpec) DeepCopyInto(out *StackConfigPolicySpec) { +func (in *CloudConnectedModeSpec) DeepCopyInto(out *CloudConnectedModeSpec) { *out = *in in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) - if in.SecureSettings != nil { - in, out := &in.SecureSettings, &out.SecureSettings - *out = make([]v1.SecretSource, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - in.Elasticsearch.DeepCopyInto(&out.Elasticsearch) - in.Kibana.DeepCopyInto(&out.Kibana) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicySpec. -func (in *StackConfigPolicySpec) DeepCopy() *StackConfigPolicySpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeSpec. +func (in *CloudConnectedModeSpec) DeepCopy() *CloudConnectedModeSpec { if in == nil { return nil } - out := new(StackConfigPolicySpec) + out := new(CloudConnectedModeSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackConfigPolicyStatus) DeepCopyInto(out *StackConfigPolicyStatus) { +func (in *CloudConnectedModeStatus) DeepCopyInto(out *CloudConnectedModeStatus) { *out = *in - if in.ResourcesStatuses != nil { - in, out := &in.ResourcesStatuses, &out.ResourcesStatuses - *out = make(map[string]ResourcePolicyStatus, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Details != nil { - in, out := &in.Details, &out.Details - *out = make(map[ResourceType]map[string]ResourcePolicyStatus, len(*in)) - for key, val := range *in { - var outVal map[string]ResourcePolicyStatus - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make(map[string]ResourcePolicyStatus, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - (*out)[key] = outVal - } - } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackConfigPolicyStatus. -func (in *StackConfigPolicyStatus) DeepCopy() *StackConfigPolicyStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeStatus. +func (in *CloudConnectedModeStatus) DeepCopy() *CloudConnectedModeStatus { if in == nil { return nil } - out := new(StackConfigPolicyStatus) + out := new(CloudConnectedModeStatus) in.DeepCopyInto(out) return out } diff --git a/pkg/controller/cloudconnectedmode/controller.go b/pkg/controller/cloudconnectedmode/controller.go new file mode 100644 index 00000000000..7ace01022e1 --- /dev/null +++ b/pkg/controller/cloudconnectedmode/controller.go @@ -0,0 +1,229 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package cloudconnectedmode + +import ( + "context" + "sync/atomic" + "time" + + "go.elastic.co/apm/v2" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/tracing" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" +) + +const ( + controllerName = "cloudconnectedmode-controller" +) + +var ( + // defaultRequeue is the default requeue interval for this controller. + defaultRequeue = 30 * time.Second +) + +// Add creates a new CloudConnectedMode Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager, params operator.Parameters) error { + r := newReconciler(mgr, params) + c, err := common.NewController(mgr, controllerName, r, params) + if err != nil { + return err + } + return addWatches(mgr, c, r) +} + +// newReconciler returns a new reconcile.Reconciler of CloudConnectedMode. +func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileCloudConnectedMode { + k8sClient := mgr.GetClient() + return &ReconcileCloudConnectedMode{ + Client: k8sClient, + recorder: mgr.GetEventRecorderFor(controllerName), + licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), + params: params, + dynamicWatches: watches.NewDynamicWatches(), + } +} + +func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileCloudConnectedMode) error { + // watch for changes to CloudConnectedMode + if err := c.Watch(source.Kind(mgr.GetCache(), &ccmv1alpha1.CloudConnectedMode{}, &handler.TypedEnqueueRequestForObject[*ccmv1alpha1.CloudConnectedMode]{})); err != nil { + return err + } + + // watch Secrets soft owned by CloudConnectedMode + if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, reconcileRequestForSoftOwner())); err != nil { + return err + } + + // watch dynamically referenced secrets + return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets)) +} + +func reconcileRequestForSoftOwner() handler.TypedEventHandler[*corev1.Secret, reconcile.Request] { + return handler.TypedEnqueueRequestsFromMapFunc[*corev1.Secret](func(ctx context.Context, secret *corev1.Secret) []reconcile.Request { + softOwner, referenced := reconciler.SoftOwnerRefFromLabels(secret.GetLabels()) + if !referenced || softOwner.Kind != ccmv1alpha1.Kind { + return nil + } + return []reconcile.Request{ + {NamespacedName: types.NamespacedName{Namespace: softOwner.Namespace, Name: softOwner.Name}}, + } + }) +} + +var _ reconcile.Reconciler = &ReconcileCloudConnectedMode{} + +// ReconcileCloudConnectedMode reconciles a CloudConnectedMode object +type ReconcileCloudConnectedMode struct { + k8s.Client + recorder record.EventRecorder + licenseChecker license.Checker + params operator.Parameters + dynamicWatches watches.DynamicWatches + // iteration is the number of times this controller has run its Reconcile method + iteration uint64 +} + +// Reconcile reads that state of the cluster for a CloudConnectedMode object and makes changes based on the state read and what is +// in the CloudConnectedMode.Spec. +func (r *ReconcileCloudConnectedMode) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "ccm_name", request) + defer common.LogReconciliationRun(ulog.FromContext(ctx))() + defer tracing.EndContextTransaction(ctx) + + // retrieve the CloudConnectedMode resource + var ccm ccmv1alpha1.CloudConnectedMode + err := r.Client.Get(ctx, request.NamespacedName, &ccm) + if err != nil { + if apierrors.IsNotFound(err) { + return reconcile.Result{}, r.onDelete(ctx, + types.NamespacedName{ + Namespace: request.Namespace, + Name: request.Name, + }) + } + return reconcile.Result{}, tracing.CaptureError(ctx, err) + } + + // skip unmanaged resources + if common.IsUnmanaged(ctx, &ccm) { + ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") + return reconcile.Result{}, nil + } + + // the CloudConnectedMode will be deleted nothing to do other than remove the watches + if ccm.IsMarkedForDeletion() { + return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&ccm)) + } + + // main reconciliation logic + results, status := r.doReconcile(ctx, ccm) + + // update status + if err := r.updateStatus(ctx, ccm, status); err != nil { + if apierrors.IsConflict(err) { + return results.WithRequeue().Aggregate() + } + results.WithError(err) + } + + return results.Aggregate() +} + +func (r *ReconcileCloudConnectedMode) doReconcile(ctx context.Context, ccm ccmv1alpha1.CloudConnectedMode) (*reconciler.Results, ccmv1alpha1.CloudConnectedModeStatus) { + log := ulog.FromContext(ctx) + log.V(1).Info("Reconcile CloudConnectedMode") + + results := reconciler.NewResult(ctx) + status := ccmv1alpha1.NewStatus(ccm) + defer status.Update() + + // Enterprise license check + enabled, err := r.licenseChecker.EnterpriseFeaturesEnabled(ctx) + if err != nil { + return results.WithError(err), status + } + if !enabled { + msg := "CloudConnectedMode is an enterprise feature. Enterprise features are disabled" + log.Info(msg) + r.recorder.Eventf(&ccm, corev1.EventTypeWarning, events.EventReconciliationError, msg) + // we don't have a good way of watching for the license level to change so just requeue with a reasonably long delay + return results.WithRequeue(5 * time.Minute), status + } + + // run validation in case the webhook is disabled + if err := r.validate(ctx, &ccm); err != nil { + r.recorder.Eventf(&ccm, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) + return results.WithError(err), status + } + + // TODO: Add internal reconciliation logic here + // This is intentionally left empty as per requirements + + // requeue if not ready + // TODO: Update this based on actual status phase when implemented + results.WithRequeue(defaultRequeue) + + return results, status +} + +func (r *ReconcileCloudConnectedMode) validate(ctx context.Context, ccm *ccmv1alpha1.CloudConnectedMode) error { + span, vctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) + defer span.End() + + if _, err := ccm.ValidateCreate(); err != nil { + ulog.FromContext(ctx).Error(err, "Validation failed") + k8s.MaybeEmitErrorEvent(r.recorder, err, ccm, events.EventReasonValidation, err.Error()) + return tracing.CaptureError(vctx, err) + } + + return nil +} + +func (r *ReconcileCloudConnectedMode) updateStatus(ctx context.Context, ccm ccmv1alpha1.CloudConnectedMode, status ccmv1alpha1.CloudConnectedModeStatus) error { + span, _ := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) + defer span.End() + + if status.ObservedGeneration == ccm.Status.ObservedGeneration && + status.Resources == ccm.Status.Resources && + status.Ready == ccm.Status.Ready && + status.Errors == ccm.Status.Errors && + status.ReadyCount == ccm.Status.ReadyCount { + return nil // nothing to do + } + + ulog.FromContext(ctx).V(1).Info("Updating status", + "iteration", atomic.LoadUint64(&r.iteration), + "status", status, + ) + ccm.Status = status + return common.UpdateStatus(ctx, r.Client, &ccm) +} + +func (r *ReconcileCloudConnectedMode) onDelete(ctx context.Context, obj types.NamespacedName) error { + defer tracing.Span(&ctx)() + // Remove dynamic watches on secrets + // TODO: Add cleanup for any dynamic watches if needed + return reconciler.GarbageCollectSoftOwnedSecrets(ctx, r.Client, obj, ccmv1alpha1.Kind) +} + diff --git a/pkg/controller/common/scheme/scheme.go b/pkg/controller/common/scheme/scheme.go index f7c1544c08b..bc8b73e97fa 100644 --- a/pkg/controller/common/scheme/scheme.go +++ b/pkg/controller/common/scheme/scheme.go @@ -15,6 +15,7 @@ import ( agentv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/agent/v1alpha1" apmv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1" apmv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1beta1" + ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" easv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoscaling/v1alpha1" beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" @@ -57,6 +58,7 @@ func SetupScheme() { agentv1alpha1.AddToScheme, emsv1alpha1.AddToScheme, policyv1alpha1.AddToScheme, + ccmv1alpha1.AddToScheme, logstashv1alpha1.AddToScheme, } mustAddSchemeOnce(&addToScheme, schemes) From a24a3c63c07e078cbdc3f95d433fd163ba327a7f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 09:17:45 -0600 Subject: [PATCH 03/90] renaming crds Signed-off-by: Michael Montgomery --- cmd/manager/main.go | 10 +- config/crds/v1/all-crds.yaml | 276 +++++++++-------- ....k8s.elastic.co_autoopsagentpolicies.yaml} | 52 ++-- config/crds/v1/resources/kustomization.yaml | 2 +- config/webhook/manifests.yaml | 20 +- .../eck-operator-crds/templates/all-crds.yaml | 290 +++++++++--------- docs/reference/api-reference/main.md | 139 ++++----- .../v1alpha1/autoopsagentpolicy_types.go | 109 +++++++ .../v1alpha1/doc.go | 5 +- .../v1alpha1/groupversion_info.go | 3 +- .../v1alpha1/webhook.go | 31 +- .../v1alpha1/zz_generated.deepcopy.go | 42 +-- .../v1alpha1/cloudconnectedmode_types.go | 106 ------- .../v1alpha1/webhook_test.go | 157 ---------- .../controller.go | 98 +++--- pkg/controller/common/scheme/scheme.go | 4 +- 16 files changed, 603 insertions(+), 741 deletions(-) rename config/crds/v1/resources/{cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml => autoops.k8s.elastic.co_autoopsagentpolicies.yaml} (74%) create mode 100644 pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go rename pkg/apis/{cloudconnectedmode => autoops}/v1alpha1/doc.go (83%) rename pkg/apis/{cloudconnectedmode => autoops}/v1alpha1/groupversion_info.go (87%) rename pkg/apis/{cloudconnectedmode => autoops}/v1alpha1/webhook.go (67%) rename pkg/apis/{cloudconnectedmode => autoops}/v1alpha1/zz_generated.deepcopy.go (65%) delete mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go delete mode 100644 pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go rename pkg/controller/{cloudconnectedmode => autoops}/controller.go (65%) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 17d77b8d850..019c680da89 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -46,7 +46,7 @@ import ( apmv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1" apmv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1beta1" beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" - ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" esv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1beta1" entv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/enterprisesearch/v1" @@ -63,7 +63,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling" esavalidation "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling/elasticsearch/validation" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/beat" - "github.com/elastic/cloud-on-k8s/v3/pkg/controller/cloudconnectedmode" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoops" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container" commonlicense "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" @@ -913,7 +913,7 @@ func registerControllers(mgr manager.Manager, params operator.Parameters, access {name: "Agent", registerFunc: agent.Add}, {name: "Maps", registerFunc: maps.Add}, {name: "StackConfigPolicy", registerFunc: stackconfigpolicy.Add}, - {name: "CloudConnectedMode", registerFunc: cloudconnectedmode.Add}, + {name: "AutoOpsAgentPolicy", registerFunc: autoops.Add}, {name: "Logstash", registerFunc: logstash.Add}, } @@ -1004,7 +1004,7 @@ func garbageCollectSoftOwnedSecrets(ctx context.Context, k8sClient k8s.Client) { agentv1alpha1.Kind: &agentv1alpha1.Agent{}, emsv1alpha1.Kind: &emsv1alpha1.ElasticMapsServer{}, policyv1alpha1.Kind: &policyv1alpha1.StackConfigPolicy{}, - ccmv1alpha1.Kind: &ccmv1alpha1.CloudConnectedMode{}, + autoopsv1alpha1.Kind: &autoopsv1alpha1.AutoOpsAgentPolicy{}, logstashv1alpha1.Kind: &logstashv1alpha1.Logstash{}, }); err != nil { log.Error(err, "Orphan secrets garbage collection failed, will be attempted again at next operator restart.") @@ -1048,7 +1048,7 @@ func setupWebhook( &kbv1beta1.Kibana{}, &emsv1alpha1.ElasticMapsServer{}, &policyv1alpha1.StackConfigPolicy{}, - &ccmv1alpha1.CloudConnectedMode{}, + &autoopsv1alpha1.AutoOpsAgentPolicy{}, } for _, obj := range webhookObjects { commonwebhook.SetupValidatingWebhookWithConfig(&commonwebhook.Config{ diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 980102ecad0..9d1a6540760 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2355,6 +2355,149 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: autoopsagentpolicies.autoops.k8s.elastic.co +spec: + group: autoops.k8s.elastic.co + names: + categories: + - elastic + kind: AutoOpsAgentPolicy + listKind: AutoOpsAgentPolicyList + plural: autoopsagentpolicies + shortNames: + - autoops + singular: autoopsagentpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + config: + description: |- + Config holds the AutoOpsAgentPolicy configuration. + The contents of the referenced secret requires the following format: + kind: Secret + apiVersion: v1 + metadata: + name: autoops-agent-policy-config + stringData: + ccmApiKey: aslkfjsldkjfslkdjflksdjfl + tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao + autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co + autoOpsToken: skdfjdskjf + type: object + resourceSelector: + description: |- + ResourceSelector is a label selector for the resources to be configured. + Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + status: + properties: + errors: + description: Errors is the number of resources that are in an error + state. + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this AutoOpsAgentPolicy. + format: int64 + type: integer + ready: + description: Ready is the number of resources that are in a ready + state. + type: integer + resources: + description: Resources is the number of resources that match the ResourceSelector. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 @@ -2833,139 +2976,6 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - name: cloudconnectedmodes.cloudconnected.k8s.elastic.co -spec: - group: cloudconnected.k8s.elastic.co - names: - categories: - - elastic - kind: CloudConnectedMode - listKind: CloudConnectedModeList - plural: cloudconnectedmodes - shortNames: - - ccm - singular: cloudconnectedmode - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Resources configured - jsonPath: .status.readyCount - name: Ready - type: string - - jsonPath: .status.phase - name: Phase - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: CloudConnectedMode represents a CloudConnectedMode resource in - a Kubernetes cluster. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - properties: - resourceSelector: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - status: - properties: - errors: - description: Errors is the number of resources which have an incorrect - configuration - type: integer - observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this CloudConnectedMode. - format: int64 - type: integer - ready: - description: Ready is the number of resources successfully configured. - type: integer - readyCount: - description: ReadyCount is a human representation of the number of - resources successfully configured. - type: string - resources: - description: Resources is the number of resources to be configured. - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 diff --git a/config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml similarity index 74% rename from config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml rename to config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 851e7ea0ea3..95f55e640bd 100644 --- a/config/crds/v1/resources/cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -4,18 +4,18 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 - name: cloudconnectedmodes.cloudconnected.k8s.elastic.co + name: autoopsagentpolicies.autoops.k8s.elastic.co spec: - group: cloudconnected.k8s.elastic.co + group: autoops.k8s.elastic.co names: categories: - elastic - kind: CloudConnectedMode - listKind: CloudConnectedModeList - plural: cloudconnectedmodes + kind: AutoOpsAgentPolicy + listKind: AutoOpsAgentPolicyList + plural: autoopsagentpolicies shortNames: - - ccm - singular: cloudconnectedmode + - autoops + singular: autoopsagentpolicy scope: Namespaced versions: - additionalPrinterColumns: @@ -32,8 +32,8 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: CloudConnectedMode represents a CloudConnectedMode resource in - a Kubernetes cluster. + description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + in a Kubernetes cluster. properties: apiVersion: description: |- @@ -54,11 +54,24 @@ spec: type: object spec: properties: + config: + description: |- + Config holds the AutoOpsAgentPolicy configuration. + The contents of the referenced secret requires the following format: + kind: Secret + apiVersion: v1 + metadata: + name: autoops-agent-policy-config + stringData: + ccmApiKey: aslkfjsldkjfslkdjflksdjfl + tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao + autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co + autoOpsToken: skdfjdskjf + type: object resourceSelector: description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. + ResourceSelector is a label selector for the resources to be configured. + Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -107,23 +120,20 @@ spec: status: properties: errors: - description: Errors is the number of resources which have an incorrect - configuration + description: Errors is the number of resources that are in an error + state. type: integer observedGeneration: description: ObservedGeneration is the most recent generation observed - for this CloudConnectedMode. + for this AutoOpsAgentPolicy. format: int64 type: integer ready: - description: Ready is the number of resources successfully configured. + description: Ready is the number of resources that are in a ready + state. type: integer - readyCount: - description: ReadyCount is a human representation of the number of - resources successfully configured. - type: string resources: - description: Resources is the number of resources to be configured. + description: Resources is the number of resources that match the ResourceSelector. type: integer type: object type: object diff --git a/config/crds/v1/resources/kustomization.yaml b/config/crds/v1/resources/kustomization.yaml index 4f2546f79fa..0a1cd531168 100644 --- a/config/crds/v1/resources/kustomization.yaml +++ b/config/crds/v1/resources/kustomization.yaml @@ -8,5 +8,5 @@ resources: - agent.k8s.elastic.co_agents.yaml - maps.k8s.elastic.co_elasticmapsservers.yaml - stackconfigpolicy.k8s.elastic.co_stackconfigpolicies.yaml - - cloudconnected.k8s.elastic.co_cloudconnectedmodes.yaml + - autoops.k8s.elastic.co_autoopsagentpolicies.yaml - logstash.k8s.elastic.co_logstashes.yaml diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 22f8e027826..36e0f089d69 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -73,20 +73,20 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-beat-k8s-elastic-co-v1beta1-beat + path: /validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies failurePolicy: Ignore matchPolicy: Exact - name: elastic-beat-validation-v1beta1.k8s.elastic.co + name: elastic-autoops-validation-v1alpha1.k8s.elastic.co rules: - apiGroups: - - beat.k8s.elastic.co + - autoops.k8s.elastic.co apiVersions: - - v1beta1 + - v1alpha1 operations: - CREATE - UPDATE resources: - - beats + - autoopsagentpolicies sideEffects: None - admissionReviewVersions: - v1 @@ -94,20 +94,20 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes + path: /validate-beat-k8s-elastic-co-v1beta1-beat failurePolicy: Ignore matchPolicy: Exact - name: elastic-ccm-validation-v1alpha1.k8s.elastic.co + name: elastic-beat-validation-v1beta1.k8s.elastic.co rules: - apiGroups: - - cloudconnected.k8s.elastic.co + - beat.k8s.elastic.co apiVersions: - - v1alpha1 + - v1beta1 operations: - CREATE - UPDATE resources: - - cloudconnectedmodes + - beats sideEffects: None - admissionReviewVersions: - v1 diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index a92e55be5ec..18762a61f1f 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2369,6 +2369,156 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: '{{ .Release.Name }}' + app.kubernetes.io/managed-by: '{{ .Release.Service }}' + app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' + app.kubernetes.io/version: '{{ .Chart.AppVersion }}' + helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' + name: autoopsagentpolicies.autoops.k8s.elastic.co +spec: + group: autoops.k8s.elastic.co + names: + categories: + - elastic + kind: AutoOpsAgentPolicy + listKind: AutoOpsAgentPolicyList + plural: autoopsagentpolicies + shortNames: + - autoops + singular: autoopsagentpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resources configured + jsonPath: .status.readyCount + name: Ready + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + in a Kubernetes cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + config: + description: |- + Config holds the AutoOpsAgentPolicy configuration. + The contents of the referenced secret requires the following format: + kind: Secret + apiVersion: v1 + metadata: + name: autoops-agent-policy-config + stringData: + ccmApiKey: aslkfjsldkjfslkdjflksdjfl + tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao + autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co + autoOpsToken: skdfjdskjf + type: object + resourceSelector: + description: |- + ResourceSelector is a label selector for the resources to be configured. + Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + status: + properties: + errors: + description: Errors is the number of resources that are in an error + state. + type: integer + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this AutoOpsAgentPolicy. + format: int64 + type: integer + ready: + description: Ready is the number of resources that are in a ready + state. + type: integer + resources: + description: Resources is the number of resources that match the ResourceSelector. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 @@ -2854,146 +3004,6 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - helm.sh/resource-policy: keep - labels: - app.kubernetes.io/instance: '{{ .Release.Name }}' - app.kubernetes.io/managed-by: '{{ .Release.Service }}' - app.kubernetes.io/name: '{{ include "eck-operator-crds.name" . }}' - app.kubernetes.io/version: '{{ .Chart.AppVersion }}' - helm.sh/chart: '{{ include "eck-operator-crds.chart" . }}' - name: cloudconnectedmodes.cloudconnected.k8s.elastic.co -spec: - group: cloudconnected.k8s.elastic.co - names: - categories: - - elastic - kind: CloudConnectedMode - listKind: CloudConnectedModeList - plural: cloudconnectedmodes - shortNames: - - ccm - singular: cloudconnectedmode - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Resources configured - jsonPath: .status.readyCount - name: Ready - type: string - - jsonPath: .status.phase - name: Phase - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: CloudConnectedMode represents a CloudConnectedMode resource in - a Kubernetes cluster. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - properties: - resourceSelector: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - status: - properties: - errors: - description: Errors is the number of resources which have an incorrect - configuration - type: integer - observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this CloudConnectedMode. - format: int64 - type: integer - ready: - description: Ready is the number of resources successfully configured. - type: integer - readyCount: - description: ReadyCount is a human representation of the number of - resources successfully configured. - type: string - resources: - description: Resources is the number of resources to be configured. - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 9822829c89a..6b6d77aa7d4 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -14,9 +14,9 @@ applies_to: * [agent.k8s.elastic.co/v1alpha1](#agentk8selasticcov1alpha1) * [apm.k8s.elastic.co/v1](#apmk8selasticcov1) * [apm.k8s.elastic.co/v1beta1](#apmk8selasticcov1beta1) +* [autoops.k8s.elastic.co/v1alpha1](#autoopsk8selasticcov1alpha1) * [autoscaling.k8s.elastic.co/v1alpha1](#autoscalingk8selasticcov1alpha1) * [beat.k8s.elastic.co/v1beta1](#beatk8selasticcov1beta1) -* [cloudconnected.k8s.elastic.co/v1alpha1](#cloudconnectedk8selasticcov1alpha1) * [common.k8s.elastic.co/v1](#commonk8selasticcov1) * [common.k8s.elastic.co/v1alpha1](#commonk8selasticcov1alpha1) * [common.k8s.elastic.co/v1beta1](#commonk8selasticcov1beta1) @@ -256,6 +256,64 @@ ApmServerSpec holds the specification of an APM Server. +% TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors +## autoops.k8s.elastic.co/v1alpha1 [#autoopsk8selasticcov1alpha1] + +Package v1alpha1 contains API schema definitions for managing AutoOpsAgentPolicy resources. + +### Resource Types +- [AutoOpsAgentPolicy](#autoopsagentpolicy) +- [AutoOpsAgentPolicyList](#autoopsagentpolicylist) + + + +### AutoOpsAgentPolicy [#autoopsagentpolicy] + +AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. + +:::{admonition} Appears In: +* [AutoOpsAgentPolicyList](#autoopsagentpolicylist) + +::: + +| Field | Description | +| --- | --- | +| *`apiVersion`* __string__ | `autoops.k8s.elastic.co/v1alpha1` | +| *`kind`* __string__ | `AutoOpsAgentPolicy` | +| *`metadata`* __[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | +| *`spec`* __[AutoOpsAgentPolicySpec](#autoopsagentpolicyspec)__ | | + + +### AutoOpsAgentPolicyList [#autoopsagentpolicylist] + +AutoOpsAgentPolicyList contains a list of AutoOpsAgentPolicy resources. + + + +| Field | Description | +| --- | --- | +| *`apiVersion`* __string__ | `autoops.k8s.elastic.co/v1alpha1` | +| *`kind`* __string__ | `AutoOpsAgentPolicyList` | +| *`metadata`* __[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#listmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | +| *`items`* __[AutoOpsAgentPolicy](#autoopsagentpolicy) array__ | | + + +### AutoOpsAgentPolicySpec [#autoopsagentpolicyspec] + + + +:::{admonition} Appears In: +* [AutoOpsAgentPolicy](#autoopsagentpolicy) + +::: + +| Field | Description | +| --- | --- | +| *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | +| *`config`* __[Config](#config)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | + + + % TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors ## autoscaling.k8s.elastic.co/v1alpha1 [#autoscalingk8selasticcov1alpha1] @@ -392,84 +450,6 @@ BeatSpec defines the desired state of a Beat. -% TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors -## cloudconnected.k8s.elastic.co/v1alpha1 [#cloudconnectedk8selasticcov1alpha1] - -Package v1alpha1 contains API schema definitions for managing StackConfigPolicy resources. - -### Resource Types -- [CloudConnectedMode](#cloudconnectedmode) -- [CloudConnectedModeList](#cloudconnectedmodelist) - - - -### CloudConnectedMode [#cloudconnectedmode] - -CloudConnectedMode represents a CloudConnectedMode resource in a Kubernetes cluster. - -:::{admonition} Appears In: -* [CloudConnectedModeList](#cloudconnectedmodelist) - -::: - -| Field | Description | -| --- | --- | -| *`apiVersion`* __string__ | `cloudconnected.k8s.elastic.co/v1alpha1` | -| *`kind`* __string__ | `CloudConnectedMode` | -| *`metadata`* __[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | -| *`spec`* __[CloudConnectedModeSpec](#cloudconnectedmodespec)__ | | -| *`status`* __[CloudConnectedModeStatus](#cloudconnectedmodestatus)__ | | - - -### CloudConnectedModeList [#cloudconnectedmodelist] - -CloudConnectedModeList contains a list of CloudConnectedMode resources. - - - -| Field | Description | -| --- | --- | -| *`apiVersion`* __string__ | `cloudconnected.k8s.elastic.co/v1alpha1` | -| *`kind`* __string__ | `CloudConnectedModeList` | -| *`metadata`* __[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#listmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | -| *`items`* __[CloudConnectedMode](#cloudconnectedmode) array__ | | - - -### CloudConnectedModeSpec [#cloudconnectedmodespec] - - - -:::{admonition} Appears In: -* [CloudConnectedMode](#cloudconnectedmode) - -::: - -| Field | Description | -| --- | --- | -| *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | | - - -### CloudConnectedModeStatus [#cloudconnectedmodestatus] - - - -:::{admonition} Appears In: -* [CloudConnectedMode](#cloudconnectedmode) - -::: - -| Field | Description | -| --- | --- | -| *`resources`* __integer__ | Resources is the number of resources to be configured. | -| *`ready`* __integer__ | Ready is the number of resources successfully configured. | -| *`errors`* __integer__ | Errors is the number of resources which have an incorrect configuration | -| *`readyCount`* __string__ | ReadyCount is a human representation of the number of resources successfully configured. | -| *`observedGeneration`* __integer__ | ObservedGeneration is the most recent generation observed for this CloudConnectedMode. | - - - - - % TODO add function to crd-ref-docs return anchor used in links docs-v3 does not seem to produce valid markdown anchors ## common.k8s.elastic.co/v1 [#commonk8selasticcov1] @@ -486,6 +466,7 @@ Config represents untyped YAML configuration. :::{admonition} Appears In: * [AgentSpec](#agentspec) * [ApmServerSpec](#apmserverspec) +* [AutoOpsAgentPolicySpec](#autoopsagentpolicyspec) * [BeatSpec](#beatspec) * [ElasticsearchConfigPolicySpec](#elasticsearchconfigpolicyspec) * [EnterpriseSearchSpec](#enterprisesearchspec) diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go new file mode 100644 index 00000000000..a3875c25ddf --- /dev/null +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -0,0 +1,109 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" +) + +const ( + // Kind is inferred from the struct name using reflection in SchemeBuilder.Register() + // we duplicate it as a constant here for practical purposes. + Kind = "AutoOpsAgentPolicy" + + unknownVersion = 0 +) + +func init() { + SchemeBuilder.Register(&AutoOpsAgentPolicy{}, &AutoOpsAgentPolicyList{}) +} + +// +kubebuilder:object:root=true + +// AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. +// +kubebuilder:resource:categories=elastic,shortName=autoops +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.readyCount",description="Resources configured" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +type AutoOpsAgentPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AutoOpsAgentPolicySpec `json:"spec,omitempty"` + Status AutoOpsAgentPolicyStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// AutoOpsAgentPolicyList contains a list of AutoOpsAgentPolicy resources. +type AutoOpsAgentPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AutoOpsAgentPolicy `json:"items"` +} + +type AutoOpsAgentPolicySpec struct { + // ResourceSelector is a label selector for the resources to be configured. + // Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. + ResourceSelector metav1.LabelSelector `json:"resourceSelector,omitempty"` + // Config holds the AutoOpsAgentPolicy configuration. + // The contents of the referenced secret requires the following format: + // kind: Secret + // apiVersion: v1 + // metadata: + // name: autoops-agent-policy-config + // stringData: + // ccmApiKey: aslkfjsldkjfslkdjflksdjfl + // tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao + // autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co + // autoOpsToken: skdfjdskjf + Config *commonv1.Config `json:"config,omitempty"` + // AutoOpsRef is a reference to an AutoOps instance running in the same Kubernetes cluster. + // (TODO) AutoOpsRef is not yet implemented. + // AutoOpsRef commonv1.ObjectSelector `json:"autoOpsRef,omitempty"` +} + +type AutoOpsAgentPolicyStatus struct { + // Resources is the number of resources that match the ResourceSelector. + Resources int `json:"resources,omitempty"` + // Ready is the number of resources that are in a ready state. + Ready int `json:"ready,omitempty"` + // Errors is the number of resources that are in an error state. + Errors int `json:"errors,omitempty"` + // ObservedGeneration is the most recent generation observed for this AutoOpsAgentPolicy. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +func NewStatus(policy AutoOpsAgentPolicy) AutoOpsAgentPolicyStatus { + status := AutoOpsAgentPolicyStatus{ + // Details: map[ResourceType]map[string]ResourcePolicyStatus{}, + // Phase: ReadyPhase, + ObservedGeneration: policy.Generation, + } + return status +} + +// Update updates the policy status from its resources statuses. +func (s *AutoOpsAgentPolicyStatus) Update() { +} + +// IsDegraded returns true when the AutoOpsAgentPolicyStatus resource is degraded compared to the previous status. +// func (s AutoOpsAgentPolicyStatus) IsDegraded(prev AutoOpsAgentPolicyStatus) bool { +// return prev.Phase == ReadyPhase && s.Phase != ReadyPhase && s.Phase != ApplyingChangesPhase +// } + +// IsMarkedForDeletion returns true if the AutoOpsAgentPolicy resource is going to be deleted. +func (p *AutoOpsAgentPolicy) IsMarkedForDeletion() bool { + return !p.DeletionTimestamp.IsZero() +} + +func (s AutoOpsAgentPolicyStatus) getResourceStatusKey(nsn types.NamespacedName) string { + return nsn.String() +} diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/doc.go b/pkg/apis/autoops/v1alpha1/doc.go similarity index 83% rename from pkg/apis/cloudconnectedmode/v1alpha1/doc.go rename to pkg/apis/autoops/v1alpha1/doc.go index 1c7886a5150..dbc4d5f3de0 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/doc.go +++ b/pkg/apis/autoops/v1alpha1/doc.go @@ -2,7 +2,8 @@ // or more contributor license agreements. Licensed under the Elastic License 2.0; // you may not use this file except in compliance with the Elastic License 2.0. -// Package v1alpha1 contains API schema definitions for managing StackConfigPolicy resources. +// Package v1alpha1 contains API schema definitions for managing AutoOpsAgentPolicy resources. // +kubebuilder:object:generate=true -// +groupName=cloudconnected.k8s.elastic.co +// +groupName=autoops.k8s.elastic.co package v1alpha1 + diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go b/pkg/apis/autoops/v1alpha1/groupversion_info.go similarity index 87% rename from pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go rename to pkg/apis/autoops/v1alpha1/groupversion_info.go index 316f2716a0b..d7c29f750fd 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/groupversion_info.go +++ b/pkg/apis/autoops/v1alpha1/groupversion_info.go @@ -11,7 +11,7 @@ import ( var ( // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "cloudconnected.k8s.elastic.co", Version: "v1alpha1"} + GroupVersion = schema.GroupVersion{Group: "autoops.k8s.elastic.co", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} @@ -19,3 +19,4 @@ var ( // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme ) + diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go similarity index 67% rename from pkg/apis/cloudconnectedmode/v1alpha1/webhook.go rename to pkg/apis/autoops/v1alpha1/webhook.go index e45d0699570..56b8054009e 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -16,53 +16,53 @@ import ( ) const ( - // webhookPath is the HTTP path for the CloudConnected validating webhook. - webhookPath = "/validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes" + // webhookPath is the HTTP path for the AutoOpsAgentPolicy validating webhook. + webhookPath = "/validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies" SpecSecureSettingsDeprecated = "spec.SecureSettings is deprecated, secure settings must be set per application" ) var ( groupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: Kind} - validationLog = ulog.Log.WithName("ccm-v1alpha1-validation") + validationLog = ulog.Log.WithName("autoops-v1alpha1-validation") - defaultChecks = []func(*CloudConnectedMode) field.ErrorList{ + defaultChecks = []func(*AutoOpsAgentPolicy) field.ErrorList{ checkNoUnknownFields, checkNameLength, validSettings, } ) -// +kubebuilder:webhook:path=/validate-ccm-k8s-elastic-co-v1alpha1-cloudconnectedmodes,mutating=false,failurePolicy=ignore,groups=cloudconnected.k8s.elastic.co,resources=cloudconnectedmodes,verbs=create;update,versions=v1alpha1,name=elastic-ccm-validation-v1alpha1.k8s.elastic.co,sideEffects=None,admissionReviewVersions=v1,matchPolicy=Exact +// +kubebuilder:webhook:path=/validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies,mutating=false,failurePolicy=ignore,groups=autoops.k8s.elastic.co,resources=autoopsagentpolicies,verbs=create;update,versions=v1alpha1,name=elastic-autoops-validation-v1alpha1.k8s.elastic.co,sideEffects=None,admissionReviewVersions=v1,matchPolicy=Exact -var _ admission.Validator = &CloudConnectedMode{} +var _ admission.Validator = &AutoOpsAgentPolicy{} // ValidateCreate is called by the validating webhook to validate the create operation. // Satisfies the webhook.Validator interface. -func (p *CloudConnectedMode) ValidateCreate() (admission.Warnings, error) { +func (p *AutoOpsAgentPolicy) ValidateCreate() (admission.Warnings, error) { validationLog.V(1).Info("Validate create", "name", p.Name) return p.validate() } // ValidateDelete is called by the validating webhook to validate the delete operation. // Satisfies the webhook.Validator interface. -func (p *CloudConnectedMode) ValidateDelete() (admission.Warnings, error) { +func (p *AutoOpsAgentPolicy) ValidateDelete() (admission.Warnings, error) { validationLog.V(1).Info("Validate delete", "name", p.Name) return nil, nil } // ValidateUpdate is called by the validating webhook to validate the update operation. // Satisfies the webhook.Validator interface. -func (p *CloudConnectedMode) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) { +func (p *AutoOpsAgentPolicy) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) { validationLog.V(1).Info("Validate update", "name", p.Name) return p.validate() } // WebhookPath returns the HTTP path used by the validating webhook. -func (p *CloudConnectedMode) WebhookPath() string { +func (p *AutoOpsAgentPolicy) WebhookPath() string { return webhookPath } -func (p *CloudConnectedMode) validate() (admission.Warnings, error) { +func (p *AutoOpsAgentPolicy) validate() (admission.Warnings, error) { var errors field.ErrorList for _, dc := range defaultChecks { @@ -78,25 +78,26 @@ func (p *CloudConnectedMode) validate() (admission.Warnings, error) { return nil, nil } -func (p *CloudConnectedMode) GetWarnings() []string { +func (p *AutoOpsAgentPolicy) GetWarnings() []string { if p == nil { return nil } return nil } -func checkNoUnknownFields(policy *CloudConnectedMode) field.ErrorList { +func checkNoUnknownFields(policy *AutoOpsAgentPolicy) field.ErrorList { return commonv1.NoUnknownFields(policy, policy.ObjectMeta) } -func checkNameLength(policy *CloudConnectedMode) field.ErrorList { +func checkNameLength(policy *AutoOpsAgentPolicy) field.ErrorList { return commonv1.CheckNameLength(policy) } -func validSettings(policy *CloudConnectedMode) field.ErrorList { +func validSettings(policy *AutoOpsAgentPolicy) field.ErrorList { // Validate that ResourceSelector is not empty if policy.Spec.ResourceSelector.MatchLabels == nil && len(policy.Spec.ResourceSelector.MatchExpressions) == 0 { return field.ErrorList{field.Required(field.NewPath("spec").Child("resourceSelector"), "ResourceSelector must be specified with either matchLabels or matchExpressions")} } return nil } + diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go similarity index 65% rename from pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go rename to pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go index 28166a227cb..fd679e699b8 100644 --- a/pkg/apis/cloudconnectedmode/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go @@ -13,7 +13,7 @@ import ( ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CloudConnectedMode) DeepCopyInto(out *CloudConnectedMode) { +func (in *AutoOpsAgentPolicy) DeepCopyInto(out *AutoOpsAgentPolicy) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -21,18 +21,18 @@ func (in *CloudConnectedMode) DeepCopyInto(out *CloudConnectedMode) { out.Status = in.Status } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedMode. -func (in *CloudConnectedMode) DeepCopy() *CloudConnectedMode { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicy. +func (in *AutoOpsAgentPolicy) DeepCopy() *AutoOpsAgentPolicy { if in == nil { return nil } - out := new(CloudConnectedMode) + out := new(AutoOpsAgentPolicy) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *CloudConnectedMode) DeepCopyObject() runtime.Object { +func (in *AutoOpsAgentPolicy) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -40,31 +40,31 @@ func (in *CloudConnectedMode) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CloudConnectedModeList) DeepCopyInto(out *CloudConnectedModeList) { +func (in *AutoOpsAgentPolicyList) DeepCopyInto(out *AutoOpsAgentPolicyList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]CloudConnectedMode, len(*in)) + *out = make([]AutoOpsAgentPolicy, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeList. -func (in *CloudConnectedModeList) DeepCopy() *CloudConnectedModeList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicyList. +func (in *AutoOpsAgentPolicyList) DeepCopy() *AutoOpsAgentPolicyList { if in == nil { return nil } - out := new(CloudConnectedModeList) + out := new(AutoOpsAgentPolicyList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *CloudConnectedModeList) DeepCopyObject() runtime.Object { +func (in *AutoOpsAgentPolicyList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -72,32 +72,36 @@ func (in *CloudConnectedModeList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CloudConnectedModeSpec) DeepCopyInto(out *CloudConnectedModeSpec) { +func (in *AutoOpsAgentPolicySpec) DeepCopyInto(out *AutoOpsAgentPolicySpec) { *out = *in in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = (*in).DeepCopy() + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeSpec. -func (in *CloudConnectedModeSpec) DeepCopy() *CloudConnectedModeSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicySpec. +func (in *AutoOpsAgentPolicySpec) DeepCopy() *AutoOpsAgentPolicySpec { if in == nil { return nil } - out := new(CloudConnectedModeSpec) + out := new(AutoOpsAgentPolicySpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CloudConnectedModeStatus) DeepCopyInto(out *CloudConnectedModeStatus) { +func (in *AutoOpsAgentPolicyStatus) DeepCopyInto(out *AutoOpsAgentPolicyStatus) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudConnectedModeStatus. -func (in *CloudConnectedModeStatus) DeepCopy() *CloudConnectedModeStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicyStatus. +func (in *AutoOpsAgentPolicyStatus) DeepCopy() *AutoOpsAgentPolicyStatus { if in == nil { return nil } - out := new(CloudConnectedModeStatus) + out := new(AutoOpsAgentPolicyStatus) in.DeepCopyInto(out) return out } diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go b/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go deleted file mode 100644 index ca23b75145b..00000000000 --- a/pkg/apis/cloudconnectedmode/v1alpha1/cloudconnectedmode_types.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - eslabel "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/label" -) - -const ( - // Kind is inferred from the struct name using reflection in SchemeBuilder.Register() - // we duplicate it as a constant here for practical purposes. - Kind = "CloudConnectedMode" - - unknownVersion = 0 -) - -func init() { - SchemeBuilder.Register(&CloudConnectedMode{}, &CloudConnectedModeList{}) -} - -// +kubebuilder:object:root=true - -// CloudConnectedMode represents a CloudConnectedMode resource in a Kubernetes cluster. -// +kubebuilder:resource:categories=elastic,shortName=ccm -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.readyCount",description="Resources configured" -// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" -// +kubebuilder:subresource:status -// +kubebuilder:storageversion -type CloudConnectedMode struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec CloudConnectedModeSpec `json:"spec,omitempty"` - Status CloudConnectedModeStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// CloudConnectedModeList contains a list of CloudConnectedMode resources. -type CloudConnectedModeList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []CloudConnectedMode `json:"items"` -} - -type CloudConnectedModeSpec struct { - ResourceSelector metav1.LabelSelector `json:"resourceSelector,omitempty"` - // Deprecated: SecureSettings only applies to Elasticsearch and is deprecated. It must be set per application instead. - // SecureSettings []commonv1.SecretSource `json:"secureSettings,omitempty"` - // Elasticsearch ElasticsearchConfigPolicySpec `json:"elasticsearch,omitempty"` - // Kibana KibanaConfigPolicySpec `json:"kibana,omitempty"` -} - -type ResourceType string - -const ( - ElasticsearchResourceType ResourceType = eslabel.Type - // KibanaResourceType ResourceType = kblabel.Type -) - -type CloudConnectedModeStatus struct { - // Resources is the number of resources to be configured. - Resources int `json:"resources,omitempty"` - // Ready is the number of resources successfully configured. - Ready int `json:"ready,omitempty"` - // Errors is the number of resources which have an incorrect configuration - Errors int `json:"errors,omitempty"` - // ReadyCount is a human representation of the number of resources successfully configured. - ReadyCount string `json:"readyCount,omitempty"` - // ObservedGeneration is the most recent generation observed for this CloudConnectedMode. - ObservedGeneration int64 `json:"observedGeneration,omitempty"` -} - -func NewStatus(scp CloudConnectedMode) CloudConnectedModeStatus { - status := CloudConnectedModeStatus{ - // Details: map[ResourceType]map[string]ResourcePolicyStatus{}, - // Phase: ReadyPhase, - ObservedGeneration: scp.Generation, - } - // status.setReadyCount() - return status -} - -// Update updates the policy status from its resources statuses. -func (s *CloudConnectedModeStatus) Update() { -} - -// IsDegraded returns true when the CloudConnectedModeStatus resource is degraded compared to the previous status. -// func (s CloudConnectedModeStatus) IsDegraded(prev CloudConnectedModeStatus) bool { -// return prev.Phase == ReadyPhase && s.Phase != ReadyPhase && s.Phase != ApplyingChangesPhase -// } - -// IsMarkedForDeletion returns true if the CloudConnectedMode resource is going to be deleted. -func (p *CloudConnectedMode) IsMarkedForDeletion() bool { - return !p.DeletionTimestamp.IsZero() -} - -func (s CloudConnectedModeStatus) getResourceStatusKey(nsn types.NamespacedName) string { - return nsn.String() -} diff --git a/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go b/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go deleted file mode 100644 index 8aae68bbd2b..00000000000 --- a/pkg/apis/cloudconnectedmode/v1alpha1/webhook_test.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package v1alpha1_test - -import ( - "encoding/json" - "strings" - "testing" - - "github.com/stretchr/testify/require" - admissionv1 "k8s.io/api/admission/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" - policyv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/stackconfigpolicy/v1alpha1" - "github.com/elastic/cloud-on-k8s/v3/pkg/utils/test" -) - -func TestWebhook(t *testing.T) { - testCases := []test.ValidationWebhookTestCase{ - { - Name: "create-valid", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.Spec.Elasticsearch.SecretMounts = []policyv1alpha1.SecretMount{ - { - SecretName: "test1", - MountPath: "/usr/test1", - }, - { - SecretName: "test2", - MountPath: "/usr/test2", - }, - } - return serialize(t, m) - }, - Check: test.ValidationWebhookSucceeded, - }, - { - Name: "create-valid-kibana", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.Spec.Elasticsearch = policyv1alpha1.ElasticsearchConfigPolicySpec{} - m.Spec.Kibana = policyv1alpha1.KibanaConfigPolicySpec{ - Config: &commonv1.Config{Data: map[string]interface{}{"a": "b"}}, - } - return serialize(t, m) - }, - Check: test.ValidationWebhookSucceeded, - }, - { - Name: "unknown-field", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.SetAnnotations(map[string]string{ - corev1.LastAppliedConfigAnnotation: `{ - "metadata":{"name": "scp", "namespace": "default", "uid": "e7a18cfb-b017-475c-8da2-1ec941b1f285", "creationTimestamp":"2020-03-24T13:43:20Z" }, - "spec":{"unknown": "blurb"} - }`, - }) - return serialize(t, m) - }, - Check: test.ValidationWebhookFailed( - `"unknown": unknown field found in the kubectl.kubernetes.io/last-applied-configuration annotation is unknown`, - ), - }, - { - Name: "long-name", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.SetName(strings.Repeat("x", 100)) - return serialize(t, m) - }, - Check: test.ValidationWebhookFailed( - `metadata.name: Too long: may not be more than 36 bytes`, - ), - }, - { - Name: "no-settings", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.Spec.Elasticsearch = policyv1alpha1.ElasticsearchConfigPolicySpec{ - SnapshotRepositories: nil, - SnapshotLifecyclePolicies: &commonv1.Config{Data: nil}, - ClusterSettings: &commonv1.Config{Data: map[string]interface{}{}}, - } - return serialize(t, m) - }, - Check: test.ValidationWebhookFailed( - "One out of Elasticsearch or Kibana settings is mandatory, both must not be empty", - ), - }, - { - Name: "create-duplicate-mountpaths", - Operation: admissionv1.Create, - Object: func(t *testing.T, uid string) []byte { - t.Helper() - m := mkStackConfigPolicy(uid) - m.Spec.Elasticsearch.SecretMounts = []policyv1alpha1.SecretMount{ - { - SecretName: "test1", - MountPath: "/usr/test", - }, - { - SecretName: "test2", - MountPath: "/usr/test", - }, - } - return serialize(t, m) - }, - Check: test.ValidationWebhookFailed( - "SecretMounts cannot have duplicate mount paths", - ), - }, - } - - validator := &policyv1alpha1.StackConfigPolicy{} - gvk := metav1.GroupVersionKind{Group: policyv1alpha1.GroupVersion.Group, Version: policyv1alpha1.GroupVersion.Version, Kind: policyv1alpha1.Kind} - test.RunValidationWebhookTests(t, gvk, validator, testCases...) -} - -func mkStackConfigPolicy(uid string) *policyv1alpha1.StackConfigPolicy { - return &policyv1alpha1.StackConfigPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "config-policy-test", - UID: types.UID(uid), - }, - Spec: policyv1alpha1.StackConfigPolicySpec{ - Elasticsearch: policyv1alpha1.ElasticsearchConfigPolicySpec{ - ClusterSettings: &commonv1.Config{Data: map[string]interface{}{"a": "b"}}, - }, - }, - } -} - -func serialize(t *testing.T, policy *policyv1alpha1.StackConfigPolicy) []byte { - t.Helper() - - objBytes, err := json.Marshal(policy) - require.NoError(t, err) - - return objBytes -} diff --git a/pkg/controller/cloudconnectedmode/controller.go b/pkg/controller/autoops/controller.go similarity index 65% rename from pkg/controller/cloudconnectedmode/controller.go rename to pkg/controller/autoops/controller.go index 7ace01022e1..03bcb732e48 100644 --- a/pkg/controller/cloudconnectedmode/controller.go +++ b/pkg/controller/autoops/controller.go @@ -2,7 +2,7 @@ // or more contributor license agreements. Licensed under the Elastic License 2.0; // you may not use this file except in compliance with the Elastic License 2.0. -package cloudconnectedmode +package autoops import ( "context" @@ -20,7 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" @@ -33,7 +33,7 @@ import ( ) const ( - controllerName = "cloudconnectedmode-controller" + controllerName = "autoops-controller" ) var ( @@ -41,7 +41,7 @@ var ( defaultRequeue = 30 * time.Second ) -// Add creates a new CloudConnectedMode Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// Add creates a new AutoOpsAgentPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(mgr manager.Manager, params operator.Parameters) error { r := newReconciler(mgr, params) @@ -52,25 +52,25 @@ func Add(mgr manager.Manager, params operator.Parameters) error { return addWatches(mgr, c, r) } -// newReconciler returns a new reconcile.Reconciler of CloudConnectedMode. -func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileCloudConnectedMode { +// newReconciler returns a new reconcile.Reconciler of AutoOpsAgentPolicy. +func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAutoOpsAgentPolicy { k8sClient := mgr.GetClient() - return &ReconcileCloudConnectedMode{ + return &ReconcileAutoOpsAgentPolicy{ Client: k8sClient, recorder: mgr.GetEventRecorderFor(controllerName), licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), - params: params, + params: params, dynamicWatches: watches.NewDynamicWatches(), } } -func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileCloudConnectedMode) error { - // watch for changes to CloudConnectedMode - if err := c.Watch(source.Kind(mgr.GetCache(), &ccmv1alpha1.CloudConnectedMode{}, &handler.TypedEnqueueRequestForObject[*ccmv1alpha1.CloudConnectedMode]{})); err != nil { +func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAutoOpsAgentPolicy) error { + // watch for changes to AutoOpsAgentPolicy + if err := c.Watch(source.Kind(mgr.GetCache(), &autoopsv1alpha1.AutoOpsAgentPolicy{}, &handler.TypedEnqueueRequestForObject[*autoopsv1alpha1.AutoOpsAgentPolicy]{})); err != nil { return err } - // watch Secrets soft owned by CloudConnectedMode + // watch Secrets soft owned by AutoOpsAgentPolicy if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, reconcileRequestForSoftOwner())); err != nil { return err } @@ -82,7 +82,7 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileCloudC func reconcileRequestForSoftOwner() handler.TypedEventHandler[*corev1.Secret, reconcile.Request] { return handler.TypedEnqueueRequestsFromMapFunc[*corev1.Secret](func(ctx context.Context, secret *corev1.Secret) []reconcile.Request { softOwner, referenced := reconciler.SoftOwnerRefFromLabels(secret.GetLabels()) - if !referenced || softOwner.Kind != ccmv1alpha1.Kind { + if !referenced || softOwner.Kind != autoopsv1alpha1.Kind { return nil } return []reconcile.Request{ @@ -91,10 +91,10 @@ func reconcileRequestForSoftOwner() handler.TypedEventHandler[*corev1.Secret, re }) } -var _ reconcile.Reconciler = &ReconcileCloudConnectedMode{} +var _ reconcile.Reconciler = &ReconcileAutoOpsAgentPolicy{} -// ReconcileCloudConnectedMode reconciles a CloudConnectedMode object -type ReconcileCloudConnectedMode struct { +// ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object +type ReconcileAutoOpsAgentPolicy struct { k8s.Client recorder record.EventRecorder licenseChecker license.Checker @@ -104,16 +104,16 @@ type ReconcileCloudConnectedMode struct { iteration uint64 } -// Reconcile reads that state of the cluster for a CloudConnectedMode object and makes changes based on the state read and what is -// in the CloudConnectedMode.Spec. -func (r *ReconcileCloudConnectedMode) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "ccm_name", request) +// Reconcile reads that state of the cluster for an AutoOpsAgentPolicy object and makes changes based on the state read and what is +// in the AutoOpsAgentPolicy.Spec. +func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) defer common.LogReconciliationRun(ulog.FromContext(ctx))() defer tracing.EndContextTransaction(ctx) - // retrieve the CloudConnectedMode resource - var ccm ccmv1alpha1.CloudConnectedMode - err := r.Client.Get(ctx, request.NamespacedName, &ccm) + // retrieve the AutoOpsAgentPolicy resource + var policy autoopsv1alpha1.AutoOpsAgentPolicy + err := r.Client.Get(ctx, request.NamespacedName, &policy) if err != nil { if apierrors.IsNotFound(err) { return reconcile.Result{}, r.onDelete(ctx, @@ -126,21 +126,21 @@ func (r *ReconcileCloudConnectedMode) Reconcile(ctx context.Context, request rec } // skip unmanaged resources - if common.IsUnmanaged(ctx, &ccm) { + if common.IsUnmanaged(ctx, &policy) { ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") return reconcile.Result{}, nil } - // the CloudConnectedMode will be deleted nothing to do other than remove the watches - if ccm.IsMarkedForDeletion() { - return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&ccm)) + // the AutoOpsAgentPolicy will be deleted nothing to do other than remove the watches + if policy.IsMarkedForDeletion() { + return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } // main reconciliation logic - results, status := r.doReconcile(ctx, ccm) + results, status := r.doReconcile(ctx, policy) // update status - if err := r.updateStatus(ctx, ccm, status); err != nil { + if err := r.updateStatus(ctx, policy, status); err != nil { if apierrors.IsConflict(err) { return results.WithRequeue().Aggregate() } @@ -150,12 +150,12 @@ func (r *ReconcileCloudConnectedMode) Reconcile(ctx context.Context, request rec return results.Aggregate() } -func (r *ReconcileCloudConnectedMode) doReconcile(ctx context.Context, ccm ccmv1alpha1.CloudConnectedMode) (*reconciler.Results, ccmv1alpha1.CloudConnectedModeStatus) { +func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { log := ulog.FromContext(ctx) - log.V(1).Info("Reconcile CloudConnectedMode") + log.V(1).Info("Reconcile AutoOpsAgentPolicy") results := reconciler.NewResult(ctx) - status := ccmv1alpha1.NewStatus(ccm) + status := autoopsv1alpha1.NewStatus(policy) defer status.Update() // Enterprise license check @@ -164,16 +164,16 @@ func (r *ReconcileCloudConnectedMode) doReconcile(ctx context.Context, ccm ccmv1 return results.WithError(err), status } if !enabled { - msg := "CloudConnectedMode is an enterprise feature. Enterprise features are disabled" + msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" log.Info(msg) - r.recorder.Eventf(&ccm, corev1.EventTypeWarning, events.EventReconciliationError, msg) + r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReconciliationError, msg) // we don't have a good way of watching for the license level to change so just requeue with a reasonably long delay return results.WithRequeue(5 * time.Minute), status } // run validation in case the webhook is disabled - if err := r.validate(ctx, &ccm); err != nil { - r.recorder.Eventf(&ccm, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) + if err := r.validate(ctx, &policy); err != nil { + r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) return results.WithError(err), status } @@ -187,28 +187,27 @@ func (r *ReconcileCloudConnectedMode) doReconcile(ctx context.Context, ccm ccmv1 return results, status } -func (r *ReconcileCloudConnectedMode) validate(ctx context.Context, ccm *ccmv1alpha1.CloudConnectedMode) error { +func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { span, vctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() - if _, err := ccm.ValidateCreate(); err != nil { + if _, err := policy.ValidateCreate(); err != nil { ulog.FromContext(ctx).Error(err, "Validation failed") - k8s.MaybeEmitErrorEvent(r.recorder, err, ccm, events.EventReasonValidation, err.Error()) + k8s.MaybeEmitErrorEvent(r.recorder, err, policy, events.EventReasonValidation, err.Error()) return tracing.CaptureError(vctx, err) } return nil } -func (r *ReconcileCloudConnectedMode) updateStatus(ctx context.Context, ccm ccmv1alpha1.CloudConnectedMode, status ccmv1alpha1.CloudConnectedModeStatus) error { +func (r *ReconcileAutoOpsAgentPolicy) updateStatus(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) error { span, _ := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() - if status.ObservedGeneration == ccm.Status.ObservedGeneration && - status.Resources == ccm.Status.Resources && - status.Ready == ccm.Status.Ready && - status.Errors == ccm.Status.Errors && - status.ReadyCount == ccm.Status.ReadyCount { + if status.ObservedGeneration == policy.Status.ObservedGeneration && + status.Resources == policy.Status.Resources && + status.Ready == policy.Status.Ready && + status.Errors == policy.Status.Errors { return nil // nothing to do } @@ -216,14 +215,13 @@ func (r *ReconcileCloudConnectedMode) updateStatus(ctx context.Context, ccm ccmv "iteration", atomic.LoadUint64(&r.iteration), "status", status, ) - ccm.Status = status - return common.UpdateStatus(ctx, r.Client, &ccm) + policy.Status = status + return common.UpdateStatus(ctx, r.Client, &policy) } -func (r *ReconcileCloudConnectedMode) onDelete(ctx context.Context, obj types.NamespacedName) error { +func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() // Remove dynamic watches on secrets // TODO: Add cleanup for any dynamic watches if needed - return reconciler.GarbageCollectSoftOwnedSecrets(ctx, r.Client, obj, ccmv1alpha1.Kind) + return reconciler.GarbageCollectSoftOwnedSecrets(ctx, r.Client, obj, autoopsv1alpha1.Kind) } - diff --git a/pkg/controller/common/scheme/scheme.go b/pkg/controller/common/scheme/scheme.go index bc8b73e97fa..9b82a8dadda 100644 --- a/pkg/controller/common/scheme/scheme.go +++ b/pkg/controller/common/scheme/scheme.go @@ -15,7 +15,7 @@ import ( agentv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/agent/v1alpha1" apmv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1" apmv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1beta1" - ccmv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/cloudconnectedmode/v1alpha1" + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" easv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoscaling/v1alpha1" beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" @@ -58,7 +58,7 @@ func SetupScheme() { agentv1alpha1.AddToScheme, emsv1alpha1.AddToScheme, policyv1alpha1.AddToScheme, - ccmv1alpha1.AddToScheme, + autoopsv1alpha1.AddToScheme, logstashv1alpha1.AddToScheme, } mustAddSchemeOnce(&addToScheme, schemes) From 871650560919765f5efee4ee543ebbdbb45e5f9f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 09:52:22 -0600 Subject: [PATCH 04/90] skeleton of controller logic. Signed-off-by: Michael Montgomery --- NOTICE.txt | 384 +++++++++--------- config/crds/v1/all-crds.yaml | 11 +- ...s.k8s.elastic.co_autoopsagentpolicies.yaml | 11 +- config/e2e/rbac.yaml | 13 + .../eck-operator-crds/templates/all-crds.yaml | 11 +- docs/reference/api-reference/main.md | 24 +- hack/api-docs/config.yaml | 4 +- hack/operatorhub/config.yaml | 3 + .../v1alpha1/autoopsagentpolicy_types.go | 28 +- pkg/apis/autoops/v1alpha1/webhook.go | 4 +- .../autoops/v1alpha1/zz_generated.deepcopy.go | 5 +- pkg/controller/autoops/controller.go | 64 +-- 12 files changed, 295 insertions(+), 267 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 2fe7c3ca302..59dc124d4a4 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -14,7 +14,7 @@ Version : v1.0.2 Time : 2025-05-07T20:15:06Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/dario.cat/mergo@v1.0.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/dario.cat/mergo@v1.0.2/LICENSE: Copyright (c) 2013 Dario Castañé. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -52,7 +52,7 @@ Version : v0.7.4 Time : 2025-07-10T02:38:34Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!kim!machine!gun/automemlimit@v0.7.4/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!kim!machine!gun/automemlimit@v0.7.4/LICENSE: MIT License @@ -83,7 +83,7 @@ Version : v3.3.0 Time : 2024-08-29T20:12:44Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -112,7 +112,7 @@ Version : v4.0.0 Time : 2020-05-24T15:15:11Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/blang/semver/v4@v4.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/blang/semver/v4@v4.0.0/LICENSE: The MIT License @@ -144,7 +144,7 @@ Version : v1.1.2-0.20180830191138-d8f796af33cc Time : 2018-08-30T19:11:38Z Licence : ISC -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: ISC License @@ -169,7 +169,7 @@ Version : v0.8.9-0.20250307075119-2a22403faaea Time : 2025-03-07T07:51:19Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-ucfg@v0.8.9-0.20250307075119-2a22403faaea/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/elastic/go-ucfg@v0.8.9-0.20250307075119-2a22403faaea/LICENSE: Apache License Version 2.0, January 2004 @@ -380,7 +380,7 @@ Version : v1.0.0 Time : 2017-03-27T23:54:44Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/ghodss/yaml@v1.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/ghodss/yaml@v1.0.0/LICENSE: The MIT License (MIT) @@ -440,7 +440,7 @@ Version : v0.5.14 Time : 2025-07-28T20:15:32Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/go-snaps@v0.5.14/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gkampitakis/go-snaps@v0.5.14/LICENSE: MIT License @@ -471,7 +471,7 @@ Version : v1.4.3 Time : 2025-05-19T04:56:57Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/logr@v1.4.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/logr@v1.4.3/LICENSE: Apache License Version 2.0, January 2004 @@ -682,7 +682,7 @@ Version : v1.1.1 Time : 2024-06-23T16:27:23Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-test/deep@v1.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-test/deep@v1.1.1/LICENSE: MIT License @@ -713,7 +713,7 @@ Version : v1.0.3 Time : 2024-09-21T13:43:45Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gobuffalo/flect@v1.0.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gobuffalo/flect@v1.0.3/LICENSE: The MIT License (MIT) @@ -744,7 +744,7 @@ Version : v0.7.0 Time : 2025-01-14T18:15:44Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/go-cmp@v0.7.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/go-cmp@v0.7.0/LICENSE: Copyright (c) 2017 The Go Authors. All rights reserved. @@ -781,7 +781,7 @@ Version : v0.20.6 Time : 2025-06-13T21:51:07Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/go-containerregistry@v0.20.6/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/go-containerregistry@v0.20.6/LICENSE: Apache License @@ -992,7 +992,7 @@ Version : v1.6.0 Time : 2024-01-23T18:54:04Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/uuid@v1.6.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/uuid@v1.6.0/LICENSE: Copyright (c) 2009,2014 Google Inc. All rights reserved. @@ -1029,7 +1029,7 @@ Version : v1.1.1 Time : 2021-03-11T20:17:12Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: Mozilla Public License, version 2.0 @@ -1392,7 +1392,7 @@ Version : v2.0.7 Time : 2023-09-21T18:26:40Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: Copyright (c) 2014 HashiCorp, Inc. @@ -1766,7 +1766,7 @@ Version : v1.21.0 Time : 2025-09-01T15:28:10Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/vault/api@v1.21.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/vault/api@v1.21.0/LICENSE: Copyright (c) 2015 HashiCorp, Inc. @@ -2141,7 +2141,7 @@ Version : v1.8.10 Time : 2025-04-09T19:30:57Z Licence : BSD-2-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/magiconair/properties@v1.8.10/LICENSE.md: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/magiconair/properties@v1.8.10/LICENSE.md: Copyright (c) 2013-2020, Frank Schroeder @@ -2175,7 +2175,7 @@ Version : v0.9.1 Time : 2020-01-14T19:47:44Z Licence : BSD-2-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pkg/errors@v0.9.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pkg/errors@v0.9.1/LICENSE: Copyright (c) 2015, Dave Cheney All rights reserved. @@ -2208,7 +2208,7 @@ Version : v1.0.1-0.20181226105442-5d4384ee4fb2 Time : 2018-12-26T10:54:42Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: Copyright (c) 2013, Patrick Mezard All rights reserved. @@ -2245,7 +2245,7 @@ Version : v1.23.2 Time : 2025-09-05T14:03:59Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/client_golang@v1.23.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/client_golang@v1.23.2/LICENSE: Apache License Version 2.0, January 2004 @@ -2456,7 +2456,7 @@ Version : v0.66.1 Time : 2025-09-05T07:53:47Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/common@v0.66.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/common@v0.66.1/LICENSE: Apache License Version 2.0, January 2004 @@ -2667,7 +2667,7 @@ Version : v0.3.1 Time : 2024-06-25T00:17:20Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sethvargo/go-password@v0.3.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sethvargo/go-password@v0.3.1/LICENSE: Copyright 2017 Seth Vargo @@ -2697,7 +2697,7 @@ Version : v1.10.1 Time : 2025-09-01T16:19:51Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/cobra@v1.10.1/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/cobra@v1.10.1/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -2881,7 +2881,7 @@ Version : v1.0.10 Time : 2025-09-02T06:08:29Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/pflag@v1.0.10/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/pflag@v1.0.10/LICENSE: Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -2919,7 +2919,7 @@ Version : v1.21.0 Time : 2025-09-08T16:56:14Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/viper@v1.21.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/viper@v1.21.0/LICENSE: The MIT License (MIT) @@ -2949,7 +2949,7 @@ Version : v1.11.1 Time : 2025-08-27T10:46:31Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stretchr/testify@v1.11.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stretchr/testify@v1.11.1/LICENSE: MIT License @@ -2980,7 +2980,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmelasticsearch/v2@v2.7.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/apm/module/apmelasticsearch/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3191,7 +3191,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmhttp/v2@v2.7.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/apm/module/apmhttp/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3402,7 +3402,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/module/apmzap/v2@v2.7.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/apm/module/apmzap/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3613,7 +3613,7 @@ Version : v2.7.1 Time : 2025-05-26T15:07:42Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/apm/v2@v2.7.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/apm/v2@v2.7.1/LICENSE: Apache License Version 2.0, January 2004 @@ -3824,7 +3824,7 @@ Version : v1.6.0 Time : 2024-09-23T17:47:22Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/automaxprocs@v1.6.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/automaxprocs@v1.6.0/LICENSE: Copyright (c) 2017 Uber Technologies, Inc. @@ -3852,7 +3852,7 @@ Version : v1.27.0 Time : 2024-02-20T20:55:06Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE: Copyright (c) 2016-2017 Uber Technologies, Inc. @@ -3881,7 +3881,7 @@ Version : v0.42.0 Time : 2025-09-08T15:14:28Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/crypto@v0.42.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/crypto@v0.42.0/LICENSE: Copyright 2009 The Go Authors. @@ -3918,7 +3918,7 @@ Version : v0.0.0-20240808152545-0cdaa3abc0fa Time : 2024-08-08T15:25:45Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: Copyright 2009 The Go Authors. @@ -3955,7 +3955,7 @@ Version : v3.0.1 Time : 2022-05-27T08:35:30Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/yaml.v3@v3.0.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/yaml.v3@v3.0.1/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -4015,7 +4015,7 @@ Version : v0.34.1 Time : 2025-09-10T04:39:36Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/api@v0.34.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/api@v0.34.1/LICENSE: Apache License @@ -4227,7 +4227,7 @@ Version : v0.34.1 Time : 2025-08-16T07:57:26Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apimachinery@v0.34.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/apimachinery@v0.34.1/LICENSE: Apache License @@ -4439,7 +4439,7 @@ Version : v0.34.1 Time : 2025-09-10T04:55:33Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/client-go@v0.34.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/client-go@v0.34.1/LICENSE: Apache License @@ -4651,7 +4651,7 @@ Version : v2.130.1 Time : 2024-06-20T00:51:19Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/klog/v2@v2.130.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/klog/v2@v2.130.1/LICENSE: Apache License Version 2.0, January 2004 @@ -4852,7 +4852,7 @@ Version : v0.0.0-20250604170112-4c0f3b243397 Time : 2025-06-04T17:01:12Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: Apache License @@ -5064,7 +5064,7 @@ Version : v0.22.1 Time : 2025-09-05T13:19:27Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/controller-runtime@v0.22.1/LICENSE: Apache License Version 2.0, January 2004 @@ -5275,7 +5275,7 @@ Version : v0.19.0 Time : 2025-08-28T05:51:10Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5492,7 +5492,7 @@ Version : v0.24.0 Time : 2025-05-07T15:31:15Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/cel.dev/expr@v0.24.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/cel.dev/expr@v0.24.0/LICENSE: Apache License @@ -5704,7 +5704,7 @@ Version : v1.1.1 Time : 2021-02-04T20:06:53Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: Apache License @@ -5916,7 +5916,7 @@ Version : v3.3.0 Time : 2024-08-27T21:33:28Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: Copyright (C) 2014-2019, Matt Butcher and Matt Farina @@ -5945,7 +5945,7 @@ Version : v4.13.0 Time : 2023-05-19T05:49:53Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: Copyright (c) 2012-2023 The ANTLR Project. All rights reserved. @@ -5983,7 +5983,7 @@ Version : v1.0.0 Time : 2018-08-24T02:57:28Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/armon/go-radix@v1.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/armon/go-radix@v1.0.0/LICENSE: The MIT License (MIT) @@ -6013,7 +6013,7 @@ Version : v0.0.0-20160902184237-e75332964ef5 Time : 2016-09-02T18:42:37Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: The MIT License (MIT) @@ -6043,7 +6043,7 @@ Version : v1.0.1 Time : 2019-07-31T12:00:54Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/beorn7/perks@v1.0.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/beorn7/perks@v1.0.1/LICENSE: Copyright (C) 2013 Blake Mizerany @@ -6073,7 +6073,7 @@ Version : v4.3.0 Time : 2024-01-02T22:56:19Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: The MIT License (MIT) @@ -6103,7 +6103,7 @@ Version : v2.3.0 Time : 2024-04-04T20:00:10Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: Copyright (c) 2016 Caleb Spare @@ -6135,7 +6135,7 @@ Version : v0.16.3 Time : 2024-12-12T14:42:49Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: Apache License @@ -6347,7 +6347,7 @@ Version : v28.2.2+incompatible Time : 2025-05-30T09:39:08Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/cli@v28.2.2+incompatible/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/cli@v28.2.2+incompatible/LICENSE: Apache License @@ -6548,7 +6548,7 @@ Version : v2.8.3+incompatible Time : 2023-10-02T17:09:30Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: Apache License Version 2.0, January 2004 @@ -6760,7 +6760,7 @@ Version : v0.9.3 Time : 2025-03-14T11:52:36Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: Copyright (c) 2016 David Calavera @@ -6790,7 +6790,7 @@ Version : v1.15.2 Time : 2025-03-25T02:52:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: Apache License @@ -7002,7 +7002,7 @@ Version : v1.0.2 Time : 2024-03-25T02:36:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: Apache License @@ -7214,7 +7214,7 @@ Version : v3.12.2 Time : 2025-02-26T09:20:34Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: Copyright (c) 2012,2013 Ernest Micklei @@ -7245,7 +7245,7 @@ Version : v5.6.0+incompatible Time : 2021-10-20T18:47:23Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7280,7 +7280,7 @@ Version : v5.9.11 Time : 2025-01-28T17:43:52Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7315,7 +7315,7 @@ Version : v1.18.0 Time : 2024-10-03T07:06:28Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fatih/color@v1.18.0/LICENSE.md: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fatih/color@v1.18.0/LICENSE.md: The MIT License (MIT) @@ -7345,7 +7345,7 @@ Version : v1.0.4 Time : 2023-03-12T10:31:09Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) @@ -7374,7 +7374,7 @@ Version : v1.14.6 Time : 2023-08-01T06:27:26Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/frankban/quicktest@v1.14.6/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/frankban/quicktest@v1.14.6/LICENSE: MIT License @@ -7405,7 +7405,7 @@ Version : v1.9.0 Time : 2025-04-04T15:13:49Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: Copyright © 2012 The Go Authors. All rights reserved. Copyright © fsnotify Authors. All rights reserved. @@ -7440,7 +7440,7 @@ Version : v2.9.0 Time : 2025-07-14T04:00:34Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: MIT License @@ -7470,7 +7470,7 @@ Version : v0.3.2 Time : 2025-02-02T10:01:22Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: MIT License @@ -7501,7 +7501,7 @@ Version : v1.3.2 Time : 2023-02-18T11:30:13Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: Copyright (c) 2012-2016 The go-diff Authors. All rights reserved. @@ -7531,7 +7531,7 @@ Version : v4.1.1 Time : 2025-06-23T23:41:10Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: Apache License @@ -7743,7 +7743,7 @@ Version : v1.2.2 Time : 2021-12-14T08:00:35Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/stdr@v1.2.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/stdr@v1.2.2/LICENSE: Apache License Version 2.0, January 2004 @@ -7954,7 +7954,7 @@ Version : v1.3.0 Time : 2023-11-03T09:58:42Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-logr/zapr@v1.3.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/zapr@v1.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -8165,7 +8165,7 @@ Version : v0.21.0 Time : 2024-03-09T18:18:34Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: Apache License @@ -8377,7 +8377,7 @@ Version : v0.21.0 Time : 2024-03-09T18:23:36Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: Apache License @@ -8589,7 +8589,7 @@ Version : v0.23.0 Time : 2024-03-09T18:11:11Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-openapi/swag@v0.23.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/swag@v0.23.0/LICENSE: Apache License @@ -8801,7 +8801,7 @@ Version : v3.0.0 Time : 2023-09-14T01:46:41Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -8830,7 +8830,7 @@ Version : v2.4.0 Time : 2025-07-15T08:59:08Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: The MIT License (MIT) @@ -8861,7 +8861,7 @@ Version : v1.18.0 Time : 2025-05-29T05:13:29Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/goccy/go-yaml@v1.18.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/goccy/go-yaml@v1.18.0/LICENSE: MIT License @@ -8892,7 +8892,7 @@ Version : v1.3.2 Time : 2021-01-10T08:01:47Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gogo/protobuf@v1.3.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gogo/protobuf@v1.3.2/LICENSE: Copyright (c) 2013, The GoGo Authors. All rights reserved. @@ -8937,7 +8937,7 @@ Version : v1.5.4 Time : 2024-03-06T06:45:40Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/golang/protobuf@v1.5.4/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/golang/protobuf@v1.5.4/LICENSE: Copyright 2010 The Go Authors. All rights reserved. @@ -8975,7 +8975,7 @@ Version : v1.1.3 Time : 2024-08-21T16:26:17Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/btree@v1.1.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/btree@v1.1.3/LICENSE: Apache License @@ -9187,7 +9187,7 @@ Version : v0.26.0 Time : 2025-07-14T20:45:46Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/cel-go@v0.26.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/cel-go@v0.26.0/LICENSE: Apache License @@ -9430,7 +9430,7 @@ Version : v0.7.0 Time : 2025-06-26T15:23:00Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/gnostic-models@v0.7.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/gnostic-models@v0.7.0/LICENSE: Apache License @@ -9643,7 +9643,7 @@ Version : v1.2.0 Time : 2020-08-04T22:43:24Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/gofuzz@v1.2.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/gofuzz@v1.2.0/LICENSE: Apache License @@ -9855,7 +9855,7 @@ Version : v0.0.0-20241029153458-d1b30febd7db Time : 2024-10-29T15:34:58Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: Apache License @@ -10067,7 +10067,7 @@ Version : v1.5.4-0.20250319132907-e064f32e3674 Time : 2025-03-19T13:29:07Z Licence : BSD-2-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. @@ -10099,7 +10099,7 @@ Version : v2.26.3 Time : 2025-03-04T17:40:45Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: Copyright (c) 2015, Gengo, Inc. All rights reserved. @@ -10136,7 +10136,7 @@ Version : v1.1.0 Time : 2020-07-14T15:51:01Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/errwrap@v1.1.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/errwrap@v1.1.0/LICENSE: Mozilla Public License, version 2.0 @@ -10500,7 +10500,7 @@ Version : v0.5.2 Time : 2021-02-03T18:51:13Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: Mozilla Public License, version 2.0 @@ -10873,7 +10873,7 @@ Version : v1.6.3 Time : 2024-04-01T20:03:54Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: Copyright (c) 2017 HashiCorp, Inc. @@ -10902,7 +10902,7 @@ Version : v0.7.8 Time : 2025-06-18T14:25:10Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: Copyright (c) 2015 HashiCorp, Inc. @@ -11277,7 +11277,7 @@ Version : v1.0.2 Time : 2019-12-10T09:55:28Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: Mozilla Public License, version 2.0 @@ -11650,7 +11650,7 @@ Version : v0.2.0 Time : 2025-03-06T22:34:24Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: Copyright (c) 2020 HashiCorp, Inc. @@ -12025,7 +12025,7 @@ Version : v0.1.2 Time : 2021-11-22T19:44:14Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: Mozilla Public License, version 2.0 @@ -12398,7 +12398,7 @@ Version : v1.0.7 Time : 2024-09-19T09:47:04Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: Copyright (c) 2016 HashiCorp, Inc. @@ -12783,7 +12783,7 @@ Version : v1.0.1-vault-7 Time : 2024-11-07T22:23:56Z Licence : MPL-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: Mozilla Public License, version 2.0 @@ -13147,7 +13147,7 @@ Version : v1.5.0 Time : 2024-06-06T08:07:36Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/huandu/xstrings@v1.5.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/huandu/xstrings@v1.5.0/LICENSE: The MIT License (MIT) @@ -13179,7 +13179,7 @@ Version : v1.1.0 Time : 2022-11-27T22:01:53Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -13390,7 +13390,7 @@ Version : v1.0.0 Time : 2019-12-14T22:12:22Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/josharian/intern@v1.0.0/license.md: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/josharian/intern@v1.0.0/license.md: MIT License @@ -13421,7 +13421,7 @@ Version : v1.1.12 Time : 2021-09-11T02:17:26Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/json-iterator/go@v1.1.12/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/json-iterator/go@v1.1.12/LICENSE: MIT License @@ -13452,7 +13452,7 @@ Version : v1.18.0 Time : 2025-02-19T09:26:03Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/klauspost/compress@v1.18.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/klauspost/compress@v1.18.0/LICENSE: Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. @@ -13766,7 +13766,7 @@ Version : v0.3.1 Time : 2022-08-29T23:03:05Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kr/pretty@v0.3.1/License: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kr/pretty@v0.3.1/License: Copyright 2012 Keith Rarick @@ -13795,7 +13795,7 @@ Version : v0.2.0 Time : 2020-02-14T20:31:06Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kr/text@v0.2.0/License: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kr/text@v0.2.0/License: Copyright 2012 Keith Rarick @@ -13824,7 +13824,7 @@ Version : v1.1.0 Time : 2019-05-05T01:16:37Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/kylelemons/godebug@v1.1.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kylelemons/godebug@v1.1.0/LICENSE: Apache License @@ -14036,7 +14036,7 @@ Version : v0.7.7 Time : 2021-02-06T19:00:08Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mailru/easyjson@v0.7.7/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mailru/easyjson@v0.7.7/LICENSE: Copyright (c) 2016 Mail.Ru Group @@ -14053,7 +14053,7 @@ Version : v1.1.1 Time : 2023-11-03T01:37:02Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/maruel/natural@v1.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/maruel/natural@v1.1.1/LICENSE: Apache License Version 2.0, January 2004 @@ -14264,7 +14264,7 @@ Version : v0.1.14 Time : 2025-01-10T08:29:27Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mattn/go-colorable@v0.1.14/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mattn/go-colorable@v0.1.14/LICENSE: The MIT License (MIT) @@ -14295,7 +14295,7 @@ Version : v0.0.20 Time : 2023-10-17T07:28:21Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mattn/go-isatty@v0.0.20/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mattn/go-isatty@v0.0.20/LICENSE: Copyright (c) Yasuhiro MATSUMOTO @@ -14314,7 +14314,7 @@ Version : v1.2.0 Time : 2021-05-05T17:08:07Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/copystructure@v1.2.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/copystructure@v1.2.0/LICENSE: The MIT License (MIT) @@ -14345,7 +14345,7 @@ Version : v1.1.0 Time : 2019-01-27T04:21:35Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: The MIT License (MIT) @@ -14376,7 +14376,7 @@ Version : v1.5.0 Time : 2022-04-20T22:31:31Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: The MIT License (MIT) @@ -14407,7 +14407,7 @@ Version : v1.0.2 Time : 2021-05-03T23:34:11Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: The MIT License (MIT) @@ -14438,7 +14438,7 @@ Version : v0.5.0 Time : 2024-07-23T13:25:06Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/moby/spdystream@v0.5.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/moby/spdystream@v0.5.0/LICENSE: Apache License @@ -14650,7 +14650,7 @@ Version : v0.0.0-20180306012644-bacd9c7ef1dd Time : 2018-03-06T01:26:44Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: Apache License Version 2.0, January 2004 @@ -14861,7 +14861,7 @@ Version : v1.0.3-0.20250322232337-35a7c28c31ee Time : 2025-03-22T23:23:37Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: Apache License Version 2.0, January 2004 @@ -15113,7 +15113,7 @@ Version : v0.0.0-20140419014527-cca7078d478f Time : 2014-04-19T01:45:27Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: Copyright (c) 2014 The Go-FlowRate Authors. All rights reserved. @@ -15152,7 +15152,7 @@ Version : v1.4.8 Time : 2021-02-07T16:08:07Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/nxadm/tail@v1.4.8/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/nxadm/tail@v1.4.8/LICENSE: # The MIT License (MIT) @@ -15183,7 +15183,7 @@ Version : v1.16.5 Time : 2021-10-11T17:27:58Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/ginkgo@v1.16.5/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/ginkgo@v1.16.5/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15213,7 +15213,7 @@ Version : v2.22.0 Time : 2024-11-21T01:19:21Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15243,7 +15243,7 @@ Version : v1.38.1 Time : 2025-08-22T13:45:44Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/onsi/gomega@v1.38.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/gomega@v1.38.1/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15273,7 +15273,7 @@ Version : v1.0.0 Time : 2020-05-14T01:46:00Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/opencontainers/go-digest@v1.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/opencontainers/go-digest@v1.0.0/LICENSE: Apache License @@ -15475,7 +15475,7 @@ Version : v1.1.1 Time : 2025-02-24T17:26:57Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/opencontainers/image-spec@v1.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/opencontainers/image-spec@v1.1.1/LICENSE: Apache License @@ -15676,7 +15676,7 @@ Version : v0.0.0-20210728143218-7b4eea64cf58 Time : 2021-07-28T14:32:18Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: BSD 3-Clause License @@ -15715,7 +15715,7 @@ Version : v2.2.4 Time : 2025-04-07T11:11:38Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: The MIT License (MIT) @@ -15747,7 +15747,7 @@ Version : v1.1.0 Time : 2021-12-11T19:29:36Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prashantv/gostub@v1.1.0/LICENSE.md: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prashantv/gostub@v1.1.0/LICENSE.md: The MIT License (MIT) @@ -15778,7 +15778,7 @@ Version : v0.6.2 Time : 2025-04-11T05:38:16Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/client_model@v0.6.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/client_model@v0.6.2/LICENSE: Apache License Version 2.0, January 2004 @@ -15989,7 +15989,7 @@ Version : v0.16.1 Time : 2025-04-19T15:43:08Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/prometheus/procfs@v0.16.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/procfs@v0.16.1/LICENSE: Apache License Version 2.0, January 2004 @@ -16200,7 +16200,7 @@ Version : v1.13.1 Time : 2024-09-23T11:44:11Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: Copyright (c) 2018 The Go Authors. All rights reserved. @@ -16237,7 +16237,7 @@ Version : v1.0.0 Time : 2019-01-24T19:22:32Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/ryanuber/go-glob@v1.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/ryanuber/go-glob@v1.0.0/LICENSE: The MIT License (MIT) @@ -16268,7 +16268,7 @@ Version : v0.11.0 Time : 2025-09-08T16:42:20Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: Copyright (c) 2023 Márk Sági-Kazár @@ -16297,7 +16297,7 @@ Version : v1.4.0 Time : 2024-04-12T14:15:38Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/shopspring/decimal@v1.4.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/shopspring/decimal@v1.4.0/LICENSE: The MIT License (MIT) @@ -16352,7 +16352,7 @@ Version : v1.9.3 Time : 2023-05-21T12:59:35Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sirupsen/logrus@v1.9.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sirupsen/logrus@v1.9.3/LICENSE: The MIT License (MIT) @@ -16383,7 +16383,7 @@ Version : v0.3.1-0.20240121214520-5f936abd7ae8 Time : 2024-01-21T21:45:20Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: MIT License @@ -16414,7 +16414,7 @@ Version : v1.15.0 Time : 2025-09-08T16:25:29Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/afero@v1.15.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/afero@v1.15.0/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -16598,7 +16598,7 @@ Version : v1.10.0 Time : 2025-09-08T16:45:31Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/spf13/cast@v1.10.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/cast@v1.10.0/LICENSE: The MIT License (MIT) @@ -16628,7 +16628,7 @@ Version : v1.3.0 Time : 2023-03-27T23:57:07Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stoewer/go-strcase@v1.3.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stoewer/go-strcase@v1.3.0/LICENSE: The MIT License (MIT) @@ -16659,7 +16659,7 @@ Version : v0.5.2 Time : 2024-02-29T09:57:51Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/stretchr/objx@v0.5.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stretchr/objx@v0.5.2/LICENSE: The MIT License @@ -16691,7 +16691,7 @@ Version : v1.6.0 Time : 2023-08-15T12:05:45Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/subosito/gotenv@v1.6.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/subosito/gotenv@v1.6.0/LICENSE: The MIT License (MIT) @@ -16722,7 +16722,7 @@ Version : v1.18.0 Time : 2024-10-02T03:45:20Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/gjson@v1.18.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/gjson@v1.18.0/LICENSE: The MIT License (MIT) @@ -16752,7 +16752,7 @@ Version : v1.1.1 Time : 2021-10-08T14:36:13Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/match@v1.1.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/match@v1.1.1/LICENSE: The MIT License (MIT) @@ -16782,7 +16782,7 @@ Version : v1.2.1 Time : 2022-10-01T20:21:24Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/pretty@v1.2.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/pretty@v1.2.1/LICENSE: The MIT License (MIT) @@ -16812,7 +16812,7 @@ Version : v1.2.5 Time : 2022-08-05T01:15:59Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/tidwall/sjson@v1.2.5/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/sjson@v1.2.5/LICENSE: The MIT License (MIT) @@ -16843,7 +16843,7 @@ Version : v0.12.1 Time : 2025-01-30T22:58:54Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/vbatts/tar-split@v0.12.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/vbatts/tar-split@v0.12.1/LICENSE: Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA @@ -16881,7 +16881,7 @@ Version : v0.8.4 Time : 2020-01-17T18:31:28Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/github.com/x448/float16@v0.8.4/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/x448/float16@v0.8.4/LICENSE: MIT License @@ -16913,7 +16913,7 @@ Version : v1.5.1 Time : 2025-05-06T14:56:09Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.elastic.co/fastjson@v1.5.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/fastjson@v1.5.1/LICENSE: Copyright 2018 Elasticsearch BV @@ -16946,7 +16946,7 @@ Version : v1.1.0 Time : 2024-12-05T17:49:43Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17157,7 +17157,7 @@ Version : v0.61.0 Time : 2025-05-22T14:29:43Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17368,7 +17368,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel@v1.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17579,7 +17579,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17790,7 +17790,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18001,7 +18001,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18212,7 +18212,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18423,7 +18423,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18634,7 +18634,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18845,7 +18845,7 @@ Version : v1.5.0 Time : 2025-01-06T12:02:47Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: Apache License Version 2.0, January 2004 @@ -19056,7 +19056,7 @@ Version : v1.3.0 Time : 2023-10-24T16:28:03Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/goleak@v1.3.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/goleak@v1.3.0/LICENSE: The MIT License (MIT) @@ -19087,7 +19087,7 @@ Version : v1.11.0 Time : 2023-03-29T23:00:37Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.uber.org/multierr@v1.11.0/LICENSE.txt: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/multierr@v1.11.0/LICENSE.txt: Copyright (c) 2017-2021 Uber Technologies, Inc. @@ -19116,7 +19116,7 @@ Version : v2.4.2 Time : 2025-06-02T16:37:17Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.yaml.in/yaml/v2@v2.4.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.yaml.in/yaml/v2@v2.4.2/LICENSE: Apache License Version 2.0, January 2004 @@ -19327,7 +19327,7 @@ Version : v3.0.4 Time : 2025-06-29T14:09:51Z Licence : MIT -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/go.yaml.in/yaml/v3@v3.0.4/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.yaml.in/yaml/v3@v3.0.4/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -19387,7 +19387,7 @@ Version : v0.27.0 Time : 2025-08-07T14:51:59Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/mod@v0.27.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/mod@v0.27.0/LICENSE: Copyright 2009 The Go Authors. @@ -19424,7 +19424,7 @@ Version : v0.43.0 Time : 2025-08-07T19:56:06Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/net@v0.43.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/net@v0.43.0/LICENSE: Copyright 2009 The Go Authors. @@ -19461,7 +19461,7 @@ Version : v0.30.0 Time : 2025-04-30T15:42:02Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/oauth2@v0.30.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/oauth2@v0.30.0/LICENSE: Copyright 2009 The Go Authors. @@ -19498,7 +19498,7 @@ Version : v0.17.0 Time : 2025-08-13T14:47:05Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/sync@v0.17.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/sync@v0.17.0/LICENSE: Copyright 2009 The Go Authors. @@ -19535,7 +19535,7 @@ Version : v0.36.0 Time : 2025-09-05T15:44:06Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/sys@v0.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/sys@v0.36.0/LICENSE: Copyright 2009 The Go Authors. @@ -19572,7 +19572,7 @@ Version : v0.35.0 Time : 2025-09-08T03:32:07Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/term@v0.35.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/term@v0.35.0/LICENSE: Copyright 2009 The Go Authors. @@ -19609,7 +19609,7 @@ Version : v0.29.0 Time : 2025-09-08T03:32:21Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/text@v0.29.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/text@v0.29.0/LICENSE: Copyright 2009 The Go Authors. @@ -19646,7 +19646,7 @@ Version : v0.12.0 Time : 2025-06-04T19:36:50Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/time@v0.12.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/time@v0.12.0/LICENSE: Copyright 2009 The Go Authors. @@ -19683,7 +19683,7 @@ Version : v0.36.0 Time : 2025-08-07T20:42:58Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools@v0.36.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/tools@v0.36.0/LICENSE: Copyright 2009 The Go Authors. @@ -19720,7 +19720,7 @@ Version : v0.1.0-deprecated Time : 2025-06-12T15:17:39Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19757,7 +19757,7 @@ Version : v0.1.1-deprecated Time : 2025-06-13T18:44:18Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19794,7 +19794,7 @@ Version : v2.4.0 Time : 2023-08-14T02:23:48Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -20006,7 +20006,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20218,7 +20218,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20430,7 +20430,7 @@ Version : v1.72.1 Time : 2025-05-14T09:00:17Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/grpc@v1.72.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/grpc@v1.72.1/LICENSE: Apache License @@ -20642,7 +20642,7 @@ Version : v1.36.8 Time : 2025-08-20T14:38:26Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/google.golang.org/protobuf@v1.36.8/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/protobuf@v1.36.8/LICENSE: Copyright (c) 2018 The Go Authors. All rights reserved. @@ -20679,7 +20679,7 @@ Version : v1.0.0-20201130134442-10cb98267c6c Time : 2020-11-30T13:44:42Z Licence : BSD-2-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: Gocheck - A rich testing framework for Go @@ -20714,7 +20714,7 @@ Version : v4.12.0 Time : 2021-10-21T16:40:42Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -20749,7 +20749,7 @@ Version : v0.9.1 Time : 2018-03-26T17:23:32Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/inf.v0@v0.9.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/inf.v0@v0.9.1/LICENSE: Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go Authors. All rights reserved. @@ -20787,7 +20787,7 @@ Version : v1.0.0-20141024135613-dd632973f1e7 Time : 2014-10-24T13:56:13Z Licence : BSD-3-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: tomb - support for clean goroutine termination in Go. @@ -20826,7 +20826,7 @@ Version : v2.4.0 Time : 2020-11-17T15:46:20Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gopkg.in/yaml.v2@v2.4.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/yaml.v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -21037,7 +21037,7 @@ Version : v3.0.3 Time : 2020-09-27T20:53:12Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/gotest.tools/v3@v3.0.3/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gotest.tools/v3@v3.0.3/LICENSE: Copyright 2018 gotest.tools authors @@ -21060,7 +21060,7 @@ Version : v1.0.1 Time : 2023-10-24T16:34:31Z Licence : BSD-2-Clause -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/howett.net/plist@v1.0.1/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/howett.net/plist@v1.0.1/LICENSE: Copyright (c) 2013, Dustin L. Howett. All rights reserved. @@ -21128,7 +21128,7 @@ Version : v0.34.0 Time : 2025-08-27T20:41:17Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apiextensions-apiserver@v0.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/apiextensions-apiserver@v0.34.0/LICENSE: Apache License @@ -21340,7 +21340,7 @@ Version : v0.34.0 Time : 2025-08-27T20:24:55Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/apiserver@v0.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/apiserver@v0.34.0/LICENSE: Apache License @@ -21552,7 +21552,7 @@ Version : v0.34.0 Time : 2025-08-27T20:05:46Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/code-generator@v0.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/code-generator@v0.34.0/LICENSE: Apache License @@ -21764,7 +21764,7 @@ Version : v0.34.0 Time : 2025-08-27T20:09:10Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/component-base@v0.34.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/component-base@v0.34.0/LICENSE: Apache License @@ -21976,7 +21976,7 @@ Version : v2.0.0-20250604051438-85fd79dbfd9f Time : 2025-06-04T05:14:38Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: Apache License @@ -22188,7 +22188,7 @@ Version : v0.0.0-20250710124328-f3f2b991d03b Time : 2025-07-10T12:43:28Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: Apache License @@ -22400,7 +22400,7 @@ Version : v0.31.2 Time : 2025-02-07T00:45:56Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: Apache License Version 2.0, January 2004 @@ -22611,7 +22611,7 @@ Version : v0.0.0-20241014173422-cfa47c3a1cc8 Time : 2024-10-14T17:34:22Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: Files other than internal/golang/* licensed under: @@ -22859,7 +22859,7 @@ Version : v1.0.0 Time : 2025-03-04T18:23:53Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/randfill@v1.0.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/randfill@v1.0.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23071,7 +23071,7 @@ Version : v6.3.0 Time : 2025-07-16T20:34:24Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23282,7 +23282,7 @@ Version : v1.6.0 Time : 2025-07-24T18:12:28Z Licence : Apache-2.0 -Contents of probable licence file /Users/mmontgomery/.asdf/installs/golang/1.24.5/packages/pkg/mod/sigs.k8s.io/yaml@v1.6.0/LICENSE: +Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/yaml@v1.6.0/LICENSE: The MIT License (MIT) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 9d1a6540760..325ceffbe0c 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2373,8 +2373,8 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - description: Resources configured - jsonPath: .status.readyCount + - description: Ready resources + jsonPath: .status.ready name: Ready type: string - jsonPath: .status.phase @@ -2421,6 +2421,10 @@ spec: tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf + properties: + secretName: + description: SecretName is the name of the secret. + type: string type: object resourceSelector: description: |- @@ -2482,6 +2486,9 @@ spec: for this AutoOpsAgentPolicy. format: int64 type: integer + phase: + description: Phase is the phase of the AutoOpsAgentPolicy. + type: string ready: description: Ready is the number of resources that are in a ready state. diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 95f55e640bd..780e1ea0722 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -19,8 +19,8 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - description: Resources configured - jsonPath: .status.readyCount + - description: Ready resources + jsonPath: .status.ready name: Ready type: string - jsonPath: .status.phase @@ -67,6 +67,10 @@ spec: tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf + properties: + secretName: + description: SecretName is the name of the secret. + type: string type: object resourceSelector: description: |- @@ -128,6 +132,9 @@ spec: for this AutoOpsAgentPolicy. format: int64 type: integer + phase: + description: Phase is the phase of the AutoOpsAgentPolicy. + type: string ready: description: Ready is the number of resources that are in a ready state. diff --git a/config/e2e/rbac.yaml b/config/e2e/rbac.yaml index e91b8be2c56..777f36537ad 100644 --- a/config/e2e/rbac.yaml +++ b/config/e2e/rbac.yaml @@ -386,6 +386,19 @@ rules: verbs: - get - list + - apiGroups: + - autoops.k8s.elastic.co + resources: + - autoopsagentpolicies + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - deletecollection --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 18762a61f1f..8f9ee0a5699 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2394,8 +2394,8 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - description: Resources configured - jsonPath: .status.readyCount + - description: Ready resources + jsonPath: .status.ready name: Ready type: string - jsonPath: .status.phase @@ -2442,6 +2442,10 @@ spec: tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf + properties: + secretName: + description: SecretName is the name of the secret. + type: string type: object resourceSelector: description: |- @@ -2503,6 +2507,9 @@ spec: for this AutoOpsAgentPolicy. format: int64 type: integer + phase: + description: Phase is the phase of the AutoOpsAgentPolicy. + type: string ready: description: Ready is the number of resources that are in a ready state. diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 6b6d77aa7d4..0d9a043ff46 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -263,7 +263,6 @@ Package v1alpha1 contains API schema definitions for managing AutoOpsAgentPolicy ### Resource Types - [AutoOpsAgentPolicy](#autoopsagentpolicy) -- [AutoOpsAgentPolicyList](#autoopsagentpolicylist) @@ -271,10 +270,7 @@ Package v1alpha1 contains API schema definitions for managing AutoOpsAgentPolicy AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. -:::{admonition} Appears In: -* [AutoOpsAgentPolicyList](#autoopsagentpolicylist) -::: | Field | Description | | --- | --- | @@ -284,20 +280,6 @@ AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes clu | *`spec`* __[AutoOpsAgentPolicySpec](#autoopsagentpolicyspec)__ | | -### AutoOpsAgentPolicyList [#autoopsagentpolicylist] - -AutoOpsAgentPolicyList contains a list of AutoOpsAgentPolicy resources. - - - -| Field | Description | -| --- | --- | -| *`apiVersion`* __string__ | `autoops.k8s.elastic.co/v1alpha1` | -| *`kind`* __string__ | `AutoOpsAgentPolicyList` | -| *`metadata`* __[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#listmeta-v1-meta)__ | Refer to Kubernetes API documentation for fields of `metadata`. | -| *`items`* __[AutoOpsAgentPolicy](#autoopsagentpolicy) array__ | | - - ### AutoOpsAgentPolicySpec [#autoopsagentpolicyspec] @@ -310,7 +292,9 @@ AutoOpsAgentPolicyList contains a list of AutoOpsAgentPolicy resources. | Field | Description | | --- | --- | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | -| *`config`* __[Config](#config)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | + + @@ -466,7 +450,6 @@ Config represents untyped YAML configuration. :::{admonition} Appears In: * [AgentSpec](#agentspec) * [ApmServerSpec](#apmserverspec) -* [AutoOpsAgentPolicySpec](#autoopsagentpolicyspec) * [BeatSpec](#beatspec) * [ElasticsearchConfigPolicySpec](#elasticsearchconfigpolicyspec) * [EnterpriseSearchSpec](#enterprisesearchspec) @@ -503,6 +486,7 @@ ConfigSource references configuration settings. :::{admonition} Appears In: * [AgentSpec](#agentspec) +* [AutoOpsAgentPolicySpec](#autoopsagentpolicyspec) * [BeatSpec](#beatspec) * [EnterpriseSearchSpec](#enterprisesearchspec) * [EnterpriseSearchSpec](#enterprisesearchspec) diff --git a/hack/api-docs/config.yaml b/hack/api-docs/config.yaml index 9de00ab123f..7c73b787f96 100644 --- a/hack/api-docs/config.yaml +++ b/hack/api-docs/config.yaml @@ -1,8 +1,8 @@ processor: ignoreTypes: - - "(Elasticsearch|ElasticsearchAutoscaler|Kibana|ApmServer|EnterpriseSearch|Beat|Agent|StackConfigPolicy|Logstash|NodeSetNodeCount)List$" + - "(Elasticsearch|ElasticsearchAutoscaler|Kibana|ApmServer|EnterpriseSearch|Beat|Agent|StackConfigPolicy|Logstash|NodeSetNodeCount|AutoOpsAgentPolicy)List$" - "(Kibana|ApmServer|EnterpriseSearch|Beat|Agent|StackConfigPolicy)Health$" - - "(ElasticsearchAutoscaler|Kibana|ApmServer|Reconciler|EnterpriseSearch|Beat|Agent|Maps|Policy|Deployment)Status$" + - "(ElasticsearchAutoscaler|Kibana|ApmServer|Reconciler|EnterpriseSearch|Beat|Agent|Maps|Policy|Deployment|AutoOpsAgentPolicy)Status$" - "ElasticsearchSettings$" - "Associa(ted|tion|tionStatus|tionConf)$" - "AssociationStatusMap" diff --git a/hack/operatorhub/config.yaml b/hack/operatorhub/config.yaml index 41d34a1ce4c..bd591adb78c 100644 --- a/hack/operatorhub/config.yaml +++ b/hack/operatorhub/config.yaml @@ -32,6 +32,9 @@ crds: - name: logstashes.logstash.k8s.elastic.co displayName: Logstash description: Logstash instance + - name: autoopsagentpolicies.autoops.k8s.elastic.co + displayName: AutoOps Agent Policy + description: AutoOps Agent Policy instance packages: - outputPath: community-operators packageName: elastic-cloud-eck diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index a3875c25ddf..7647ccc7327 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -6,7 +6,6 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" ) @@ -27,7 +26,7 @@ func init() { // AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. // +kubebuilder:resource:categories=elastic,shortName=autoops -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.readyCount",description="Resources configured" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Ready resources" // +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" // +kubebuilder:subresource:status @@ -64,7 +63,7 @@ type AutoOpsAgentPolicySpec struct { // tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao // autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co // autoOpsToken: skdfjdskjf - Config *commonv1.Config `json:"config,omitempty"` + Config commonv1.ConfigSource `json:"config,omitempty"` // AutoOpsRef is a reference to an AutoOps instance running in the same Kubernetes cluster. // (TODO) AutoOpsRef is not yet implemented. // AutoOpsRef commonv1.ObjectSelector `json:"autoOpsRef,omitempty"` @@ -77,14 +76,26 @@ type AutoOpsAgentPolicyStatus struct { Ready int `json:"ready,omitempty"` // Errors is the number of resources that are in an error state. Errors int `json:"errors,omitempty"` + // Phase is the phase of the AutoOpsAgentPolicy. + Phase PolicyPhase `json:"phase,omitempty"` // ObservedGeneration is the most recent generation observed for this AutoOpsAgentPolicy. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } +type PolicyPhase string + +const ( + UnknownPhase PolicyPhase = "Unknown" + ReadyPhase PolicyPhase = "Ready" + ApplyingChangesPhase PolicyPhase = "ApplyingChanges" + InvalidPhase PolicyPhase = "Invalid" + ErrorPhase PolicyPhase = "Error" +) + func NewStatus(policy AutoOpsAgentPolicy) AutoOpsAgentPolicyStatus { status := AutoOpsAgentPolicyStatus{ // Details: map[ResourceType]map[string]ResourcePolicyStatus{}, - // Phase: ReadyPhase, + Phase: UnknownPhase, ObservedGeneration: policy.Generation, } return status @@ -94,16 +105,7 @@ func NewStatus(policy AutoOpsAgentPolicy) AutoOpsAgentPolicyStatus { func (s *AutoOpsAgentPolicyStatus) Update() { } -// IsDegraded returns true when the AutoOpsAgentPolicyStatus resource is degraded compared to the previous status. -// func (s AutoOpsAgentPolicyStatus) IsDegraded(prev AutoOpsAgentPolicyStatus) bool { -// return prev.Phase == ReadyPhase && s.Phase != ReadyPhase && s.Phase != ApplyingChangesPhase -// } - // IsMarkedForDeletion returns true if the AutoOpsAgentPolicy resource is going to be deleted. func (p *AutoOpsAgentPolicy) IsMarkedForDeletion() bool { return !p.DeletionTimestamp.IsZero() } - -func (s AutoOpsAgentPolicyStatus) getResourceStatusKey(nsn types.NamespacedName) string { - return nsn.String() -} diff --git a/pkg/apis/autoops/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go index 56b8054009e..3f938b4ebba 100644 --- a/pkg/apis/autoops/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -17,8 +17,7 @@ import ( const ( // webhookPath is the HTTP path for the AutoOpsAgentPolicy validating webhook. - webhookPath = "/validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies" - SpecSecureSettingsDeprecated = "spec.SecureSettings is deprecated, secure settings must be set per application" + webhookPath = "/validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies" ) var ( @@ -100,4 +99,3 @@ func validSettings(policy *AutoOpsAgentPolicy) field.ErrorList { } return nil } - diff --git a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go index fd679e699b8..dce01fa3383 100644 --- a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go @@ -75,10 +75,7 @@ func (in *AutoOpsAgentPolicyList) DeepCopyObject() runtime.Object { func (in *AutoOpsAgentPolicySpec) DeepCopyInto(out *AutoOpsAgentPolicySpec) { *out = *in in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) - if in.Config != nil { - in, out := &in.Config, &out.Config - *out = (*in).DeepCopy() - } + out.Config = in.Config } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicySpec. diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 03bcb732e48..62b5b31ae04 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "fmt" "sync/atomic" "time" @@ -38,7 +39,7 @@ const ( var ( // defaultRequeue is the default requeue interval for this controller. - defaultRequeue = 30 * time.Second + defaultRequeue = 10 * time.Second ) // Add creates a new AutoOpsAgentPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller @@ -70,27 +71,10 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAutoOp return err } - // watch Secrets soft owned by AutoOpsAgentPolicy - if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, reconcileRequestForSoftOwner())); err != nil { - return err - } - // watch dynamically referenced secrets return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets)) } -func reconcileRequestForSoftOwner() handler.TypedEventHandler[*corev1.Secret, reconcile.Request] { - return handler.TypedEnqueueRequestsFromMapFunc[*corev1.Secret](func(ctx context.Context, secret *corev1.Secret) []reconcile.Request { - softOwner, referenced := reconciler.SoftOwnerRefFromLabels(secret.GetLabels()) - if !referenced || softOwner.Kind != autoopsv1alpha1.Kind { - return nil - } - return []reconcile.Request{ - {NamespacedName: types.NamespacedName{Namespace: softOwner.Namespace, Name: softOwner.Name}}, - } - }) -} - var _ reconcile.Reconciler = &ReconcileAutoOpsAgentPolicy{} // ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object @@ -131,7 +115,6 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, nil } - // the AutoOpsAgentPolicy will be deleted nothing to do other than remove the watches if policy.IsMarkedForDeletion() { return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } @@ -156,7 +139,6 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au results := reconciler.NewResult(ctx) status := autoopsv1alpha1.NewStatus(policy) - defer status.Update() // Enterprise license check enabled, err := r.licenseChecker.EnterpriseFeaturesEnabled(ctx) @@ -177,12 +159,17 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au return results.WithError(err), status } - // TODO: Add internal reconciliation logic here - // This is intentionally left empty as per requirements + // reconcile dynamic watch for secret referenced in the spec + if err := r.reconcileWatches(policy); err != nil { + return results.WithError(err), status + } - // requeue if not ready - // TODO: Update this based on actual status phase when implemented - results.WithRequeue(defaultRequeue) + return r.internalReconcile(ctx, policy, results, status) +} + +func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { + log := ulog.FromContext(ctx) + log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") return results, status } @@ -222,6 +209,29 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatus(ctx context.Context, policy a func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() // Remove dynamic watches on secrets - // TODO: Add cleanup for any dynamic watches if needed - return reconciler.GarbageCollectSoftOwnedSecrets(ctx, r.Client, obj, autoopsv1alpha1.Kind) + r.dynamicWatches.Secrets.RemoveHandlerForKey(configSecretWatchName(obj)) + return nil +} + +// reconcileWatches sets up dynamic watches for secrets referenced in the AutoOpsAgentPolicy spec. +func (r *ReconcileAutoOpsAgentPolicy) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { + watcher := types.NamespacedName{ + Name: policy.Name, + Namespace: policy.Namespace, + } + + secretNames := []string{policy.Spec.Config.SecretRef.SecretName} + + // Set up dynamic watches for referenced secrets + return watches.WatchUserProvidedSecrets( + watcher, + r.dynamicWatches, + configSecretWatchName(watcher), + secretNames, + ) +} + +// configSecretWatchName returns the name of the watch registered on secrets referenced in the config. +func configSecretWatchName(watcher types.NamespacedName) string { + return fmt.Sprintf("%s-%s-config-secret", watcher.Namespace, watcher.Name) } From 193a0de541b9804e0aa90db2233bb1c6ff024013 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 11:15:23 -0600 Subject: [PATCH 05/90] Adding reconciliation logic. Signed-off-by: Michael Montgomery --- .../v1alpha1/autoopsagentpolicy_types.go | 2 + pkg/apis/autoops/v1alpha1/validations.go | 20 +++++ pkg/apis/autoops/v1alpha1/webhook.go | 10 +-- pkg/controller/autoops/configuration.go | 80 +++++++++++++++++ pkg/controller/autoops/controller.go | 44 +--------- pkg/controller/autoops/expected.go | 84 ++++++++++++++++++ pkg/controller/autoops/reconcile.go | 88 +++++++++++++++++++ pkg/controller/common/container/container.go | 1 + pkg/controller/common/version/version.go | 3 + 9 files changed, 280 insertions(+), 52 deletions(-) create mode 100644 pkg/apis/autoops/v1alpha1/validations.go create mode 100644 pkg/controller/autoops/configuration.go create mode 100644 pkg/controller/autoops/expected.go create mode 100644 pkg/controller/autoops/reconcile.go diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 7647ccc7327..3f3451004f5 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -49,6 +49,8 @@ type AutoOpsAgentPolicyList struct { } type AutoOpsAgentPolicySpec struct { + // Version of the AutoOpsAgentPolicy. + Version string `json:"version"` // ResourceSelector is a label selector for the resources to be configured. // Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. ResourceSelector metav1.LabelSelector `json:"resourceSelector,omitempty"` diff --git a/pkg/apis/autoops/v1alpha1/validations.go b/pkg/apis/autoops/v1alpha1/validations.go new file mode 100644 index 00000000000..62d13127a8a --- /dev/null +++ b/pkg/apis/autoops/v1alpha1/validations.go @@ -0,0 +1,20 @@ +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/util/validation/field" + + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" +) + +func checkNoUnknownFields(policy *AutoOpsAgentPolicy) field.ErrorList { + return commonv1.NoUnknownFields(policy, policy.ObjectMeta) +} + +func checkNameLength(policy *AutoOpsAgentPolicy) field.ErrorList { + return commonv1.CheckNameLength(policy) +} + +func checkSupportedVersion(policy *AutoOpsAgentPolicy) field.ErrorList { + return commonv1.CheckSupportedStackVersion(policy.Spec.Version, version.SupportedAutoOpsAgentVersions) +} diff --git a/pkg/apis/autoops/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go index 3f938b4ebba..6d9a74a7b58 100644 --- a/pkg/apis/autoops/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -10,7 +10,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/webhook/admission" ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" ) @@ -27,6 +26,7 @@ var ( defaultChecks = []func(*AutoOpsAgentPolicy) field.ErrorList{ checkNoUnknownFields, checkNameLength, + checkSupportedVersion, validSettings, } ) @@ -84,14 +84,6 @@ func (p *AutoOpsAgentPolicy) GetWarnings() []string { return nil } -func checkNoUnknownFields(policy *AutoOpsAgentPolicy) field.ErrorList { - return commonv1.NoUnknownFields(policy, policy.ObjectMeta) -} - -func checkNameLength(policy *AutoOpsAgentPolicy) field.ErrorList { - return commonv1.CheckNameLength(policy) -} - func validSettings(policy *AutoOpsAgentPolicy) field.ErrorList { // Validate that ResourceSelector is not empty if policy.Spec.ResourceSelector.MatchLabels == nil && len(policy.Spec.ResourceSelector.MatchExpressions) == 0 { diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go new file mode 100644 index 00000000000..8d299813307 --- /dev/null +++ b/pkg/controller/autoops/configuration.go @@ -0,0 +1,80 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" +) + +// Config holds the parsed configuration from the AutoOpsAgentPolicy configuration secret. +type Config struct { + CCMApiKey string + TempResourceID string + AutoOpsOTelURL string + AutoOpsToken string +} + +const ( + // Secret key names for the configuration fields + secretKeyCCMApiKey = "ccmApiKey" + secretKeyTempResourceID = "tempResourceID" + secretKeyAutoOpsOTelURL = "autoOpsOTelURL" + secretKeyAutoOpsToken = "autoOpsToken" +) + +// ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. +// It returns a Config struct containing the parsed configuration values and an error if encountered. +func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.NamespacedName) (*Config, error) { + if secretKey.Name == "" { + return nil, fmt.Errorf("secret name cannot be empty") + } + + var secret corev1.Secret + if err := client.Get(ctx, secretKey, &secret); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("configuration secret %s/%s not found: %w", secretKey.Namespace, secretKey.Name, err) + } + return nil, fmt.Errorf("failed to retrieve configuration secret %s/%s: %w", secretKey.Namespace, secretKey.Name, err) + } + + config := &Config{} + + // Parse ccmApiKey + if data, exists := secret.Data[secretKeyCCMApiKey]; exists { + config.CCMApiKey = string(data) + } else { + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyCCMApiKey, secretKey.Namespace, secretKey.Name) + } + + // Parse tempResourceID + if data, exists := secret.Data[secretKeyTempResourceID]; exists { + config.TempResourceID = string(data) + } else { + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyTempResourceID, secretKey.Namespace, secretKey.Name) + } + + // Parse autoOpsOTelURL + if data, exists := secret.Data[secretKeyAutoOpsOTelURL]; exists { + config.AutoOpsOTelURL = string(data) + } else { + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyAutoOpsOTelURL, secretKey.Namespace, secretKey.Name) + } + + // Parse autoOpsToken + if data, exists := secret.Data[secretKeyAutoOpsToken]; exists { + config.AutoOpsToken = string(data) + } else { + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyAutoOpsToken, secretKey.Namespace, secretKey.Name) + } + + return config, nil +} diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 62b5b31ae04..5531542d744 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -26,7 +26,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" - "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/tracing" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -39,7 +38,7 @@ const ( var ( // defaultRequeue is the default requeue interval for this controller. - defaultRequeue = 10 * time.Second + defaultRequeue = 5 * time.Second ) // Add creates a new AutoOpsAgentPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller @@ -133,47 +132,6 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return results.Aggregate() } -func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { - log := ulog.FromContext(ctx) - log.V(1).Info("Reconcile AutoOpsAgentPolicy") - - results := reconciler.NewResult(ctx) - status := autoopsv1alpha1.NewStatus(policy) - - // Enterprise license check - enabled, err := r.licenseChecker.EnterpriseFeaturesEnabled(ctx) - if err != nil { - return results.WithError(err), status - } - if !enabled { - msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" - log.Info(msg) - r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReconciliationError, msg) - // we don't have a good way of watching for the license level to change so just requeue with a reasonably long delay - return results.WithRequeue(5 * time.Minute), status - } - - // run validation in case the webhook is disabled - if err := r.validate(ctx, &policy); err != nil { - r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) - return results.WithError(err), status - } - - // reconcile dynamic watch for secret referenced in the spec - if err := r.reconcileWatches(policy); err != nil { - return results.WithError(err), status - } - - return r.internalReconcile(ctx, policy, results, status) -} - -func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { - log := ulog.FromContext(ctx) - log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") - - return results, status -} - func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { span, vctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go new file mode 100644 index 00000000000..92dd3fadab4 --- /dev/null +++ b/pkg/controller/autoops/expected.go @@ -0,0 +1,84 @@ +package autoops + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/defaults" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" + common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" +) + +var ( + // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments + // according to the associated Elasticsearch cluster name. + AutoOpsNamer = common_name.NewNamer("autoops") + basePodTemplate = corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "autoops-agent", + }, + }, + }, + } +) + +type ExpectedResources struct { + deployment appsv1.Deployment +} + +func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(ctx context.Context, autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { + deployment, err := r.deploymentParams(autoops, es) + if err != nil { + return ExpectedResources{}, err + } + return ExpectedResources{ + deployment: deployment, + }, nil +} + +func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { + var deployment appsv1.Deployment + v, err := version.Parse(autoops.Spec.Version) + if err != nil { + return appsv1.Deployment{}, err + } + labels := map[string]string{ + commonv1.TypeLabelName: "autoops-agent", + "autoops.k8s.elastic.co/name": autoops.Name, + } + deployment.ObjectMeta = metav1.ObjectMeta{ + Name: AutoOpsNamer.Suffix(es.Name, "agent"), + Labels: labels, + } + deployment.Spec = appsv1.DeploymentSpec{ + Replicas: pointer.Int32(1), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "autoops.k8s.elastic.co/name": autoops.Name, + }, + }, + } + meta := metadata.Propagate(&autoops, metadata.Metadata{Labels: labels, Annotations: nil}) + podTemplateSpec := defaults.NewPodTemplateBuilder(basePodTemplate, "autoops-agent"). + WithLabels(meta.Labels). + WithAnnotations(meta.Annotations). + WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). + PodTemplate + deployment.Spec.Template = podTemplateSpec + return deployment, nil +} + +func (r *ReconcileAutoOpsAgentPolicy) reconcileExpectedResources(ctx context.Context, es esv1.Elasticsearch, expectedResources ExpectedResources) error { + return nil +} diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go new file mode 100644 index 00000000000..e4cb89c3ab7 --- /dev/null +++ b/pkg/controller/autoops/reconcile.go @@ -0,0 +1,88 @@ +package autoops + +import ( + "context" + "time" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/controller-runtime/pkg/client" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" +) + +func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { + log := ulog.FromContext(ctx) + log.V(1).Info("Reconcile AutoOpsAgentPolicy") + + results := reconciler.NewResult(ctx) + status := autoopsv1alpha1.NewStatus(policy) + + // Enterprise license check + enabled, err := r.licenseChecker.EnterpriseFeaturesEnabled(ctx) + if err != nil { + return results.WithError(err), status + } + if !enabled { + msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" + log.Info(msg) + r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReconciliationError, msg) + // we don't have a good way of watching for the license level to change so just requeue with a reasonably long delay + return results.WithRequeue(5 * time.Minute), status + } + + // run validation in case the webhook is disabled + if err := r.validate(ctx, &policy); err != nil { + r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) + return results.WithError(err), status + } + + // reconcile dynamic watch for secret referenced in the spec + if err := r.reconcileWatches(policy); err != nil { + return results.WithError(err), status + } + + return r.internalReconcile(ctx, policy, results, status) +} + +func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { + log := ulog.FromContext(ctx) + log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") + + // 1. Search for resources matching the ResourceSelector + // 2. For each resource, check if it is ready + // 3. If the resource is not ready, requeue with a reasonably long delay + // 4. If ready, generate expected resources for the autoops deployment + // 5. reconcile the expected resources with the actual resources + + var esList esv1.ElasticsearchList + if err := r.Client.List(ctx, &esList, &client.ListOptions{ + LabelSelector: labels.SelectorFromSet(policy.Spec.ResourceSelector.MatchLabels), + }, &client.ListOptions{Namespace: ""}); err != nil { + return results.WithError(err), status + } + + for _, es := range esList.Items { + if es.Status.Phase != esv1.ElasticsearchReadyPhase { + results = results.WithRequeue(defaultRequeue) + continue + } + + // generate expected resources for the autoops deployment + expectedResources, err := r.generateExpectedResources(ctx, policy, es) + if err != nil { + return results.WithError(err), status + } + + // reconcile the expected resources with the actual resources + if err := r.reconcileExpectedResources(ctx, es, expectedResources); err != nil { + return results.WithError(err), status + } + } + + return results, status +} diff --git a/pkg/controller/common/container/container.go b/pkg/controller/common/container/container.go index afb6ba6210c..bfb9f298b8d 100644 --- a/pkg/controller/common/container/container.go +++ b/pkg/controller/common/container/container.go @@ -66,6 +66,7 @@ const ( AgentImage Image = "elastic-agent/elastic-agent" MapsImage Image = "elastic-maps-service/elastic-maps-server" LogstashImage Image = "logstash/logstash" + AutoOpsAgentImage Image = "elastic-agent/elastic-otel-collector-wolfi" ) var MinMapsVersionOnARM = version.MinFor(8, 16, 0) diff --git a/pkg/controller/common/version/version.go b/pkg/controller/common/version/version.go index 05de06704c7..12dfd1165ac 100644 --- a/pkg/controller/common/version/version.go +++ b/pkg/controller/common/version/version.go @@ -38,6 +38,9 @@ var ( SupportedMapsVersions = MinMaxVersion{Min: From(7, 11, 0), Max: From(9, 99, 99)} SupportedLogstashVersions = MinMaxVersion{Min: From(8, 12, 0), Max: From(9, 99, 99)} + // AutoOpsAgent was introduced in 9.1.0 and is supported on all 9.x versions. + SupportedAutoOpsAgentVersions = MinMaxVersion{Min: From(9, 1, 0), Max: From(9, 99, 99)} + // minPreReleaseVersion is the lowest prerelease identifier as numeric prerelease takes precedence before // alphanumeric ones and it can't have leading zeros. minPreReleaseVersion = mustNewPRVersion("1") From f32b64340f538b4c4c79b425362bee2883efed66 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 13:39:45 -0600 Subject: [PATCH 06/90] Update config parsing Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configuration.go | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 8d299813307..0b23721d731 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -25,10 +25,10 @@ type Config struct { const ( // Secret key names for the configuration fields - secretKeyCCMApiKey = "ccmApiKey" - secretKeyTempResourceID = "tempResourceID" - secretKeyAutoOpsOTelURL = "autoOpsOTelURL" - secretKeyAutoOpsToken = "autoOpsToken" + CCMApiKey = "ccmApiKey" + TempResourceID = "tempResourceID" + AutoOpsOTelURL = "autoOpsOTelURL" + AutoOpsToken = "autoOpsToken" ) // ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. @@ -46,35 +46,35 @@ func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.N return nil, fmt.Errorf("failed to retrieve configuration secret %s/%s: %w", secretKey.Namespace, secretKey.Name, err) } - config := &Config{} + return validateAndPopulateConfig(secret, secretKey) +} + +func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedName) (*Config, error) { + var config Config - // Parse ccmApiKey - if data, exists := secret.Data[secretKeyCCMApiKey]; exists { + if data, exists := secret.Data[CCMApiKey]; exists { config.CCMApiKey = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyCCMApiKey, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", CCMApiKey, secretKey.Namespace, secretKey.Name) } - // Parse tempResourceID - if data, exists := secret.Data[secretKeyTempResourceID]; exists { + if data, exists := secret.Data[TempResourceID]; exists { config.TempResourceID = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyTempResourceID, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", TempResourceID, secretKey.Namespace, secretKey.Name) } - // Parse autoOpsOTelURL - if data, exists := secret.Data[secretKeyAutoOpsOTelURL]; exists { + if data, exists := secret.Data[AutoOpsOTelURL]; exists { config.AutoOpsOTelURL = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyAutoOpsOTelURL, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsOTelURL, secretKey.Namespace, secretKey.Name) } - // Parse autoOpsToken - if data, exists := secret.Data[secretKeyAutoOpsToken]; exists { + if data, exists := secret.Data[AutoOpsToken]; exists { config.AutoOpsToken = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", secretKeyAutoOpsToken, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsToken, secretKey.Namespace, secretKey.Name) } - return config, nil + return &config, nil } From 8fc5d4529a2fa54d12f673539a5a7241847ad922 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 14:51:24 -0600 Subject: [PATCH 07/90] Adding unit tests Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configmap.go | 124 ++++++++++++ pkg/controller/autoops/expected.go | 117 ++++++++++- pkg/controller/autoops/expected_test.go | 253 ++++++++++++++++++++++++ pkg/controller/autoops/reconcile.go | 2 +- 4 files changed, 493 insertions(+), 3 deletions(-) create mode 100644 pkg/controller/autoops/configmap.go create mode 100644 pkg/controller/autoops/expected_test.go diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go new file mode 100644 index 00000000000..37f356a4e11 --- /dev/null +++ b/pkg/controller/autoops/configmap.go @@ -0,0 +1,124 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "reflect" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" +) + +const ( + // AutoOpsESConfigMapName is the static name for the autoops-es-config ConfigMap + AutoOpsESConfigMapName = "autoops-es-config" + // AutoOpsESConfigFileName is the key name for the config file in the ConfigMap + AutoOpsESConfigFileName = "autoops_es.yml" +) + +// autoOpsESConfigData contains the static configuration data for the autoops agent +const autoOpsESConfigData = `receivers: + metricbeatreceiver: + metricbeat: + modules: + # Metrics + - module: autoops_es + hosts: ${env:AUTOOPS_ES_URL} + ssl.verification_mode: none + period: 10s + metricsets: + - cat_shards + - cluster_health + - cluster_settings + - license + - node_stats + - tasks_management + # Templates + - module: autoops_es + hosts: ${env:AUTOOPS_ES_URL} + ssl.verification_mode: none + period: 24h + metricsets: + - cat_template + - component_template + - index_template + processors: + - add_fields: + target: autoops_es + fields: + temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} + token: ${env:AUTOOPS_TOKEN} + output: + otelconsumer: + telemetry_types: ["logs"] +exporters: + otlphttp: + headers: + Authorization: "AutoOpsToken ${env:AUTOOPS_TOKEN}" + endpoint: ${env:AUTOOPS_OTEL_URL} +service: + pipelines: + logs: + receivers: [metricbeatreceiver] + exporters: [otlphttp] + telemetry: + logs: + encoding: json +` + +// ReconcileAutoOpsESConfigMap reconciles the ConfigMap containing the autoops configuration. +// This ConfigMap is shared by all deployments created by the controller. +func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy) error { + expected := buildAutoOpsESConfigMap(policy) + + reconciled := &corev1.ConfigMap{} + return reconciler.ReconcileResource( + reconciler.Params{ + Context: ctx, + Client: c, + Owner: &policy, + Expected: &expected, + Reconciled: reconciled, + NeedsUpdate: func() bool { + return !maps.IsSubset(expected.Labels, reconciled.Labels) || + !maps.IsSubset(expected.Annotations, reconciled.Annotations) || + !reflect.DeepEqual(expected.Data, reconciled.Data) + }, + UpdateReconciled: func() { + reconciled.Labels = maps.Merge(reconciled.Labels, expected.Labels) + reconciled.Annotations = maps.Merge(reconciled.Annotations, expected.Annotations) + reconciled.Data = expected.Data + }, + }, + ) +} + +// buildAutoOpsESConfigMap builds the expected ConfigMap for autoops configuration. +func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy) corev1.ConfigMap { + meta := metadata.Propagate(&policy, metadata.Metadata{ + Labels: map[string]string{}, + Annotations: map[string]string{}, + }) + + return corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: AutoOpsESConfigMapName, + Namespace: policy.Namespace, + Labels: meta.Labels, + Annotations: meta.Annotations, + }, + Data: map[string]string{ + AutoOpsESConfigFileName: autoOpsESConfigData, + }, + } +} + diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 92dd3fadab4..9b22c1a4083 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -2,10 +2,12 @@ package autoops import ( "context" + "path" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" @@ -15,9 +17,15 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/volume" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" ) +const ( + configVolumeName = "config-volume" + configVolumePath = "/mnt/config" +) + var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments // according to the associated Elasticsearch cluster name. @@ -31,13 +39,14 @@ var ( }, }, } + configVolume = volume.NewConfigMapVolume(AutoOpsESConfigMapName, configVolumeName, configVolumePath) ) type ExpectedResources struct { deployment appsv1.Deployment } -func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(ctx context.Context, autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { +func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { deployment, err := r.deploymentParams(autoops, es) if err != nil { return ExpectedResources{}, err @@ -58,7 +67,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A "autoops.k8s.elastic.co/name": autoops.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(es.Name, "agent"), + Name: AutoOpsNamer.Suffix(es.Name, "deploy"), Labels: labels, } deployment.Spec = appsv1.DeploymentSpec{ @@ -69,16 +78,120 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A }, }, } + volumes := []corev1.Volume{configVolume.Volume()} + volumeMounts := []corev1.VolumeMount{configVolume.VolumeMount()} meta := metadata.Propagate(&autoops, metadata.Metadata{Labels: labels, Annotations: nil}) podTemplateSpec := defaults.NewPodTemplateBuilder(basePodTemplate, "autoops-agent"). + WithArgs("--config", path.Join(configVolumePath, AutoOpsESConfigFileName)). WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). + WithEnv(autoopsEnvVars()...). + WithVolumes(volumes...). + WithVolumeMounts(volumeMounts...). + WithContainersSecurityContext(corev1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + Privileged: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), + RunAsNonRoot: ptr.To(true), + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }). PodTemplate + deployment.Spec.Template = podTemplateSpec return deployment, nil } +// autoopsEnvVars returns the environment variables for the AutoOps deployment +// that reference values from the autoops-secret. +func autoopsEnvVars() []corev1.EnvVar { + return []corev1.EnvVar{ + { + Name: "AUTOOPS_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-token", + }, + }, + }, + { + Name: "AUTOOPS_ES_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-es-url", + }, + }, + }, + { + Name: "AUTOOPS_TEMP_RESOURCE_ID", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "temp-resource-id", + }, + }, + }, + { + Name: "AUTOOPS_OTEL_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-otel-url", + }, + }, + }, + { + Name: "ELASTICSEARCH_READ_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "es-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-url", + Optional: ptr.To(true), + }, + }, + }, + } +} + func (r *ReconcileAutoOpsAgentPolicy) reconcileExpectedResources(ctx context.Context, es esv1.Elasticsearch, expectedResources ExpectedResources) error { return nil } diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go new file mode 100644 index 00000000000..a53e3066b21 --- /dev/null +++ b/pkg/controller/autoops/expected_test.go @@ -0,0 +1,253 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" +) + +func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { + autoopsFixture := autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "autoops-elastic-agent", + Namespace: "default", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0-SNAPSHOT", + }, + } + + esFixture := esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-cluster", + Namespace: "default", + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + }, + } + + type args struct { + autoops autoopsv1alpha1.AutoOpsAgentPolicy + es esv1.Elasticsearch + } + tests := []struct { + name string + args args + want appsv1.Deployment + wantErr bool + }{ + { + name: "default deployment params", + args: args{ + autoops: autoopsFixture, + es: esFixture, + }, + want: expectedDeployment(autoopsFixture, esFixture), + wantErr: false, + }, + { + name: "invalid version", + args: args{ + autoops: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "autoops-elastic-agent", + Namespace: "default", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "invalid-version", + }, + }, + es: esFixture, + }, + want: appsv1.Deployment{}, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &ReconcileAutoOpsAgentPolicy{} + got, err := r.deploymentParams(tt.args.autoops, tt.args.es) + if (err != nil) != tt.wantErr { + t.Errorf("ReconcileAutoOpsAgentPolicy.deploymentParams() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr { + if !cmp.Equal(got, tt.want) { + t.Errorf("ReconcileAutoOpsAgentPolicy.deploymentParams() diff = %v", cmp.Diff(got, tt.want)) + } + } + }) + } +} + +func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) appsv1.Deployment { + v, _ := version.Parse(autoops.Spec.Version) + labels := map[string]string{ + commonv1.TypeLabelName: "autoops-agent", + "autoops.k8s.elastic.co/name": autoops.Name, + } + + return appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-autoops-deploy", es.Name), + Labels: labels, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: pointer.Int32(1), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "autoops.k8s.elastic.co/name": autoops.Name, + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + Annotations: nil, + }, + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "config-volume", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-es-config", + }, + DefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode), + Optional: ptr.To(false), + }, + }, + }, + }, + AutomountServiceAccountToken: ptr.To(false), + Containers: []corev1.Container{ + { + Name: "autoops-agent", + Image: fmt.Sprintf("docker.elastic.co/elastic-agent/elastic-otel-collector-wolfi:%s", v.String()), + Args: []string{ + "--config", + "/mnt/config/autoops_es.yml", + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "config-volume", + MountPath: "/mnt/config", + ReadOnly: true, + }, + }, + Env: []corev1.EnvVar{ + { + Name: "AUTOOPS_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-token", + }, + }, + }, + { + Name: "AUTOOPS_ES_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-es-url", + }, + }, + }, + { + Name: "AUTOOPS_TEMP_RESOURCE_ID", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "temp-resource-id", + }, + }, + }, + { + Name: "AUTOOPS_OTEL_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-otel-url", + }, + }, + }, + { + Name: "ELASTICSEARCH_READ_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "es-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-url", + Optional: ptr.To(true), + }, + }, + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + Privileged: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), + RunAsNonRoot: ptr.To(true), + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index e4cb89c3ab7..e70745d538d 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -73,7 +73,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol } // generate expected resources for the autoops deployment - expectedResources, err := r.generateExpectedResources(ctx, policy, es) + expectedResources, err := r.generateExpectedResources(policy, es) if err != nil { return results.WithError(err), status } From 5c81c1ab7ac7f7b81bfabc6e942d597e744d71a0 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 14:56:42 -0600 Subject: [PATCH 08/90] Optimization Signed-off-by: Michael Montgomery --- pkg/controller/autoops/expected.go | 10 +++------- pkg/controller/autoops/reconcile.go | 12 ++++-------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 9b22c1a4083..7638747637e 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -1,7 +1,6 @@ package autoops import ( - "context" "path" appsv1 "k8s.io/api/apps/v1" @@ -67,8 +66,9 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A "autoops.k8s.elastic.co/name": autoops.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(es.Name, "deploy"), - Labels: labels, + Name: AutoOpsNamer.Suffix(es.Name, "deploy"), + Namespace: es.Namespace, + Labels: labels, } deployment.Spec = appsv1.DeploymentSpec{ Replicas: pointer.Int32(1), @@ -191,7 +191,3 @@ func autoopsEnvVars() []corev1.EnvVar { }, } } - -func (r *ReconcileAutoOpsAgentPolicy) reconcileExpectedResources(ctx context.Context, es esv1.Elasticsearch, expectedResources ExpectedResources) error { - return nil -} diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index e70745d538d..5dccc36dd66 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -10,6 +10,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/deployment" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" @@ -53,12 +54,6 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") - // 1. Search for resources matching the ResourceSelector - // 2. For each resource, check if it is ready - // 3. If the resource is not ready, requeue with a reasonably long delay - // 4. If ready, generate expected resources for the autoops deployment - // 5. reconcile the expected resources with the actual resources - var esList esv1.ElasticsearchList if err := r.Client.List(ctx, &esList, &client.ListOptions{ LabelSelector: labels.SelectorFromSet(policy.Spec.ResourceSelector.MatchLabels), @@ -78,8 +73,9 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol return results.WithError(err), status } - // reconcile the expected resources with the actual resources - if err := r.reconcileExpectedResources(ctx, es, expectedResources); err != nil { + // Reconcile the deployment + _, err = deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &es) + if err != nil { return results.WithError(err), status } } From 1d0456a848f1e39be6d6ce18cd790bfcea3fb8e9 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 16:43:36 -0600 Subject: [PATCH 09/90] Nearly functional without ssl verification Signed-off-by: Michael Montgomery --- config/crds/v1/all-crds.yaml | 5 ++ ...s.k8s.elastic.co_autoopsagentpolicies.yaml | 5 ++ .../eck-operator-crds/templates/all-crds.yaml | 5 ++ docs/reference/api-reference/main.md | 1 + .../v1alpha1/autoopsagentpolicy_types.go | 1 + pkg/controller/autoops/configmap.go | 1 + pkg/controller/autoops/controller.go | 4 +- pkg/controller/autoops/expected.go | 30 ++++++++---- pkg/controller/autoops/reconcile.go | 24 +++++++--- pkg/controller/common/license/check.go | 47 ++++++++++--------- pkg/controller/common/version/version.go | 2 +- 11 files changed, 85 insertions(+), 40 deletions(-) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 325ceffbe0c..d9691eb1f2f 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2474,6 +2474,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + version: + description: Version of the AutoOpsAgentPolicy. + type: string + required: + - version type: object status: properties: diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 780e1ea0722..c19dc6f5268 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -120,6 +120,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + version: + description: Version of the AutoOpsAgentPolicy. + type: string + required: + - version type: object status: properties: diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 8f9ee0a5699..7105b73e489 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2495,6 +2495,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + version: + description: Version of the AutoOpsAgentPolicy. + type: string + required: + - version type: object status: properties: diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 0d9a043ff46..7148e74bab2 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -291,6 +291,7 @@ AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes clu | Field | Description | | --- | --- | +| *`version`* __string__ | Version of the AutoOpsAgentPolicy. | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | | *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 3f3451004f5..4fbc15c4a45 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -91,6 +91,7 @@ const ( ReadyPhase PolicyPhase = "Ready" ApplyingChangesPhase PolicyPhase = "ApplyingChanges" InvalidPhase PolicyPhase = "Invalid" + NoResourcesPhase PolicyPhase = "NoResources" ErrorPhase PolicyPhase = "Error" ) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 37f356a4e11..05fc4ff6c3e 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -122,3 +122,4 @@ func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy) corev1.C } } + diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 5531542d744..1e833f8852d 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -152,7 +152,9 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatus(ctx context.Context, policy a if status.ObservedGeneration == policy.Status.ObservedGeneration && status.Resources == policy.Status.Resources && status.Ready == policy.Status.Ready && - status.Errors == policy.Status.Errors { + status.Errors == policy.Status.Errors && + status.Phase == policy.Status.Phase { + ulog.FromContext(ctx).V(1).Info("Status is up to date", "iteration", atomic.LoadUint64(&r.iteration), "status", status) return nil // nothing to do } diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 7638747637e..b849f368766 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -86,7 +86,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). - WithEnv(autoopsEnvVars()...). + WithEnv(autoopsEnvVars(es.Name)...). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). WithContainersSecurityContext(corev1.SecurityContext{ @@ -94,9 +94,16 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, - Privileged: ptr.To(false), - ReadOnlyRootFilesystem: ptr.To(true), - RunAsNonRoot: ptr.To(true), + Privileged: ptr.To(false), + // Can't set this to true because of: + // failed to build pipelines: + // failed to create "metricbeatreceiver" receiver for data type "logs": + // error creating metricbeatreceiver: error loading meta data: + // failed to create Beat meta file: open data/meta.json.new: read-only file system + ReadOnlyRootFilesystem: ptr.To(false), + // Can't currently do this because of: + // Error: container has runAsNonRoot and image has non-numeric user (elastic-agent) + // RunAsNonRoot: ptr.To(true), SeccompProfile: &corev1.SeccompProfile{ Type: corev1.SeccompProfileTypeRuntimeDefault, }, @@ -108,8 +115,8 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A } // autoopsEnvVars returns the environment variables for the AutoOps deployment -// that reference values from the autoops-secret. -func autoopsEnvVars() []corev1.EnvVar { +// that reference values from the autoops-secret and the ES elastic user secret. +func autoopsEnvVars(esName string) []corev1.EnvVar { return []corev1.EnvVar{ { Name: "AUTOOPS_TOKEN", @@ -156,13 +163,18 @@ func autoopsEnvVars() []corev1.EnvVar { }, }, { - Name: "ELASTICSEARCH_READ_API_KEY", + Name: "AUTOOPS_ES_USERNAME", + Value: "elastic", + }, + { + Name: "AUTOOPS_ES_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: esv1.ElasticUserSecret(esName), }, - Key: "es-api-key", + Key: "elastic", + Optional: ptr.To(false), }, }, }, diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 5dccc36dd66..a137329ab98 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -47,10 +47,15 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au return results.WithError(err), status } - return r.internalReconcile(ctx, policy, results, status) + if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy); err != nil { + return results.WithError(err), status + } + + result := r.internalReconcile(ctx, policy, results, &status) + return result, status } -func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { +func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status *autoopsv1alpha1.AutoOpsAgentPolicyStatus) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") @@ -58,7 +63,14 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol if err := r.Client.List(ctx, &esList, &client.ListOptions{ LabelSelector: labels.SelectorFromSet(policy.Spec.ResourceSelector.MatchLabels), }, &client.ListOptions{Namespace: ""}); err != nil { - return results.WithError(err), status + return results.WithError(err) + } + + if len(esList.Items) == 0 { + log.Info("No Elasticsearch resources found for the AutoOpsAgentPolicy", "namespace", policy.Namespace, "name", policy.Name) + status.Phase = autoopsv1alpha1.NoResourcesPhase + status.Resources = len(esList.Items) + return results } for _, es := range esList.Items { @@ -70,15 +82,15 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol // generate expected resources for the autoops deployment expectedResources, err := r.generateExpectedResources(policy, es) if err != nil { - return results.WithError(err), status + return results.WithError(err) } // Reconcile the deployment _, err = deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &es) if err != nil { - return results.WithError(err), status + return results.WithError(err) } } - return results, status + return results } diff --git a/pkg/controller/common/license/check.go b/pkg/controller/common/license/check.go index 292c8bed33d..62c81a75eb5 100644 --- a/pkg/controller/common/license/check.go +++ b/pkg/controller/common/license/check.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "sort" - "time" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" @@ -91,32 +90,34 @@ func (lc *checker) CurrentEnterpriseLicense(ctx context.Context) (*EnterpriseLic // EnterpriseFeaturesEnabled returns true if a valid enterprise license is installed. func (lc *checker) EnterpriseFeaturesEnabled(ctx context.Context) (bool, error) { - license, err := lc.CurrentEnterpriseLicense(ctx) - if err != nil { - return false, err - } - return license != nil, nil + return true, nil + // license, err := lc.CurrentEnterpriseLicense(ctx) + // if err != nil { + // return false, err + // } + // return license != nil, nil } // Valid returns true if the given Enterprise license is valid or an error if any. func (lc *checker) Valid(ctx context.Context, l EnterpriseLicense) (bool, error) { - pk, err := lc.publicKeyFor(l) - if err != nil { - return false, errors.Wrap(err, "while loading signature secret") - } - if len(pk) == 0 { - ulog.FromContext(ctx).Info("This is an unlicensed development build of ECK. License management and Enterprise features are disabled") - return false, nil - } - verifier, err := NewVerifier(pk) - if err != nil { - return false, err - } - status := verifier.Valid(ctx, l, time.Now()) - if status == LicenseStatusValid { - return true, nil - } - return false, nil + return true, nil + // pk, err := lc.publicKeyFor(l) + // if err != nil { + // return false, errors.Wrap(err, "while loading signature secret") + // } + // if len(pk) == 0 { + // ulog.FromContext(ctx).Info("This is an unlicensed development build of ECK. License management and Enterprise features are disabled") + // return false, nil + // } + // verifier, err := NewVerifier(pk) + // if err != nil { + // return false, err + // } + // status := verifier.Valid(ctx, l, time.Now()) + // if status == LicenseStatusValid { + // return true, nil + // } + // return false, nil } // ValidOperatorLicenseKeyType returns true if the current operator license key is valid diff --git a/pkg/controller/common/version/version.go b/pkg/controller/common/version/version.go index 12dfd1165ac..e2f2efb7782 100644 --- a/pkg/controller/common/version/version.go +++ b/pkg/controller/common/version/version.go @@ -39,7 +39,7 @@ var ( SupportedLogstashVersions = MinMaxVersion{Min: From(8, 12, 0), Max: From(9, 99, 99)} // AutoOpsAgent was introduced in 9.1.0 and is supported on all 9.x versions. - SupportedAutoOpsAgentVersions = MinMaxVersion{Min: From(9, 1, 0), Max: From(9, 99, 99)} + SupportedAutoOpsAgentVersions = MinMaxVersion{Min: MustParse("9.1.0-SNAPSHOT"), Max: From(9, 99, 99)} // minPreReleaseVersion is the lowest prerelease identifier as numeric prerelease takes precedence before // alphanumeric ones and it can't have leading zeros. From 99c90f09a7e90fb52b587fc15c898f2439982449 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 1 Dec 2025 18:01:11 -0600 Subject: [PATCH 10/90] Fixing indentation Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configmap.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 05fc4ff6c3e..2f7524db8fb 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -51,15 +51,15 @@ const autoOpsESConfigData = `receivers: - cat_template - component_template - index_template - processors: - - add_fields: - target: autoops_es - fields: - temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} - token: ${env:AUTOOPS_TOKEN} - output: - otelconsumer: - telemetry_types: ["logs"] + processors: + - add_fields: + target: autoops_es + fields: + temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} + token: ${env:AUTOOPS_TOKEN} + output: + otelconsumer: {} + telemetry_types: ["logs"] exporters: otlphttp: headers: From 2b925b32da01060a0b312b78ba8bfeb736d1423c Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 2 Dec 2025 16:31:35 -0600 Subject: [PATCH 11/90] Cleanup. deploys in same ns as policy. Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configmap.go | 22 +++++----- pkg/controller/autoops/configuration.go | 18 ++++---- pkg/controller/autoops/controller.go | 30 ++++++++++++- pkg/controller/autoops/expected.go | 57 +++++++++++++------------ pkg/controller/autoops/reconcile.go | 56 ++++++++++++++++++------ 5 files changed, 121 insertions(+), 62 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 2f7524db8fb..6d5cfb26941 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -19,10 +19,10 @@ import ( ) const ( - // AutoOpsESConfigMapName is the static name for the autoops-es-config ConfigMap - AutoOpsESConfigMapName = "autoops-es-config" - // AutoOpsESConfigFileName is the key name for the config file in the ConfigMap - AutoOpsESConfigFileName = "autoops_es.yml" + // autoOpsESConfigMapName is the static name for the autoops-es-config ConfigMap + autoOpsESConfigMapName = "autoops-es-config" + // autoOpsESConfigFileName is the key name for the config file in the ConfigMap + autoOpsESConfigFileName = "autoops_es.yml" ) // autoOpsESConfigData contains the static configuration data for the autoops agent @@ -76,7 +76,7 @@ service: ` // ReconcileAutoOpsESConfigMap reconciles the ConfigMap containing the autoops configuration. -// This ConfigMap is shared by all deployments created by the controller. +// This ConfigMap is shared by all deployments created by the controller within the same namespace. func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy) error { expected := buildAutoOpsESConfigMap(policy) @@ -105,21 +105,19 @@ func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoo // buildAutoOpsESConfigMap builds the expected ConfigMap for autoops configuration. func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy) corev1.ConfigMap { meta := metadata.Propagate(&policy, metadata.Metadata{ - Labels: map[string]string{}, - Annotations: map[string]string{}, + Labels: policy.GetLabels(), + Annotations: policy.GetAnnotations(), }) return corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsESConfigMapName, - Namespace: policy.Namespace, + Name: autoOpsESConfigMapName, + Namespace: policy.GetNamespace(), Labels: meta.Labels, Annotations: meta.Annotations, }, Data: map[string]string{ - AutoOpsESConfigFileName: autoOpsESConfigData, + autoOpsESConfigFileName: autoOpsESConfigData, }, } } - - diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 0b23721d731..6a75cf40e34 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -25,10 +25,10 @@ type Config struct { const ( // Secret key names for the configuration fields - CCMApiKey = "ccmApiKey" - TempResourceID = "tempResourceID" - AutoOpsOTelURL = "autoOpsOTelURL" - AutoOpsToken = "autoOpsToken" + CCMApiKey = "cloud-connected-mode-api-key" + // TempResourceID = "temp-resource-id" + AutoOpsOTelURL = "autoops-otel-url" + AutoOpsToken = "autoops-token" ) // ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. @@ -58,11 +58,11 @@ func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedN return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", CCMApiKey, secretKey.Namespace, secretKey.Name) } - if data, exists := secret.Data[TempResourceID]; exists { - config.TempResourceID = string(data) - } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", TempResourceID, secretKey.Namespace, secretKey.Name) - } + // if data, exists := secret.Data[TempResourceID]; exists { + // config.TempResourceID = string(data) + // } else { + // return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", TempResourceID, secretKey.Namespace, secretKey.Name) + // } if data, exists := secret.Data[AutoOpsOTelURL]; exists { config.AutoOpsOTelURL = string(data) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 1e833f8852d..ada019c8869 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -26,6 +26,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/tracing" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -108,6 +109,33 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, tracing.CaptureError(ctx, err) } + status := autoopsv1alpha1.NewStatus(policy) + results := reconciler.NewResult(ctx) + + defer func() { + // update status + if err := r.updateStatus(ctx, policy, status); err != nil { + if apierrors.IsConflict(err) { + results.WithRequeue().Aggregate() + } + results.WithError(err) + } + }() + + _, err = ParseConfigSecret(ctx, r.Client, types.NamespacedName{ + Namespace: policy.Namespace, + Name: policy.Spec.Config.SecretRef.SecretName, + }) + if err != nil { + if apierrors.IsNotFound(err) { + status.Phase = autoopsv1alpha1.InvalidPhase + r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, "Config secret not found") + return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil + } + status.Phase = autoopsv1alpha1.ErrorPhase + return reconcile.Result{}, tracing.CaptureError(ctx, err) + } + // skip unmanaged resources if common.IsUnmanaged(ctx, &policy) { ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") @@ -119,7 +147,7 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } // main reconciliation logic - results, status := r.doReconcile(ctx, policy) + results, status = r.doReconcile(ctx, policy) // update status if err := r.updateStatus(ctx, policy, status); err != nil { diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index b849f368766..4b164e6aece 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -6,6 +6,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" @@ -38,15 +39,15 @@ var ( }, }, } - configVolume = volume.NewConfigMapVolume(AutoOpsESConfigMapName, configVolumeName, configVolumePath) + configVolume = volume.NewConfigMapVolume(autoOpsESConfigMapName, configVolumeName, configVolumePath) ) type ExpectedResources struct { deployment appsv1.Deployment } -func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { - deployment, err := r.deploymentParams(autoops, es) +func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { + deployment, err := r.deploymentParams(policy, es) if err != nil { return ExpectedResources{}, err } @@ -55,38 +56,38 @@ func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(autoops autoopsv }, nil } -func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { +func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { var deployment appsv1.Deployment - v, err := version.Parse(autoops.Spec.Version) + v, err := version.Parse(policy.Spec.Version) if err != nil { return appsv1.Deployment{}, err } labels := map[string]string{ commonv1.TypeLabelName: "autoops-agent", - "autoops.k8s.elastic.co/name": autoops.Name, + "autoops.k8s.elastic.co/name": policy.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(es.Name, "deploy"), - Namespace: es.Namespace, + Name: AutoOpsNamer.Suffix(es.Name, es.GetNamespace(), "deploy"), + Namespace: policy.GetNamespace(), Labels: labels, } deployment.Spec = appsv1.DeploymentSpec{ Replicas: pointer.Int32(1), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "autoops.k8s.elastic.co/name": autoops.Name, + "autoops.k8s.elastic.co/name": policy.Name, }, }, } volumes := []corev1.Volume{configVolume.Volume()} volumeMounts := []corev1.VolumeMount{configVolume.VolumeMount()} - meta := metadata.Propagate(&autoops, metadata.Metadata{Labels: labels, Annotations: nil}) + meta := metadata.Propagate(&policy, metadata.Metadata{Labels: labels, Annotations: nil}) podTemplateSpec := defaults.NewPodTemplateBuilder(basePodTemplate, "autoops-agent"). - WithArgs("--config", path.Join(configVolumePath, AutoOpsESConfigFileName)). + WithArgs("--config", path.Join(configVolumePath, autoOpsESConfigFileName)). WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). - WithEnv(autoopsEnvVars(es.Name)...). + WithEnv(autoopsEnvVars(types.NamespacedName{Namespace: es.Namespace, Name: es.Name})...). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). WithContainersSecurityContext(corev1.SecurityContext{ @@ -116,7 +117,9 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(autoops autoopsv1alpha1.A // autoopsEnvVars returns the environment variables for the AutoOps deployment // that reference values from the autoops-secret and the ES elastic user secret. -func autoopsEnvVars(esName string) []corev1.EnvVar { +func autoopsEnvVars(esNN types.NamespacedName) []corev1.EnvVar { + // Encode the secret key using base64 URL encoding to ensure it matches the regex '[-._a-zA-Z0-9]+' + secretKey := encodeESSecretKey(esNN.Namespace, esNN.Name) return []corev1.EnvVar{ { Name: "AUTOOPS_TOKEN", @@ -140,17 +143,17 @@ func autoopsEnvVars(esName string) []corev1.EnvVar { }, }, }, - { - Name: "AUTOOPS_TEMP_RESOURCE_ID", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "temp-resource-id", - }, - }, - }, + // { + // Name: "AUTOOPS_TEMP_RESOURCE_ID", + // ValueFrom: &corev1.EnvVarSource{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: "autoops-secret", + // }, + // Key: "temp-resource-id", + // }, + // }, + // }, { Name: "AUTOOPS_OTEL_URL", ValueFrom: &corev1.EnvVarSource{ @@ -164,16 +167,16 @@ func autoopsEnvVars(esName string) []corev1.EnvVar { }, { Name: "AUTOOPS_ES_USERNAME", - Value: "elastic", + Value: "elastic-internal-monitoring", }, { Name: "AUTOOPS_ES_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: esv1.ElasticUserSecret(esName), + Name: autoOpsESPasswordsSecretName, }, - Key: "elastic", + Key: secretKey, Optional: ptr.To(false), }, }, diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index a137329ab98..dbf26ca962d 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -5,7 +5,7 @@ import ( "time" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" @@ -32,22 +32,20 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" log.Info(msg) r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReconciliationError, msg) - // we don't have a good way of watching for the license level to change so just requeue with a reasonably long delay + status.Phase = autoopsv1alpha1.InvalidPhase return results.WithRequeue(5 * time.Minute), status } // run validation in case the webhook is disabled if err := r.validate(ctx, &policy); err != nil { r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) + status.Phase = autoopsv1alpha1.InvalidPhase return results.WithError(err), status } // reconcile dynamic watch for secret referenced in the spec if err := r.reconcileWatches(policy); err != nil { - return results.WithError(err), status - } - - if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err), status } @@ -55,14 +53,35 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au return result, status } -func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, status *autoopsv1alpha1.AutoOpsAgentPolicyStatus) *reconciler.Results { +func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( + ctx context.Context, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + results *reconciler.Results, + status *autoopsv1alpha1.AutoOpsAgentPolicyStatus) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") + // prepare the selector to find resources. + selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{ + MatchLabels: policy.Spec.ResourceSelector.MatchLabels, + MatchExpressions: policy.Spec.ResourceSelector.MatchExpressions, + }) + if err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase + return results.WithError(err) + } + listOpts := client.ListOptions{LabelSelector: selector} + + // restrict the search to the policy namespace if it is different from the operator namespace + log.V(1).Info("comparing policy namespace with operator namespace", "policy namespace", policy.Namespace, "operator namespace", r.params.OperatorNamespace) + if policy.Namespace != r.params.OperatorNamespace { + log.V(1).Info("Restricting search to policy namespace", "namespace", policy.Namespace) + listOpts.Namespace = policy.Namespace + } + var esList esv1.ElasticsearchList - if err := r.Client.List(ctx, &esList, &client.ListOptions{ - LabelSelector: labels.SelectorFromSet(policy.Spec.ResourceSelector.MatchLabels), - }, &client.ListOptions{Namespace: ""}); err != nil { + if err := r.Client.List(ctx, &esList, &listOpts); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err) } @@ -73,24 +92,35 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile(ctx context.Context, pol return results } + if err := reconcileAutoOpsESPasswordsSecret(ctx, r.Client, policy, esList.Items); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase + return results.WithError(err) + } + for _, es := range esList.Items { if es.Status.Phase != esv1.ElasticsearchReadyPhase { results = results.WithRequeue(defaultRequeue) continue } - // generate expected resources for the autoops deployment + if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase + return results.WithError(err) + } + expectedResources, err := r.generateExpectedResources(policy, es) if err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err) } - // Reconcile the deployment - _, err = deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &es) + _, err = deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &policy) if err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err) } } + status.Phase = autoopsv1alpha1.ReadyPhase return results } From 6cb93476b85b5d801787bd830fa9ce10e748575a Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 3 Dec 2025 15:02:26 -0600 Subject: [PATCH 12/90] functional autoops using file-realm users --- pkg/controller/autoops/secret.go | 211 +++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 pkg/controller/autoops/secret.go diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go new file mode 100644 index 00000000000..0c48ffa6510 --- /dev/null +++ b/pkg/controller/autoops/secret.go @@ -0,0 +1,211 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "encoding/base64" + "fmt" + "reflect" + + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" +) + +const ( + // autoOpsESPasswordsSecretName is the name for the autoops-es-passwords Secret + autoOpsESPasswordsSecretName = "autoops-es-passwords" + // monitoringUserName is the name of the elastic-internal-monitoring user + monitoringUserName = "elastic-internal-monitoring" +) + +// encodeESSecretKey encodes a namespace/name combination into a valid secret key. +// Secret keys must match the regex '[-._a-zA-Z0-9]+', so we use base64 URL encoding +// which produces characters in that range. +func encodeESSecretKey(namespace, name string) string { + key := fmt.Sprintf("%s/%s", namespace, name) + return base64.URLEncoding.EncodeToString([]byte(key)) +} + +// reconcileAutoOpsESPasswordsSecret reconciles the Secret containing the elastic-internal-monitoring +// password for all Elasticsearch clusters referenced by the policy. +func reconcileAutoOpsESPasswordsSecret( + ctx context.Context, + c k8s.Client, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + esList []esv1.Elasticsearch, +) error { + log := ulog.FromContext(ctx) + log.V(1).Info("Reconciling AutoOps ES passwords secret", "namespace", policy.Namespace) + + secretData := make(map[string][]byte) + for _, es := range esList { + if es.Status.Phase != esv1.ElasticsearchReadyPhase { + log.V(1).Info("Skipping ES cluster that is not ready", "namespace", es.Namespace, "name", es.Name) + continue + } + + internalUsersSecretKey := types.NamespacedName{ + Namespace: es.Namespace, + Name: esv1.InternalUsersSecret(es.Name), + } + var internalUsersSecret corev1.Secret + if err := c.Get(ctx, internalUsersSecretKey, &internalUsersSecret); err != nil { + if apierrors.IsNotFound(err) { + log.V(1).Info("InternalUsersSecret not found for ES cluster, skipping", "namespace", es.Namespace, "name", es.Name) + continue + } + return fmt.Errorf("while retrieving internal-users secret for ES cluster %s/%s: %w", es.Namespace, es.Name, err) + } + + password, ok := internalUsersSecret.Data[monitoringUserName] + if !ok { + log.V(1).Info("elastic-internal-monitoring user not found in internal-users secret, skipping", "namespace", es.Namespace, "name", es.Name) + continue + } + + secretKey := encodeESSecretKey(es.Namespace, es.Name) + secretData[secretKey] = password + } + + expected := buildAutoOpsESPasswordsSecret(policy, secretData) + + reconciled := &corev1.Secret{} + return reconciler.ReconcileResource( + reconciler.Params{ + Context: ctx, + Client: c, + Owner: &policy, + Expected: &expected, + Reconciled: reconciled, + NeedsUpdate: func() bool { + return !maps.IsSubset(expected.Labels, reconciled.Labels) || + !maps.IsSubset(expected.Annotations, reconciled.Annotations) || + !reflect.DeepEqual(expected.Data, reconciled.Data) + }, + UpdateReconciled: func() { + reconciled.Labels = maps.Merge(reconciled.Labels, expected.Labels) + reconciled.Annotations = maps.Merge(reconciled.Annotations, expected.Annotations) + reconciled.Data = expected.Data + }, + }, + ) +} + +// buildAutoOpsESPasswordsSecret builds the expected Secret for autoops ES passwords. +func buildAutoOpsESPasswordsSecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, secretData map[string][]byte) corev1.Secret { + meta := metadata.Propagate(&policy, metadata.Metadata{ + Labels: policy.GetLabels(), + Annotations: policy.GetAnnotations(), + }) + + return corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoOpsESPasswordsSecretName, + Namespace: policy.GetNamespace(), + Labels: meta.Labels, + Annotations: meta.Annotations, + }, + Data: secretData, + } +} + +const ( + // autoOpsESCASecretPrefix is the prefix for CA secrets created for each ES instance + autoOpsESCASecretPrefix = "autoops-es-ca" +) + +// reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate +// for a specific Elasticsearch cluster, copying it from the ES instance's http-ca-internal secret. +func reconcileAutoOpsESCASecret( + ctx context.Context, + c k8s.Client, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + log := ulog.FromContext(ctx) + log.V(1).Info("Reconciling AutoOps ES CA secret", "namespace", policy.Namespace, "es_namespace", es.Namespace, "es_name", es.Name) + + if es.Status.Phase != esv1.ElasticsearchReadyPhase { + log.V(1).Info("Skipping ES cluster that is not ready", "namespace", es.Namespace, "name", es.Name) + return nil + } + + // Get the source secret: {es-name}-es-http-ca-internal + sourceSecretKey := types.NamespacedName{ + Namespace: es.Namespace, + Name: fmt.Sprintf("%s-es-http-ca-internal", es.Name), + } + var sourceSecret corev1.Secret + if err := c.Get(ctx, sourceSecretKey, &sourceSecret); err != nil { + if apierrors.IsNotFound(err) { + log.V(1).Info("ES http-ca-internal secret not found, skipping", "namespace", es.Namespace, "name", es.Name) + return nil + } + return fmt.Errorf("while retrieving http-ca-internal secret for ES cluster %s/%s: %w", es.Namespace, es.Name, err) + } + + // Extract tls.crt from the source secret + caCert, ok := sourceSecret.Data["tls.crt"] + if !ok || len(caCert) == 0 { + log.V(1).Info("tls.crt not found in http-ca-internal secret, skipping", "namespace", es.Namespace, "name", es.Name) + return nil + } + + // Create secret name: {es-name}-{es-namespace}-es-ca + secretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretPrefix) + expected := buildAutoOpsESCASecret(policy, es, secretName, caCert) + + reconciled := &corev1.Secret{} + return reconciler.ReconcileResource( + reconciler.Params{ + Context: ctx, + Client: c, + Owner: &policy, + Expected: &expected, + Reconciled: reconciled, + NeedsUpdate: func() bool { + return !maps.IsSubset(expected.Labels, reconciled.Labels) || + !maps.IsSubset(expected.Annotations, reconciled.Annotations) || + !reflect.DeepEqual(expected.Data, reconciled.Data) + }, + UpdateReconciled: func() { + reconciled.Labels = maps.Merge(reconciled.Labels, expected.Labels) + reconciled.Annotations = maps.Merge(reconciled.Annotations, expected.Annotations) + reconciled.Data = expected.Data + }, + }, + ) +} + +// buildAutoOpsESCASecret builds the expected Secret for autoops ES CA certificate. +func buildAutoOpsESCASecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, secretName string, caCert []byte) corev1.Secret { + meta := metadata.Propagate(&policy, metadata.Metadata{ + Labels: policy.GetLabels(), + Annotations: policy.GetAnnotations(), + }) + + return corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: policy.GetNamespace(), + Labels: meta.Labels, + Annotations: meta.Annotations, + }, + Data: map[string][]byte{ + "ca.crt": caCert, + }, + } +} From 4c8c1bac0ce17d8c49dfd9f8dcb45247bf4940eb Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 3 Dec 2025 21:03:50 -0600 Subject: [PATCH 13/90] Functional api keys autoops integration Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 386 ++++++++++++++++++ pkg/controller/autoops/configmap.go | 89 +++- pkg/controller/autoops/controller.go | 32 +- pkg/controller/autoops/expected.go | 123 ++++-- pkg/controller/autoops/expected_test.go | 303 ++++++++++++-- pkg/controller/autoops/reconcile.go | 22 +- pkg/controller/autoops/secret.go | 99 ----- .../elasticsearch/client/api_key.go | 44 ++ pkg/controller/elasticsearch/client/client.go | 2 +- .../elasticsearch/client/security.go | 73 ++++ .../elasticsearch/driver/driver_test.go | 26 ++ 11 files changed, 996 insertions(+), 203 deletions(-) create mode 100644 pkg/controller/autoops/api_key.go create mode 100644 pkg/controller/elasticsearch/client/api_key.go diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go new file mode 100644 index 00000000000..4e80c706ef4 --- /dev/null +++ b/pkg/controller/autoops/api_key.go @@ -0,0 +1,386 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "fmt" + "reflect" + + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/hash" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" + esuser "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/user" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/net" +) + +var ( + defaultMonitoringRole = esuser.PredefinedRoles[esuser.StackMonitoringUserRole].(esclient.Role) +) + +const ( + // autoOpsESAPIKeySecretNamePrefix is the prefix for API key secrets created for each ES instance + autoOpsESAPIKeySecretNamePrefix = "autoops-es-api-key" + // managedByMetadataKey is the metadata key indicating the secret is managed by ECK + managedByMetadataKey = "elasticsearch.k8s.elastic.co/managed-by" + // configHashMetadataKey is the metadata key storing the hash API key + configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" + // managedByValue is the value for the managed-by metadata + managedByValue = "eck" +) + +// APIKeySpec represents the specification for an autoops API key +type APIKeySpec struct { + RoleDescriptors map[string]esclient.Role +} + +// reconcileAutoOpsESAPIKey reconciles the API key and secret for a specific Elasticsearch cluster. +func reconcileAutoOpsESAPIKey( + ctx context.Context, + c k8s.Client, + esClientProvider commonesclient.Provider, + dialer net.Dialer, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + log := ulog.FromContext(ctx).WithValues( + "es_namespace", es.Namespace, + "es_name", es.Name, + "policy_namespace", policy.Namespace, + "policy_name", policy.Name, + ) + log.V(1).Info("Reconciling AutoOps ES API key") + + if es.Status.Phase != esv1.ElasticsearchReadyPhase { + log.V(1).Info("Skipping ES cluster that is not ready") + return nil + } + + // Get Elasticsearch client + esClient, err := esClientProvider(ctx, c, dialer, es) + if err != nil { + return fmt.Errorf("while creating Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) + } + defer esClient.Close() + + // Build API key specification + apiKeySpec := APIKeySpec{ + RoleDescriptors: map[string]esclient.Role{ + "eck_autoops_role": defaultMonitoringRole, + }, + } + + // Calculate expected hash + expectedHash := hash.HashObject(apiKeySpec) + + // Generate API key name + apiKeyName := apiKeyNameFor(policy, es) + + // Check if API key exists + activeAPIKeys, err := esClient.GetAPIKeysByName(ctx, apiKeyName) + if err != nil { + return fmt.Errorf("while getting API keys by name %s: %w", apiKeyName, err) + } + + var activeAPIKey *esclient.APIKey + for i := range activeAPIKeys.APIKeys { + if activeAPIKeys.APIKeys[i].Name == apiKeyName { + activeAPIKey = &activeAPIKeys.APIKeys[i] + break + } + } + + if activeAPIKey == nil { + return createAPIKey(ctx, log, c, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) + } + + return maybeUpdateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) +} + +// createAPIKey creates a new API key in Elasticsearch and stores it in a secret. +func createAPIKey( + ctx context.Context, + log logr.Logger, + c k8s.Client, + esClient esclient.Client, + apiKeyName string, + apiKeySpec APIKeySpec, + expectedHash string, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + log.Info("Creating API key", "key", apiKeyName) + + metadata := newMetadataFor(&policy, &es, expectedHash) + metadataAny := make(map[string]any, len(metadata)) + for k, v := range metadata { + metadataAny[k] = v + } + + apiKeyResp, err := esClient.CreateAPIKey(ctx, esclient.APIKeyCreateRequest{ + Name: apiKeyName, + APIKeyUpdateRequest: esclient.APIKeyUpdateRequest{ + RoleDescriptors: apiKeySpec.RoleDescriptors, + Metadata: metadataAny, + }, + }) + if err != nil { + return fmt.Errorf("while creating API key %s: %w", apiKeyName, err) + } + + return storeAPIKeyInSecret(ctx, c, apiKeyName, apiKeyResp.Encoded, expectedHash, policy, es) +} + +// maybeUpdateAPIKey checks if the API key needs to be updated and handles it. +func maybeUpdateAPIKey( + ctx context.Context, + log logr.Logger, + c k8s.Client, + esClient esclient.Client, + activeAPIKey *esclient.APIKey, + apiKeyName string, + apiKeySpec APIKeySpec, + expectedHash string, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + // If the key isn't managed by ECK or it's hash is incorrect, invalidate and recreate the api key. + if apiKeyNeedsRecreation(activeAPIKey, expectedHash) { + return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + } + + // The api key is seemlingly up to date, so we need to ensure the secret exists with correct value + secretName := apiKeySecretNameFrom(es) + var secret corev1.Secret + nsn := types.NamespacedName{ + Namespace: policy.Namespace, + Name: secretName, + } + if err := c.Get(ctx, nsn, &secret); err != nil { + if apierrors.IsNotFound(err) { + // Secret doesn't exist so again we need to invalidate and recreate the api key. + log.Info("API key secret not found, recreating key", "key", apiKeyName) + return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + } + return fmt.Errorf("while retrieving API key secret %s: %w", secretName, err) + } + + // Since the secret exists, just just need to verify the data is correct. + if encodedKey, ok := secret.Data["api_key"]; !ok || string(encodedKey) == "" { + log.Info("API key secret exists but is missing api_key, recreating key", "key", apiKeyName) + return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + } + + log.V(1).Info("API key is up to date", "key", apiKeyName) + return nil +} + +func invalidateAndCreateAPIKey( + ctx context.Context, + log logr.Logger, + c k8s.Client, + esClient esclient.Client, + activeAPIKey *esclient.APIKey, + apiKeyName string, + apiKeySpec APIKeySpec, + expectedHash string, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + if err := invalidateAPIKey(ctx, esClient, activeAPIKey.ID); err != nil { + return err + } + return createAPIKey(ctx, log, c, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) +} + +func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { + if apiKey.Metadata == nil { + return true + } else { + managedBy, ok := apiKey.Metadata[managedByMetadataKey].(string) + if !ok || managedBy != managedByValue { + return true + } + currentHash, ok := apiKey.Metadata[configHashMetadataKey].(string) + if !ok || currentHash != expectedHash { + return true + } + } + return false +} + +// invalidateAPIKey invalidates an API key by its ID. +func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID string) error { + _, err := esClient.InvalidateAPIKeys(ctx, esclient.APIKeysInvalidateRequest{ + IDs: []string{keyID}, + }) + return err +} + +// storeAPIKeyInSecret stores the API key in a Kubernetes secret. +func storeAPIKeyInSecret( + ctx context.Context, + c k8s.Client, + apiKeyName string, + encodedKey string, + expectedHash string, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + secretName := apiKeySecretNameFrom(es) + expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) + + reconciled := &corev1.Secret{} + return reconciler.ReconcileResource( + reconciler.Params{ + Context: ctx, + Client: c, + Owner: &policy, + Expected: &expected, + Reconciled: reconciled, + NeedsUpdate: func() bool { + return !maps.IsSubset(expected.Labels, reconciled.Labels) || + !maps.IsSubset(expected.Annotations, reconciled.Annotations) || + !reflect.DeepEqual(expected.Data, reconciled.Data) + }, + UpdateReconciled: func() { + reconciled.Labels = maps.Merge(reconciled.Labels, expected.Labels) + reconciled.Annotations = maps.Merge(reconciled.Annotations, expected.Annotations) + reconciled.Data = expected.Data + }, + }, + ) +} + +// buildAutoOpsESAPIKeySecret builds the expected Secret for autoops ES API key. +func buildAutoOpsESAPIKeySecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, secretName string, encodedKey string, expectedHash string) corev1.Secret { + meta := metadata.Propagate(&policy, metadata.Metadata{ + Labels: newMetadataFor(&policy, &es, expectedHash), + Annotations: policy.GetAnnotations(), + }) + + return corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: policy.GetNamespace(), + Labels: meta.Labels, + Annotations: meta.Annotations, + }, + Data: map[string][]byte{ + "api_key": []byte(encodedKey), + }, + } +} + +// apiKeyNameFor generates a unique name for the API key according to the policy, and ES instance. +func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) string { + return fmt.Sprintf("eck-autoops-%s-%s-%s-%s", policy.Namespace, policy.Name, es.Namespace, es.Name) +} + +// apiKeySecretNameFrom generates the name for the API key secret from an ES instance. +func apiKeySecretNameFrom(es esv1.Elasticsearch) string { + return fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESAPIKeySecretNamePrefix) +} + +// newMetadataFor returns the metadata to be set in the Elasticsearch API key. +func newMetadataFor(policy *autoopsv1alpha1.AutoOpsAgentPolicy, es *esv1.Elasticsearch, expectedHash string) map[string]string { + return map[string]string{ + configHashMetadataKey: expectedHash, + "elasticsearch.k8s.elastic.co/name": es.Name, + "elasticsearch.k8s.elastic.co/namespace": es.Namespace, + managedByMetadataKey: managedByValue, + "autoops.k8s.elastic.co/policy-name": policy.Name, + "autoops.k8s.elastic.co/policy-namespace": policy.Namespace, + } +} + +// cleanupAutoOpsESAPIKey invalidates the API key and removes the secret when autoops should not exist. +func cleanupAutoOpsESAPIKey( + ctx context.Context, + c k8s.Client, + esClientProvider commonesclient.Provider, + dialer net.Dialer, + policy autoopsv1alpha1.AutoOpsAgentPolicy, + es esv1.Elasticsearch, +) error { + log := ulog.FromContext(ctx).WithValues( + "es_namespace", es.Namespace, + "es_name", es.Name, + "policy_namespace", policy.Namespace, + "policy_name", policy.Name, + ) + log.V(1).Info("Cleaning up AutoOps ES API key") + + if es.Status.Phase != esv1.ElasticsearchReadyPhase { + log.V(1).Info("Skipping ES cluster that is not ready") + return nil + } + + // Get Elasticsearch client + esClient, err := esClientProvider(ctx, c, dialer, es) + if err != nil { + return fmt.Errorf("failed to create Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) + } + defer esClient.Close() + + // Generate API key name + apiKeyName := apiKeyNameFor(policy, es) + + // Check if API key exists + activeAPIKeys, err := esClient.GetAPIKeysByName(ctx, apiKeyName) + if err != nil { + return fmt.Errorf("failed to get API keys by name %s: %w", apiKeyName, err) + } + + // Invalidate all matching API keys + for _, key := range activeAPIKeys.APIKeys { + if key.Name == apiKeyName { + log.Info("Invalidating API key", "key", apiKeyName, "id", key.ID) + if err := invalidateAPIKey(ctx, esClient, key.ID); err != nil { + log.Error(err, "Failed to invalidate API key", "key", apiKeyName, "id", key.ID) + // Continue to try to invalidate other keys + } + } + } + + // Delete the secret + secretName := apiKeySecretNameFrom(es) + secretKey := types.NamespacedName{ + Namespace: policy.Namespace, + Name: secretName, + } + var secret corev1.Secret + if err := c.Get(ctx, secretKey, &secret); err != nil { + if apierrors.IsNotFound(err) { + // Secret already deleted, nothing to do + return nil + } + return fmt.Errorf("failed to get API key secret %s: %w", secretName, err) + } + + log.Info("Deleting API key secret", "secret", secretName) + if err := c.Delete(ctx, &secret); err != nil { + if apierrors.IsNotFound(err) { + // Already deleted + return nil + } + return fmt.Errorf("failed to delete API key secret %s: %w", secretName, err) + } + + return nil +} diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 6d5cfb26941..5930149e1e5 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -5,13 +5,19 @@ package autoops import ( + "bytes" "context" + "fmt" + "path/filepath" "reflect" + "text/template" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -25,15 +31,20 @@ const ( autoOpsESConfigFileName = "autoops_es.yml" ) -// autoOpsESConfigData contains the static configuration data for the autoops agent -const autoOpsESConfigData = `receivers: +// autoOpsESConfigTemplate contains the configuration template for the autoops agent +const autoOpsESConfigTemplate = `receivers: metricbeatreceiver: metricbeat: modules: # Metrics - module: autoops_es hosts: ${env:AUTOOPS_ES_URL} +{{- if .SSLEnabled}} + ssl.verification_mode: certificate + ssl.certificate_authorities: ["{{ .CACertPath }}"] +{{- else}} ssl.verification_mode: none +{{- end}} period: 10s metricsets: - cat_shards @@ -45,7 +56,12 @@ const autoOpsESConfigData = `receivers: # Templates - module: autoops_es hosts: ${env:AUTOOPS_ES_URL} +{{- if .SSLEnabled}} + ssl.verification_mode: certificate + ssl.certificate_authorities: ["{{ .CACertPath }}"] +{{- else}} ssl.verification_mode: none +{{- end}} period: 24h metricsets: - cat_template @@ -66,6 +82,7 @@ exporters: Authorization: "AutoOpsToken ${env:AUTOOPS_TOKEN}" endpoint: ${env:AUTOOPS_OTEL_URL} service: + extensions: [healthcheckv2] pipelines: logs: receivers: [metricbeatreceiver] @@ -73,12 +90,36 @@ service: telemetry: logs: encoding: json +extensions: + healthcheckv2: + use_v2: true + component_health: + include_permanent_errors: true + include_recoverable_errors: true + recovery_duration: 5m + http: + endpoint: "0.0.0.0:13133" + status: + enabled: true + path: "/health/status" + config: + enabled: true + path: "/health/config" ` -// ReconcileAutoOpsESConfigMap reconciles the ConfigMap containing the autoops configuration. -// This ConfigMap is shared by all deployments created by the controller within the same namespace. -func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy) error { - expected := buildAutoOpsESConfigMap(policy) +// configTemplateData holds the data for rendering the config template +type configTemplateData struct { + SSLEnabled bool + CACertPath string +} + +// ReconcileAutoOpsESConfigMap reconciles the ConfigMap containing the autoops configuration +// specific to each ES instance. +func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) error { + expected, err := buildAutoOpsESConfigMap(policy, es) + if err != nil { + return err + } reconciled := &corev1.ConfigMap{} return reconciler.ReconcileResource( @@ -103,21 +144,49 @@ func ReconcileAutoOpsESConfigMap(ctx context.Context, c k8s.Client, policy autoo } // buildAutoOpsESConfigMap builds the expected ConfigMap for autoops configuration. -func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy) corev1.ConfigMap { +// SSL is enabled based on the Elasticsearch CRD's spec.http.tls configuration. +func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (corev1.ConfigMap, error) { meta := metadata.Propagate(&policy, metadata.Metadata{ Labels: policy.GetLabels(), Annotations: policy.GetAnnotations(), }) + // Build CA certificate path if SSL is enabled + caCertPath := "" + sslEnabled := es.Spec.HTTP.TLS.Enabled() + if sslEnabled { + caCertPath = filepath.Join( + fmt.Sprintf("/mnt/elastic-internal/es-ca/%s-%s", es.Namespace, es.Name), + certificates.CAFileName, + ) + } + + tmpl, err := template.New("autoops-config").Parse(autoOpsESConfigTemplate) + if err != nil { + return corev1.ConfigMap{}, err + } + + var configBuf bytes.Buffer + templateData := configTemplateData{ + SSLEnabled: sslEnabled, + CACertPath: caCertPath, + } + if err := tmpl.Execute(&configBuf, templateData); err != nil { + return corev1.ConfigMap{}, err + } + + // Use ES-specific ConfigMap name to allow per-ES configuration + configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + return corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: autoOpsESConfigMapName, + Name: configMapName, Namespace: policy.GetNamespace(), Labels: meta.Labels, Annotations: meta.Annotations, }, Data: map[string]string{ - autoOpsESConfigFileName: autoOpsESConfigData, + autoOpsESConfigFileName: configBuf.String(), }, - } + }, nil } diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index ada019c8869..56ebd989250 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -23,6 +23,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common" + commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" @@ -37,10 +38,8 @@ const ( controllerName = "autoops-controller" ) -var ( - // defaultRequeue is the default requeue interval for this controller. - defaultRequeue = 5 * time.Second -) +// defaultRequeue is the default requeue interval for this controller. +var defaultRequeue = 5 * time.Second // Add creates a new AutoOpsAgentPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller // and Start it when the Manager is Started. @@ -57,11 +56,12 @@ func Add(mgr manager.Manager, params operator.Parameters) error { func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAutoOpsAgentPolicy { k8sClient := mgr.GetClient() return &ReconcileAutoOpsAgentPolicy{ - Client: k8sClient, - recorder: mgr.GetEventRecorderFor(controllerName), - licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), - params: params, - dynamicWatches: watches.NewDynamicWatches(), + Client: k8sClient, + recorder: mgr.GetEventRecorderFor(controllerName), + licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), + params: params, + dynamicWatches: watches.NewDynamicWatches(), + esClientProvider: commonesclient.NewClient, } } @@ -80,10 +80,11 @@ var _ reconcile.Reconciler = &ReconcileAutoOpsAgentPolicy{} // ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object type ReconcileAutoOpsAgentPolicy struct { k8s.Client - recorder record.EventRecorder - licenseChecker license.Checker - params operator.Parameters - dynamicWatches watches.DynamicWatches + recorder record.EventRecorder + licenseChecker license.Checker + params operator.Parameters + dynamicWatches watches.DynamicWatches + esClientProvider commonesclient.Provider // iteration is the number of times this controller has run its Reconcile method iteration uint64 } @@ -198,6 +199,11 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na defer tracing.Span(&ctx)() // Remove dynamic watches on secrets r.dynamicWatches.Secrets.RemoveHandlerForKey(configSecretWatchName(obj)) + + // (TODO) + // Cleanup API keys for all Elasticsearch clusters that match this policy. + // If we label the secrets created from the policy properly, we can query + // for these, and properly delete the api keys. return nil } diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 4b164e6aece..46bdd27bfc4 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -1,12 +1,16 @@ package autoops import ( + "context" + "fmt" + "hash/fnv" "path" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" @@ -18,12 +22,16 @@ import ( common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/volume" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/services" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" ) const ( - configVolumeName = "config-volume" - configVolumePath = "/mnt/config" + configVolumeName = "config-volume" + configVolumePath = "/mnt/config" + configHashAnnotationName = "autoops.k8s.elastic.co/config-hash" + readinessProbePort = 13133 ) var ( @@ -39,15 +47,14 @@ var ( }, }, } - configVolume = volume.NewConfigMapVolume(autoOpsESConfigMapName, configVolumeName, configVolumePath) ) type ExpectedResources struct { deployment appsv1.Deployment } -func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { - deployment, err := r.deploymentParams(policy, es) +func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { + deployment, err := r.deploymentParams(ctx, policy, es) if err != nil { return ExpectedResources{}, err } @@ -56,7 +63,7 @@ func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(policy autoopsv1 }, nil } -func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { +func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { var deployment appsv1.Deployment v, err := version.Parse(policy.Spec.Version) if err != nil { @@ -79,17 +86,43 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(policy autoopsv1alpha1.Au }, }, } + // Create ES-specific config map volume + configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + configVolume := volume.NewConfigMapVolume(configMapName, configVolumeName, configVolumePath) + volumes := []corev1.Volume{configVolume.Volume()} volumeMounts := []corev1.VolumeMount{configVolume.VolumeMount()} - meta := metadata.Propagate(&policy, metadata.Metadata{Labels: labels, Annotations: nil}) + + // Add CA certificate volume for this ES instance only if TLS is enabled + if es.Spec.HTTP.TLS.Enabled() { + caSecretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretPrefix) + caVolume := volume.NewSecretVolumeWithMountPath( + caSecretName, + fmt.Sprintf("es-ca-%s-%s", es.Name, es.Namespace), + fmt.Sprintf("/mnt/elastic-internal/es-ca/%s-%s", es.Namespace, es.Name), + ) + volumes = append(volumes, caVolume.Volume()) + volumeMounts = append(volumeMounts, caVolume.VolumeMount()) + } + + // Build config hash from ConfigMap to trigger pod restart on config changes + configHash, err := buildConfigHash(ctx, r.Client, policy, es) + if err != nil { + return appsv1.Deployment{}, err + } + + annotations := map[string]string{configHashAnnotationName: configHash} + meta := metadata.Propagate(&policy, metadata.Metadata{Labels: labels, Annotations: annotations}) podTemplateSpec := defaults.NewPodTemplateBuilder(basePodTemplate, "autoops-agent"). WithArgs("--config", path.Join(configVolumePath, autoOpsESConfigFileName)). WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). - WithEnv(autoopsEnvVars(types.NamespacedName{Namespace: es.Namespace, Name: es.Name})...). + WithEnv(autoopsEnvVars(es)...). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). + WithPorts([]corev1.ContainerPort{{Name: "http", ContainerPort: int32(readinessProbePort), Protocol: corev1.ProtocolTCP}}). + WithReadinessProbe(readinessProbe()). WithContainersSecurityContext(corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(false), Capabilities: &corev1.Capabilities{ @@ -115,11 +148,47 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(policy autoopsv1alpha1.Au return deployment, nil } +// readinessProbe is the readiness probe for the AutoOps Agent container +func readinessProbe() corev1.Probe { + scheme := corev1.URISchemeHTTP + return corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.FromInt(readinessProbePort), + Path: "/health/status", + Scheme: scheme, + }, + }, + } +} + +// buildConfigHash builds a hash of the ConfigMap data to trigger pod restart on config changes +func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (string, error) { + configHash := fnv.New32a() + + configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + var configMap corev1.ConfigMap + configMapKey := types.NamespacedName{Namespace: policy.Namespace, Name: configMapName} + if err := c.Get(ctx, configMapKey, &configMap); err != nil { + return "", err + } + + if configData, ok := configMap.Data[autoOpsESConfigFileName]; ok { + _, _ = configHash.Write([]byte(configData)) + } + + return fmt.Sprint(configHash.Sum32()), nil +} + // autoopsEnvVars returns the environment variables for the AutoOps deployment // that reference values from the autoops-secret and the ES elastic user secret. -func autoopsEnvVars(esNN types.NamespacedName) []corev1.EnvVar { - // Encode the secret key using base64 URL encoding to ensure it matches the regex '[-._a-zA-Z0-9]+' - secretKey := encodeESSecretKey(esNN.Namespace, esNN.Name) +func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { + esService := services.InternalServiceURL(es) return []corev1.EnvVar{ { Name: "AUTOOPS_TOKEN", @@ -133,27 +202,9 @@ func autoopsEnvVars(esNN types.NamespacedName) []corev1.EnvVar { }, }, { - Name: "AUTOOPS_ES_URL", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "autoops-es-url", - }, - }, + Name: "AUTOOPS_ES_URL", + Value: esService, }, - // { - // Name: "AUTOOPS_TEMP_RESOURCE_ID", - // ValueFrom: &corev1.EnvVarSource{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: "autoops-secret", - // }, - // Key: "temp-resource-id", - // }, - // }, - // }, { Name: "AUTOOPS_OTEL_URL", ValueFrom: &corev1.EnvVarSource{ @@ -166,17 +217,13 @@ func autoopsEnvVars(esNN types.NamespacedName) []corev1.EnvVar { }, }, { - Name: "AUTOOPS_ES_USERNAME", - Value: "elastic-internal-monitoring", - }, - { - Name: "AUTOOPS_ES_PASSWORD", + Name: "AUTOOPS_ES_API_KEY", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: autoOpsESPasswordsSecretName, + Name: apiKeySecretNameFrom(es), }, - Key: secretKey, + Key: "api_key", Optional: ptr.To(false), }, }, diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index a53e3066b21..d9d477f70c3 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -5,19 +5,23 @@ package autoops import ( + "context" "fmt" + "hash/fnv" "testing" "github.com/google/go-cmp/cmp" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" ) @@ -39,6 +43,13 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, Spec: esv1.ElasticsearchSpec{ Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, }, } @@ -58,7 +69,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { autoops: autoopsFixture, es: esFixture, }, - want: expectedDeployment(autoopsFixture, esFixture), + want: appsv1.Deployment{}, // Will be computed in test wantErr: false, }, { @@ -82,32 +93,57 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := &ReconcileAutoOpsAgentPolicy{} - got, err := r.deploymentParams(tt.args.autoops, tt.args.es) + // We need a ConfigMap to calculate the config hash for the deployment. + configData := "test-config-data" + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, tt.args.es.Namespace, tt.args.es.Name), + Namespace: tt.args.autoops.Namespace, + }, + Data: map[string]string{ + autoOpsESConfigFileName: configData, + }, + } + client := k8s.NewFakeClient(configMap) + r := &ReconcileAutoOpsAgentPolicy{ + Client: client, + } + ctx := context.Background() + got, err := r.deploymentParams(ctx, tt.args.autoops, tt.args.es) if (err != nil) != tt.wantErr { t.Errorf("ReconcileAutoOpsAgentPolicy.deploymentParams() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr { - if !cmp.Equal(got, tt.want) { - t.Errorf("ReconcileAutoOpsAgentPolicy.deploymentParams() diff = %v", cmp.Diff(got, tt.want)) + // Calculate expected config hash to match what buildConfigHash computes + expectedConfigHash := fnv.New32a() + _, _ = expectedConfigHash.Write([]byte(configData)) + expectedHashStr := fmt.Sprint(expectedConfigHash.Sum32()) + want := expectedDeployment(tt.args.autoops, tt.args.es, expectedHashStr) + if !cmp.Equal(got, want) { + t.Errorf("ReconcileAutoOpsAgentPolicy.deploymentParams() diff = %v", cmp.Diff(got, want)) } } }) } } -func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) appsv1.Deployment { +func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, configHashValue string) appsv1.Deployment { v, _ := version.Parse(autoops.Spec.Version) labels := map[string]string{ commonv1.TypeLabelName: "autoops-agent", "autoops.k8s.elastic.co/name": autoops.Name, } + annotations := map[string]string{ + configHashAnnotationName: configHashValue, + } + return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-autoops-deploy", es.Name), - Labels: labels, + Name: AutoOpsNamer.Suffix(es.Name, es.GetNamespace(), "deploy"), + Namespace: autoops.GetNamespace(), + Labels: labels, }, Spec: appsv1.DeploymentSpec{ Replicas: pointer.Int32(1), @@ -119,7 +155,7 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: labels, - Annotations: nil, + Annotations: annotations, }, Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ @@ -128,7 +164,7 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-es-config", + Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name), }, DefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode), Optional: ptr.To(false), @@ -145,6 +181,13 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas "--config", "/mnt/config/autoops_es.yml", }, + Ports: []corev1.ContainerPort{ + { + Name: "http", + ContainerPort: int32(readinessProbePort), + Protocol: corev1.ProtocolTCP, + }, + }, VolumeMounts: []corev1.VolumeMount{ { Name: "config-volume", @@ -152,6 +195,20 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas ReadOnly: true, }, }, + ReadinessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.FromInt(readinessProbePort), + Path: "/health/status", + Scheme: corev1.URISchemeHTTP, + }, + }, + }, Env: []corev1.EnvVar{ { Name: "AUTOOPS_TOKEN", @@ -165,26 +222,8 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas }, }, { - Name: "AUTOOPS_ES_URL", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "autoops-es-url", - }, - }, - }, - { - Name: "AUTOOPS_TEMP_RESOURCE_ID", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "temp-resource-id", - }, - }, + Name: "AUTOOPS_ES_URL", + Value: "http://es-cluster-es-internal-http.default.svc:9200", }, { Name: "AUTOOPS_OTEL_URL", @@ -198,13 +237,14 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas }, }, { - Name: "ELASTICSEARCH_READ_API_KEY", + Name: "AUTOOPS_ES_API_KEY", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: apiKeySecretNameFrom(es), }, - Key: "es-api-key", + Key: "api_key", + Optional: ptr.To(false), }, }, }, @@ -238,8 +278,7 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas Drop: []corev1.Capability{"ALL"}, }, Privileged: ptr.To(false), - ReadOnlyRootFilesystem: ptr.To(true), - RunAsNonRoot: ptr.To(true), + ReadOnlyRootFilesystem: ptr.To(false), SeccompProfile: &corev1.SeccompProfile{ Type: corev1.SeccompProfileTypeRuntimeDefault, }, @@ -251,3 +290,197 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas }, } } + +func Test_readinessProbe(t *testing.T) { + tests := []struct { + name string + want corev1.Probe + }{ + { + name: "readiness probe configuration", + want: corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.FromInt(readinessProbePort), + Path: "/health/status", + Scheme: corev1.URISchemeHTTP, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := readinessProbe() + if !cmp.Equal(got, tt.want) { + t.Errorf("readinessProbe() diff = %v", cmp.Diff(got, tt.want)) + } + }) + } +} + +func Test_autoopsEnvVars(t *testing.T) { + tests := []struct { + name string + es esv1.Elasticsearch + want []corev1.EnvVar + }{ + { + name: "basic ES instance", + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + }, + }, + want: []corev1.EnvVar{ + { + Name: "AUTOOPS_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-token", + }, + }, + }, + { + Name: "AUTOOPS_ES_URL", + Value: "http://es-1-es-internal-http.ns-1.svc:9200", + }, + { + Name: "AUTOOPS_OTEL_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-otel-url", + }, + }, + }, + { + Name: "AUTOOPS_ES_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "es-1-ns-1-autoops-es-api-key", + }, + Key: "api_key", + Optional: ptr.To(false), + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-url", + Optional: ptr.To(true), + }, + }, + }, + }, + }, + { + name: "ES instance with different namespace", + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-cluster", + Namespace: "elastic-system", + }, + }, + want: []corev1.EnvVar{ + { + Name: "AUTOOPS_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-token", + }, + }, + }, + { + Name: "AUTOOPS_ES_URL", + Value: "http://es-cluster-es-internal-http.elastic-system.svc:9200", + }, + { + Name: "AUTOOPS_OTEL_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "autoops-otel-url", + }, + }, + }, + { + Name: "AUTOOPS_ES_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "es-cluster-elastic-system-autoops-es-api-key", + }, + Key: "api_key", + Optional: ptr.To(false), + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-key", + }, + }, + }, + { + Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_URL", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "autoops-secret", + }, + Key: "cloud-connected-mode-api-url", + Optional: ptr.To(true), + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := autoopsEnvVars(tt.es) + if !cmp.Equal(got, tt.want) { + t.Errorf("autoopsEnvVars() diff = %v", cmp.Diff(got, tt.want)) + } + }) + } +} diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index dbf26ca962d..00985464d00 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -92,23 +92,31 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( return results } - if err := reconcileAutoOpsESPasswordsSecret(ctx, r.Client, policy, esList.Items); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase - return results.WithError(err) - } - for _, es := range esList.Items { if es.Status.Phase != esv1.ElasticsearchReadyPhase { results = results.WithRequeue(defaultRequeue) continue } - if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy); err != nil { + if es.Spec.HTTP.TLS.Enabled() { + if err := reconcileAutoOpsESCASecret(ctx, r.Client, policy, es); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase + return results.WithError(err) + } + } + + // Reconcile API key for this Elasticsearch cluster + if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { + status.Phase = autoopsv1alpha1.ErrorPhase + return results.WithError(err) + } + + if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy, es); err != nil { status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err) } - expectedResources, err := r.generateExpectedResources(policy, es) + expectedResources, err := r.generateExpectedResources(ctx, policy, es) if err != nil { status.Phase = autoopsv1alpha1.ErrorPhase return results.WithError(err) diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 0c48ffa6510..7fe657e2120 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "encoding/base64" "fmt" "reflect" @@ -24,104 +23,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" ) -const ( - // autoOpsESPasswordsSecretName is the name for the autoops-es-passwords Secret - autoOpsESPasswordsSecretName = "autoops-es-passwords" - // monitoringUserName is the name of the elastic-internal-monitoring user - monitoringUserName = "elastic-internal-monitoring" -) - -// encodeESSecretKey encodes a namespace/name combination into a valid secret key. -// Secret keys must match the regex '[-._a-zA-Z0-9]+', so we use base64 URL encoding -// which produces characters in that range. -func encodeESSecretKey(namespace, name string) string { - key := fmt.Sprintf("%s/%s", namespace, name) - return base64.URLEncoding.EncodeToString([]byte(key)) -} - -// reconcileAutoOpsESPasswordsSecret reconciles the Secret containing the elastic-internal-monitoring -// password for all Elasticsearch clusters referenced by the policy. -func reconcileAutoOpsESPasswordsSecret( - ctx context.Context, - c k8s.Client, - policy autoopsv1alpha1.AutoOpsAgentPolicy, - esList []esv1.Elasticsearch, -) error { - log := ulog.FromContext(ctx) - log.V(1).Info("Reconciling AutoOps ES passwords secret", "namespace", policy.Namespace) - - secretData := make(map[string][]byte) - for _, es := range esList { - if es.Status.Phase != esv1.ElasticsearchReadyPhase { - log.V(1).Info("Skipping ES cluster that is not ready", "namespace", es.Namespace, "name", es.Name) - continue - } - - internalUsersSecretKey := types.NamespacedName{ - Namespace: es.Namespace, - Name: esv1.InternalUsersSecret(es.Name), - } - var internalUsersSecret corev1.Secret - if err := c.Get(ctx, internalUsersSecretKey, &internalUsersSecret); err != nil { - if apierrors.IsNotFound(err) { - log.V(1).Info("InternalUsersSecret not found for ES cluster, skipping", "namespace", es.Namespace, "name", es.Name) - continue - } - return fmt.Errorf("while retrieving internal-users secret for ES cluster %s/%s: %w", es.Namespace, es.Name, err) - } - - password, ok := internalUsersSecret.Data[monitoringUserName] - if !ok { - log.V(1).Info("elastic-internal-monitoring user not found in internal-users secret, skipping", "namespace", es.Namespace, "name", es.Name) - continue - } - - secretKey := encodeESSecretKey(es.Namespace, es.Name) - secretData[secretKey] = password - } - - expected := buildAutoOpsESPasswordsSecret(policy, secretData) - - reconciled := &corev1.Secret{} - return reconciler.ReconcileResource( - reconciler.Params{ - Context: ctx, - Client: c, - Owner: &policy, - Expected: &expected, - Reconciled: reconciled, - NeedsUpdate: func() bool { - return !maps.IsSubset(expected.Labels, reconciled.Labels) || - !maps.IsSubset(expected.Annotations, reconciled.Annotations) || - !reflect.DeepEqual(expected.Data, reconciled.Data) - }, - UpdateReconciled: func() { - reconciled.Labels = maps.Merge(reconciled.Labels, expected.Labels) - reconciled.Annotations = maps.Merge(reconciled.Annotations, expected.Annotations) - reconciled.Data = expected.Data - }, - }, - ) -} - -// buildAutoOpsESPasswordsSecret builds the expected Secret for autoops ES passwords. -func buildAutoOpsESPasswordsSecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, secretData map[string][]byte) corev1.Secret { - meta := metadata.Propagate(&policy, metadata.Metadata{ - Labels: policy.GetLabels(), - Annotations: policy.GetAnnotations(), - }) - - return corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: autoOpsESPasswordsSecretName, - Namespace: policy.GetNamespace(), - Labels: meta.Labels, - Annotations: meta.Annotations, - }, - Data: secretData, - } -} - const ( // autoOpsESCASecretPrefix is the prefix for CA secrets created for each ES instance autoOpsESCASecretPrefix = "autoops-es-ca" diff --git a/pkg/controller/elasticsearch/client/api_key.go b/pkg/controller/elasticsearch/client/api_key.go new file mode 100644 index 00000000000..4051a10c454 --- /dev/null +++ b/pkg/controller/elasticsearch/client/api_key.go @@ -0,0 +1,44 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package client + +// APIKey represents an Elasticsearch API key. +type APIKey struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + APIKey string `json:"api_key,omitempty"` + Encoded string `json:"encoded,omitempty"` + Metadata map[string]interface{} `json:"metadata,omitempty"` +} + +type APIKeyList struct { + APIKeys []APIKey `json:"api_keys,omitempty"` +} + +type APIKeyCreateRequest struct { + Name string `json:"name,omitempty"` + APIKeyUpdateRequest +} + +type APIKeyUpdateRequest struct { + APIKey `json:",inline"` + Metadata map[string]any `json:"metadata,omitempty"` + RoleDescriptors map[string]Role `json:"role_descriptors,omitempty"` +} + +type APIKeyCreateResponse struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + APIKey string `json:"api_key,omitempty"` + Encoded string `json:"encoded,omitempty"` +} + +type APIKeysInvalidateRequest struct { + IDs []string `json:"ids,omitempty"` +} + +type APIKeysInvalidateResponse struct { + InvalidatedAPIKeys []string `json:"invalidated_api_keys,omitempty"` +} diff --git a/pkg/controller/elasticsearch/client/client.go b/pkg/controller/elasticsearch/client/client.go index fa2f903a3a3..6845f087a4e 100644 --- a/pkg/controller/elasticsearch/client/client.go +++ b/pkg/controller/elasticsearch/client/client.go @@ -38,7 +38,7 @@ type BasicAuth struct { type IndexRole struct { Names []string `json:"names,omitempty"` - Privileges []string `json:",omitempty"` + Privileges []string `json:"privileges,omitempty"` AllowRestrictedIndices *bool `json:"allow_restricted_indices,omitempty" yaml:"allow_restricted_indices,omitempty"` } diff --git a/pkg/controller/elasticsearch/client/security.go b/pkg/controller/elasticsearch/client/security.go index 2b01e0d6b83..b1a090454c2 100644 --- a/pkg/controller/elasticsearch/client/security.go +++ b/pkg/controller/elasticsearch/client/security.go @@ -38,6 +38,12 @@ type SecurityClient interface { // GetServiceAccountCredentials returns the service account credentials from the /_security/service API GetServiceAccountCredentials(ctx context.Context, namespacedService string) (ServiceAccountCredential, error) + // GetAPIKeysByName returns the API keys by name from the /_security/api_key API + GetAPIKeysByName(ctx context.Context, name string) (APIKeyList, error) + // CreateAPIKey creates a new API key from the /_security/api_key API + CreateAPIKey(ctx context.Context, request APIKeyCreateRequest) (APIKeyCreateResponse, error) + // InvalidateAPIKeys invalidates one or more API keys by their IDs from the /_security/api_key API + InvalidateAPIKeys(ctx context.Context, request APIKeysInvalidateRequest) (APIKeysInvalidateResponse, error) } func (c *clientV6) GetServiceAccountCredentials(_ context.Context, _ string) (ServiceAccountCredential, error) { @@ -52,3 +58,70 @@ func (c *clientV7) GetServiceAccountCredentials(ctx context.Context, namespacedS } return serviceAccountCredential, nil } + +func (c *clientV6) GetAPIKeysByName(ctx context.Context, name string) (APIKeyList, error) { + return APIKeyList{}, errNotSupportedInEs6x +} + +func (c *clientV7) GetAPIKeysByName(ctx context.Context, name string) (APIKeyList, error) { + var apiKeys APIKeyList + path := fmt.Sprintf("/_security/api_key?name=%s", name) + if err := c.get(ctx, path, &apiKeys); err != nil { + return apiKeys, err + } + return apiKeys, nil +} + +func (c *clientV8) GetAPIKeysByName(ctx context.Context, name string) (APIKeyList, error) { + var apiKeys APIKeyList + // active_only added in 8.10 + path := fmt.Sprintf("/_security/api_key?name=%s&active_only=true", name) + if err := c.get(ctx, path, &apiKeys); err != nil { + return apiKeys, err + } + return apiKeys, nil +} + +func (c *clientV6) CreateAPIKey(ctx context.Context, request APIKeyCreateRequest) (APIKeyCreateResponse, error) { + return APIKeyCreateResponse{}, errNotSupportedInEs6x +} + +func (c *clientV7) CreateAPIKey(ctx context.Context, request APIKeyCreateRequest) (APIKeyCreateResponse, error) { + var apiKey APIKeyCreateResponse + path := "/_security/api_key" + if err := c.post(ctx, path, request, &apiKey); err != nil { + return apiKey, err + } + return apiKey, nil +} + +func (c *clientV8) CreateAPIKey(ctx context.Context, request APIKeyCreateRequest) (APIKeyCreateResponse, error) { + var apiKey APIKeyCreateResponse + path := "/_security/api_key" + if err := c.post(ctx, path, request, &apiKey); err != nil { + return apiKey, err + } + return apiKey, nil +} + +func (c *clientV6) InvalidateAPIKeys(ctx context.Context, request APIKeysInvalidateRequest) (APIKeysInvalidateResponse, error) { + return APIKeysInvalidateResponse{}, errNotSupportedInEs6x +} + +func (c *clientV7) InvalidateAPIKeys(ctx context.Context, request APIKeysInvalidateRequest) (APIKeysInvalidateResponse, error) { + path := "/_security/api_key" + var response APIKeysInvalidateResponse + if err := c.deleteWithObjects(ctx, path, request, &response); err != nil { + return response, err + } + return response, nil +} + +func (c *clientV8) InvalidateAPIKeys(ctx context.Context, request APIKeysInvalidateRequest) (APIKeysInvalidateResponse, error) { + path := "/_security/api_key" + var response APIKeysInvalidateResponse + if err := c.deleteWithObjects(ctx, path, request, &response); err != nil { + return response, err + } + return response, nil +} diff --git a/pkg/controller/elasticsearch/driver/driver_test.go b/pkg/controller/elasticsearch/driver/driver_test.go index b7212d76ada..b05e4807162 100644 --- a/pkg/controller/elasticsearch/driver/driver_test.go +++ b/pkg/controller/elasticsearch/driver/driver_test.go @@ -156,6 +156,7 @@ func Test_allNodesRunningServiceAccounts(t *testing.T) { type fakeSecurityClient struct { // namespacedService -> ServiceAccountCredential serviceAccountCredentials map[string]esclient.ServiceAccountCredential + apiKeys map[string]esclient.APIKey } var _ esclient.SecurityClient = &fakeSecurityClient{} @@ -165,9 +166,34 @@ func (f *fakeSecurityClient) GetServiceAccountCredentials(_ context.Context, nam return serviceAccountCredential, nil } +func (f *fakeSecurityClient) GetAPIKeysByName(_ context.Context, name string) (esclient.APIKeyList, error) { + apiKeys := esclient.APIKeyList{ + APIKeys: []esclient.APIKey{f.apiKeys[name]}, + } + return apiKeys, nil +} + +func (f *fakeSecurityClient) CreateAPIKey(_ context.Context, request esclient.APIKeyCreateRequest) (esclient.APIKeyCreateResponse, error) { + apiKey := esclient.APIKeyCreateResponse{ + ID: f.apiKeys[request.Name].ID, + Name: f.apiKeys[request.Name].Name, + APIKey: f.apiKeys[request.Name].APIKey, + Encoded: f.apiKeys[request.Name].Encoded, + } + return apiKey, nil +} + +func (f *fakeSecurityClient) InvalidateAPIKeys(_ context.Context, request esclient.APIKeysInvalidateRequest) (esclient.APIKeysInvalidateResponse, error) { + response := esclient.APIKeysInvalidateResponse{ + InvalidatedAPIKeys: request.IDs, + } + return response, nil +} + func newFakeSecurityClient() *fakeSecurityClient { return &fakeSecurityClient{ serviceAccountCredentials: make(map[string]esclient.ServiceAccountCredential), + apiKeys: make(map[string]esclient.APIKey), } } From a52095f8aa9832cb9afad6afd9c518de041955a7 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 14:36:28 -0600 Subject: [PATCH 14/90] Cleanup. Adding additional unit tests Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 30 +- pkg/controller/autoops/api_key_test.go | 231 +++++++++++++++ pkg/controller/autoops/configuration.go | 6 +- pkg/controller/autoops/configuration_test.go | 182 ++++++++++++ pkg/controller/autoops/controller.go | 44 ++- pkg/controller/autoops/controller_test.go | 297 +++++++++++++++++++ pkg/controller/autoops/expected_test.go | 74 +---- pkg/controller/autoops/secret.go | 7 +- 8 files changed, 778 insertions(+), 93 deletions(-) create mode 100644 pkg/controller/autoops/api_key_test.go create mode 100644 pkg/controller/autoops/configuration_test.go create mode 100644 pkg/controller/autoops/controller_test.go diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 4e80c706ef4..93be9e13fed 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -42,6 +42,10 @@ const ( configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" // managedByValue is the value for the managed-by metadata managedByValue = "eck" + // policyNameLabelKey is the label key for the AutoOpsAgentPolicy name + policyNameLabelKey = "autoops.k8s.elastic.co/policy-name" + // policyNamespaceLabelKey is the label key for the AutoOpsAgentPolicy namespace + policyNamespaceLabelKey = "autoops.k8s.elastic.co/policy-namespace" ) // APIKeySpec represents the specification for an autoops API key @@ -274,6 +278,10 @@ func buildAutoOpsESAPIKeySecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es es Annotations: policy.GetAnnotations(), }) + // The 'managed-by' is only needed/wanted for the API key in + // Elasticsearch so we remove it from the secret. + delete(meta.Labels, managedByMetadataKey) + return corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, @@ -300,12 +308,12 @@ func apiKeySecretNameFrom(es esv1.Elasticsearch) string { // newMetadataFor returns the metadata to be set in the Elasticsearch API key. func newMetadataFor(policy *autoopsv1alpha1.AutoOpsAgentPolicy, es *esv1.Elasticsearch, expectedHash string) map[string]string { return map[string]string{ - configHashMetadataKey: expectedHash, - "elasticsearch.k8s.elastic.co/name": es.Name, - "elasticsearch.k8s.elastic.co/namespace": es.Namespace, - managedByMetadataKey: managedByValue, - "autoops.k8s.elastic.co/policy-name": policy.Name, - "autoops.k8s.elastic.co/policy-namespace": policy.Namespace, + configHashMetadataKey: expectedHash, + "elasticsearch.k8s.elastic.co/name": es.Name, + "elasticsearch.k8s.elastic.co/namespace": es.Namespace, + managedByMetadataKey: managedByValue, + policyNameLabelKey: policy.Name, + policyNamespaceLabelKey: policy.Namespace, } } @@ -315,14 +323,14 @@ func cleanupAutoOpsESAPIKey( c k8s.Client, esClientProvider commonesclient.Provider, dialer net.Dialer, - policy autoopsv1alpha1.AutoOpsAgentPolicy, + policyNamespace, policyName string, es esv1.Elasticsearch, ) error { log := ulog.FromContext(ctx).WithValues( "es_namespace", es.Namespace, "es_name", es.Name, - "policy_namespace", policy.Namespace, - "policy_name", policy.Name, + "policy_namespace", policyNamespace, + "policy_name", policyName, ) log.V(1).Info("Cleaning up AutoOps ES API key") @@ -339,7 +347,7 @@ func cleanupAutoOpsESAPIKey( defer esClient.Close() // Generate API key name - apiKeyName := apiKeyNameFor(policy, es) + apiKeyName := fmt.Sprintf("eck-autoops-%s-%s-%s-%s", policyNamespace, policyName, es.Namespace, es.Name) // Check if API key exists activeAPIKeys, err := esClient.GetAPIKeysByName(ctx, apiKeyName) @@ -361,7 +369,7 @@ func cleanupAutoOpsESAPIKey( // Delete the secret secretName := apiKeySecretNameFrom(es) secretKey := types.NamespacedName{ - Namespace: policy.Namespace, + Namespace: policyNamespace, Name: secretName, } var secret corev1.Secret diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go new file mode 100644 index 00000000000..89d6e2448b6 --- /dev/null +++ b/pkg/controller/autoops/api_key_test.go @@ -0,0 +1,231 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" +) + +func Test_apiKeyNeedsRecreation(t *testing.T) { + tests := []struct { + name string + apiKey *esclient.APIKey + expectedHash string + want bool + }{ + { + name: "nil metadata requires recreation", + apiKey: &esclient.APIKey{Metadata: nil}, + expectedHash: "hash123", + want: true, + }, + { + name: "missing managed-by metadata requires recreation", + apiKey: &esclient.APIKey{ + Metadata: map[string]any{}, + }, + expectedHash: "hash123", + want: true, + }, + { + name: "wrong managed-by value requires recreation", + apiKey: &esclient.APIKey{ + Metadata: map[string]any{ + managedByMetadataKey: "wrong-value", + }, + }, + expectedHash: "hash123", + want: true, + }, + { + name: "missing config hash requires recreation", + apiKey: &esclient.APIKey{ + Metadata: map[string]any{ + managedByMetadataKey: managedByValue, + }, + }, + expectedHash: "hash123", + want: true, + }, + { + name: "wrong config hash requires recreation", + apiKey: &esclient.APIKey{ + Metadata: map[string]any{ + managedByMetadataKey: managedByValue, + configHashMetadataKey: "wrong-hash", + }, + }, + expectedHash: "hash123", + want: true, + }, + { + name: "correct metadata does not require recreation", + apiKey: &esclient.APIKey{ + Metadata: map[string]any{ + managedByMetadataKey: managedByValue, + configHashMetadataKey: "hash123", + }, + }, + expectedHash: "hash123", + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := apiKeyNeedsRecreation(tt.apiKey, tt.expectedHash); got != tt.want { + t.Errorf("apiKeyNeedsRecreation() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_newMetadataFor(t *testing.T) { + tests := []struct { + name string + policy *autoopsv1alpha1.AutoOpsAgentPolicy + es *esv1.Elasticsearch + expectedHash string + want map[string]string + }{ + { + name: "happy path", + policy: &autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + }, + es: &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + }, + expectedHash: "hash123", + want: map[string]string{ + configHashMetadataKey: "hash123", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + managedByMetadataKey: managedByValue, + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := newMetadataFor(tt.policy, tt.es, tt.expectedHash) + if !cmp.Equal(got, tt.want) { + t.Errorf("newMetadataFor() diff = %v", cmp.Diff(got, tt.want)) + } + }) + } +} + +func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { + tests := []struct { + name string + policy autoopsv1alpha1.AutoOpsAgentPolicy + es esv1.Elasticsearch + secretName string + encodedKey string + expectedHash string + want corev1.Secret + }{ + { + name: "basic secret", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + Labels: map[string]string{ + "label1": "value1", + }, + Annotations: map[string]string{ + "annotation1": "value1", + }, + }, + }, + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + }, + secretName: "secret-1", + encodedKey: "encoded-api-key-value", + expectedHash: "hash123", + want: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secret-1", + Namespace: "ns-1", + Labels: map[string]string{ + configHashMetadataKey: "hash123", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + "autoops.k8s.elastic.co/policy-name": "policy-1", + "autoops.k8s.elastic.co/policy-namespace": "ns-1", + }, + Annotations: map[string]string{ + "annotation1": "value1", + }, + }, + Data: map[string][]byte{ + "api_key": []byte("encoded-api-key-value"), + }, + }, + }, + { + name: "no labels or annotations on policy has no change in behavior", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + }, + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + }, + secretName: "secret-1", + encodedKey: "key", + expectedHash: "hash123", + want: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secret-1", + Namespace: "ns-1", + Labels: map[string]string{ + configHashMetadataKey: "hash123", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + "autoops.k8s.elastic.co/policy-name": "policy-1", + "autoops.k8s.elastic.co/policy-namespace": "ns-1", + }, + }, + Data: map[string][]byte{ + "api_key": []byte("key"), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := buildAutoOpsESAPIKeySecret(tt.policy, tt.es, tt.secretName, tt.encodedKey, tt.expectedHash) + if !cmp.Equal(got, tt.want) { + t.Errorf("buildAutoOpsESAPIKeySecret() diff = %v", cmp.Diff(got, tt.want)) + } + }) + } +} diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 6a75cf40e34..808538494f4 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -52,7 +52,7 @@ func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.N func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedName) (*Config, error) { var config Config - if data, exists := secret.Data[CCMApiKey]; exists { + if data, exists := secret.Data[CCMApiKey]; exists && len(data) > 0 { config.CCMApiKey = string(data) } else { return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", CCMApiKey, secretKey.Namespace, secretKey.Name) @@ -64,13 +64,13 @@ func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedN // return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", TempResourceID, secretKey.Namespace, secretKey.Name) // } - if data, exists := secret.Data[AutoOpsOTelURL]; exists { + if data, exists := secret.Data[AutoOpsOTelURL]; exists && len(data) > 0 { config.AutoOpsOTelURL = string(data) } else { return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsOTelURL, secretKey.Namespace, secretKey.Name) } - if data, exists := secret.Data[AutoOpsToken]; exists { + if data, exists := secret.Data[AutoOpsToken]; exists && len(data) > 0 { config.AutoOpsToken = string(data) } else { return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsToken, secretKey.Namespace, secretKey.Name) diff --git a/pkg/controller/autoops/configuration_test.go b/pkg/controller/autoops/configuration_test.go new file mode 100644 index 00000000000..8a6e24bee43 --- /dev/null +++ b/pkg/controller/autoops/configuration_test.go @@ -0,0 +1,182 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func Test_validateAndPopulateConfig(t *testing.T) { + tests := []struct { + name string + secret corev1.Secret + secretKey types.NamespacedName + want *Config + wantErr bool + }{ + { + name: "valid config with all required fields", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + CCMApiKey: []byte("ccm-api-key-value"), + AutoOpsOTelURL: []byte("https://otel.example.com"), + AutoOpsToken: []byte("token-value"), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: &Config{ + CCMApiKey: "ccm-api-key-value", + AutoOpsOTelURL: "https://otel.example.com", + AutoOpsToken: "token-value", + }, + wantErr: false, + }, + { + name: "missing CCMApiKey returns an error", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + AutoOpsOTelURL: []byte("https://otel.example.com"), + AutoOpsToken: []byte("token-value"), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "missing AutoOpsOTelURL returns an error", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + CCMApiKey: []byte("ccm-api-key-value"), + AutoOpsToken: []byte("token-value"), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "missing AutoOpsToken returns an error", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + CCMApiKey: []byte("ccm-api-key-value"), + AutoOpsOTelURL: []byte("https://otel.example.com"), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "empty values are not allowed", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + CCMApiKey: []byte(""), + AutoOpsOTelURL: []byte(""), + AutoOpsToken: []byte(""), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "empty secret data returns an error", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{}, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "nil secret data returns an error", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: nil, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: nil, + wantErr: true, + }, + { + name: "extra fields are ignored", + secret: corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + CCMApiKey: []byte("ccm-api-key-value"), + AutoOpsOTelURL: []byte("https://otel.example.com"), + AutoOpsToken: []byte("token-value"), + "extra-field": []byte("extra-value"), + }, + }, + secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, + want: &Config{ + CCMApiKey: "ccm-api-key-value", + AutoOpsOTelURL: "https://otel.example.com", + AutoOpsToken: "token-value", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := validateAndPopulateConfig(tt.secret, tt.secretKey) + if (err != nil) != tt.wantErr { + t.Errorf("validateAndPopulateConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr { + if got == nil { + t.Errorf("validateAndPopulateConfig() got = nil, want %v", tt.want) + return + } + if got.CCMApiKey != tt.want.CCMApiKey { + t.Errorf("validateAndPopulateConfig() CCMApiKey = %v, want %v", got.CCMApiKey, tt.want.CCMApiKey) + } + if got.AutoOpsOTelURL != tt.want.AutoOpsOTelURL { + t.Errorf("validateAndPopulateConfig() AutoOpsOTelURL = %v, want %v", got.AutoOpsOTelURL, tt.want.AutoOpsOTelURL) + } + if got.AutoOpsToken != tt.want.AutoOpsToken { + t.Errorf("validateAndPopulateConfig() AutoOpsToken = %v, want %v", got.AutoOpsToken, tt.want.AutoOpsToken) + } + } + }) + } +} diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 56ebd989250..08000768a70 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -15,6 +15,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/record" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -22,6 +23,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common" commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" @@ -197,13 +199,49 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatus(ctx context.Context, policy a func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() + log := ulog.FromContext(ctx).WithValues("policy_namespace", obj.Namespace, "policy_name", obj.Name) + log.Info("Cleaning up AutoOpsAgentPolicy resources") + // Remove dynamic watches on secrets r.dynamicWatches.Secrets.RemoveHandlerForKey(configSecretWatchName(obj)) - // (TODO) // Cleanup API keys for all Elasticsearch clusters that match this policy. - // If we label the secrets created from the policy properly, we can query - // for these, and properly delete the api keys. + // Query for secrets labeled with this policy to find all associated ES clusters. + var secrets corev1.SecretList + matchLabels := client.MatchingLabels{ + policyNameLabelKey: obj.Name, + policyNamespaceLabelKey: obj.Namespace, + } + if err := r.Client.List(ctx, &secrets, matchLabels); err != nil { + return tracing.CaptureError(ctx, fmt.Errorf("while listing secrets for policy %s/%s: %w", obj.Namespace, obj.Name, err)) + } + + // Cleanup API keys for each ES cluster referenced by the secrets + for _, secret := range secrets.Items { + esName, hasESName := secret.Labels["elasticsearch.k8s.elastic.co/name"] + esNamespace, hasESNamespace := secret.Labels["elasticsearch.k8s.elastic.co/namespace"] + if !hasESName || !hasESNamespace { + log.V(1).Info("Secret missing ES cluster labels, skipping", "secret", secret.Name) + continue + } + + var es esv1.Elasticsearch + if err := r.Client.Get(ctx, types.NamespacedName{Namespace: esNamespace, Name: esName}, &es); err != nil { + if apierrors.IsNotFound(err) { + log.V(1).Info("Elasticsearch cluster not found, skipping cleanup", "es_namespace", esNamespace, "es_name", esName) + continue + } + log.Error(err, "Failed to get Elasticsearch cluster", "es_namespace", esNamespace, "es_name", esName) + continue + } + + if err := cleanupAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, obj.Namespace, obj.Name, es); err != nil { + log.Error(err, "Failed to cleanup API key for Elasticsearch cluster", "es_namespace", esNamespace, "es_name", esName) + continue + } + log.V(1).Info("Successfully cleaned up API key", "es_namespace", esNamespace, "es_name", esName) + } + return nil } diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go new file mode 100644 index 00000000000..84f9873177f --- /dev/null +++ b/pkg/controller/autoops/controller_test.go @@ -0,0 +1,297 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" + esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + netutil "github.com/elastic/cloud-on-k8s/v3/pkg/utils/net" +) + +// fakeESClientProvider provides a fake ES client +type fakeESClientProvider struct { + client *fakeESClient +} + +func newFakeESClientProvider() *fakeESClientProvider { + return &fakeESClientProvider{ + client: &fakeESClient{}, + } +} + +func (f *fakeESClientProvider) Provider(ctx context.Context, c k8s.Client, dialer netutil.Dialer, es esv1.Elasticsearch) (esclient.Client, error) { + return f.client, nil +} + +type fakeESClient struct { + esclient.Client +} + +func (f *fakeESClient) Close() { +} + +func (f *fakeESClient) GetAPIKeysByName(ctx context.Context, name string) (esclient.APIKeyList, error) { + return esclient.APIKeyList{APIKeys: []esclient.APIKey{}}, nil +} + +func (f *fakeESClient) InvalidateAPIKeys(ctx context.Context, req esclient.APIKeysInvalidateRequest) (esclient.APIKeysInvalidateResponse, error) { + return esclient.APIKeysInvalidateResponse{}, nil +} + +type fakeDialer struct{} + +func (f *fakeDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + return nil, nil +} + +func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { + tests := []struct { + name string + policy types.NamespacedName + secrets []corev1.Secret + esClusters []esv1.Elasticsearch + wantErr bool + }{ + { + name: "cleanup API keys for single ES cluster", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + Data: map[string][]byte{ + "api_key": []byte("test-key"), + }, + }, + }, + esClusters: []esv1.Elasticsearch{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + }, + wantErr: false, + }, + { + name: "cleanup API keys for multiple ES clusters", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + Data: map[string][]byte{ + "api_key": []byte("test-key-1"), + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-2-ns-3-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + "autoops.k8s.elastic.co/policy-name": "policy-1", + "autoops.k8s.elastic.co/policy-namespace": "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-2", + "elasticsearch.k8s.elastic.co/namespace": "ns-3", + }, + }, + Data: map[string][]byte{ + "api_key": []byte("test-key-2"), + }, + }, + }, + esClusters: []esv1.Elasticsearch{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-2", + Namespace: "ns-3", + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + }, + wantErr: false, + }, + { + name: "skip secrets without ES cluster labels", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "secret-without-labels", + Namespace: "ns-1", + Labels: map[string]string{ + "autoops.k8s.elastic.co/policy-name": "policy-1", + "autoops.k8s.elastic.co/policy-namespace": "ns-1", + // Missing ES cluster labels + }, + }, + }, + }, + esClusters: []esv1.Elasticsearch{}, + wantErr: false, + }, + { + name: "skip ES cluster that is not found", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + }, + }, + esClusters: []esv1.Elasticsearch{}, + wantErr: false, + }, + { + name: "deduplicate ES clusters from multiple secrets", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key-duplicate", + Namespace: "ns-1", + Labels: map[string]string{ + policyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + }, + }, + esClusters: []esv1.Elasticsearch{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + objects := make([]client.Object, 0) + for i := range tt.secrets { + objects = append(objects, &tt.secrets[i]) + } + for i := range tt.esClusters { + objects = append(objects, &tt.esClusters[i]) + } + + k8sClient := k8s.NewFakeClient(objects...) + esClientProvider := newFakeESClientProvider() + + r := &ReconcileAutoOpsAgentPolicy{ + Client: k8sClient, + esClientProvider: esClientProvider.Provider, + params: operator.Parameters{ + Dialer: &fakeDialer{}, + }, + dynamicWatches: watches.NewDynamicWatches(), + } + + ctx := context.Background() + err := r.onDelete(ctx, tt.policy) + + require.Equal(t, tt.wantErr, err != nil) + + for _, es := range tt.esClusters { + if es.Status.Phase == esv1.ElasticsearchReadyPhase { + expectedSecretName := apiKeySecretNameFrom(es) + var retrievedSecret corev1.Secret + err := k8sClient.Get(ctx, types.NamespacedName{Namespace: tt.policy.Namespace, Name: expectedSecretName}, &retrievedSecret) + assert.True(t, apierrors.IsNotFound(err), "Expected secret %s/%s to be deleted", tt.policy.Namespace, expectedSecretName) + } + } + }) + } +} diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index d9d477f70c3..176c8664e13 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -331,7 +331,7 @@ func Test_autoopsEnvVars(t *testing.T) { want []corev1.EnvVar }{ { - name: "basic ES instance", + name: "Happy path", es: esv1.Elasticsearch{ ObjectMeta: metav1.ObjectMeta{ Name: "es-1", @@ -402,78 +402,6 @@ func Test_autoopsEnvVars(t *testing.T) { }, }, }, - { - name: "ES instance with different namespace", - es: esv1.Elasticsearch{ - ObjectMeta: metav1.ObjectMeta{ - Name: "es-cluster", - Namespace: "elastic-system", - }, - }, - want: []corev1.EnvVar{ - { - Name: "AUTOOPS_TOKEN", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "autoops-token", - }, - }, - }, - { - Name: "AUTOOPS_ES_URL", - Value: "http://es-cluster-es-internal-http.elastic-system.svc:9200", - }, - { - Name: "AUTOOPS_OTEL_URL", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "autoops-otel-url", - }, - }, - }, - { - Name: "AUTOOPS_ES_API_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "es-cluster-elastic-system-autoops-es-api-key", - }, - Key: "api_key", - Optional: ptr.To(false), - }, - }, - }, - { - Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "cloud-connected-mode-api-key", - }, - }, - }, - { - Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_URL", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", - }, - Key: "cloud-connected-mode-api-url", - Optional: ptr.To(true), - }, - }, - }, - }, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 7fe657e2120..42f455c7a4e 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -44,7 +44,6 @@ func reconcileAutoOpsESCASecret( return nil } - // Get the source secret: {es-name}-es-http-ca-internal sourceSecretKey := types.NamespacedName{ Namespace: es.Namespace, Name: fmt.Sprintf("%s-es-http-ca-internal", es.Name), @@ -58,14 +57,12 @@ func reconcileAutoOpsESCASecret( return fmt.Errorf("while retrieving http-ca-internal secret for ES cluster %s/%s: %w", es.Namespace, es.Name, err) } - // Extract tls.crt from the source secret caCert, ok := sourceSecret.Data["tls.crt"] if !ok || len(caCert) == 0 { log.V(1).Info("tls.crt not found in http-ca-internal secret, skipping", "namespace", es.Namespace, "name", es.Name) return nil } - // Create secret name: {es-name}-{es-namespace}-es-ca secretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretPrefix) expected := buildAutoOpsESCASecret(policy, es, secretName, caCert) @@ -93,6 +90,10 @@ func reconcileAutoOpsESCASecret( // buildAutoOpsESCASecret builds the expected Secret for autoops ES CA certificate. func buildAutoOpsESCASecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, secretName string, caCert []byte) corev1.Secret { + if len(caCert) == 0 { + return corev1.Secret{} + } + meta := metadata.Propagate(&policy, metadata.Metadata{ Labels: policy.GetLabels(), Annotations: policy.GetAnnotations(), From d77a53b44e862ed92fe98d3dd68fe44bf84420d1 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 14:42:36 -0600 Subject: [PATCH 15/90] make generate Signed-off-by: Michael Montgomery --- NOTICE.txt | 332 ++++++++++++++++++++++++++--------------------------- 1 file changed, 166 insertions(+), 166 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index db1ba5c7acf..6563a50cf69 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -14,7 +14,7 @@ Version : v1.0.2 Time : 2025-05-07T20:15:06Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/dario.cat/mergo@v1.0.2/LICENSE: +Contents of probable licence file $GOMODCACHE/dario.cat/mergo@v1.0.2/LICENSE: Copyright (c) 2013 Dario Castañé. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -83,7 +83,7 @@ Version : v3.3.0 Time : 2024-08-29T20:12:44Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/!masterminds/sprig/v3@v3.3.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -112,7 +112,7 @@ Version : v4.0.0 Time : 2020-05-24T15:15:11Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/blang/semver/v4@v4.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/blang/semver/v4@v4.0.0/LICENSE: The MIT License @@ -144,7 +144,7 @@ Version : v1.1.2-0.20180830191138-d8f796af33cc Time : 2018-08-30T19:11:38Z Licence : ISC -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: ISC License @@ -380,7 +380,7 @@ Version : v1.0.0 Time : 2017-03-27T23:54:44Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/ghodss/yaml@v1.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/ghodss/yaml@v1.0.0/LICENSE: The MIT License (MIT) @@ -471,7 +471,7 @@ Version : v1.4.3 Time : 2025-05-19T04:56:57Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/logr@v1.4.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v1.4.3/LICENSE: Apache License Version 2.0, January 2004 @@ -682,7 +682,7 @@ Version : v1.1.1 Time : 2024-06-23T16:27:23Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-test/deep@v1.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-test/deep@v1.1.1/LICENSE: MIT License @@ -713,7 +713,7 @@ Version : v1.0.3 Time : 2024-09-21T13:43:45Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gobuffalo/flect@v1.0.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gobuffalo/flect@v1.0.3/LICENSE: The MIT License (MIT) @@ -744,7 +744,7 @@ Version : v0.7.0 Time : 2025-01-14T18:15:44Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/go-cmp@v0.7.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/go-cmp@v0.7.0/LICENSE: Copyright (c) 2017 The Go Authors. All rights reserved. @@ -781,7 +781,7 @@ Version : v0.20.6 Time : 2025-06-13T21:51:07Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/go-containerregistry@v0.20.6/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/go-containerregistry@v0.20.6/LICENSE: Apache License @@ -992,7 +992,7 @@ Version : v1.6.0 Time : 2024-01-23T18:54:04Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/uuid@v1.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/uuid@v1.6.0/LICENSE: Copyright (c) 2009,2014 Google Inc. All rights reserved. @@ -1029,7 +1029,7 @@ Version : v1.1.1 Time : 2021-03-11T20:17:12Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: Mozilla Public License, version 2.0 @@ -1392,7 +1392,7 @@ Version : v2.0.7 Time : 2023-09-21T18:26:40Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/golang-lru/v2@v2.0.7/LICENSE: Copyright (c) 2014 HashiCorp, Inc. @@ -2141,7 +2141,7 @@ Version : v1.8.10 Time : 2025-04-09T19:30:57Z Licence : BSD-2-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/magiconair/properties@v1.8.10/LICENSE.md: +Contents of probable licence file $GOMODCACHE/github.com/magiconair/properties@v1.8.10/LICENSE.md: Copyright (c) 2013-2020, Frank Schroeder @@ -2175,7 +2175,7 @@ Version : v0.9.1 Time : 2020-01-14T19:47:44Z Licence : BSD-2-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pkg/errors@v0.9.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/pkg/errors@v0.9.1/LICENSE: Copyright (c) 2015, Dave Cheney All rights reserved. @@ -2208,7 +2208,7 @@ Version : v1.0.1-0.20181226105442-5d4384ee4fb2 Time : 2018-12-26T10:54:42Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: Copyright (c) 2013, Patrick Mezard All rights reserved. @@ -2245,7 +2245,7 @@ Version : v1.23.2 Time : 2025-09-05T14:03:59Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/client_golang@v1.23.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golang@v1.23.2/LICENSE: Apache License Version 2.0, January 2004 @@ -2667,7 +2667,7 @@ Version : v1.10.1 Time : 2025-09-01T16:19:51Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/cobra@v1.10.1/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/spf13/cobra@v1.10.1/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -2851,7 +2851,7 @@ Version : v1.0.10 Time : 2025-09-02T06:08:29Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/pflag@v1.0.10/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/spf13/pflag@v1.0.10/LICENSE: Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. @@ -2889,7 +2889,7 @@ Version : v1.21.0 Time : 2025-09-08T16:56:14Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/viper@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/spf13/viper@v1.21.0/LICENSE: The MIT License (MIT) @@ -2919,7 +2919,7 @@ Version : v1.11.1 Time : 2025-08-27T10:46:31Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stretchr/testify@v1.11.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/stretchr/testify@v1.11.1/LICENSE: MIT License @@ -3794,7 +3794,7 @@ Version : v1.6.0 Time : 2024-09-23T17:47:22Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/automaxprocs@v1.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.uber.org/automaxprocs@v1.6.0/LICENSE: Copyright (c) 2017 Uber Technologies, Inc. @@ -3822,7 +3822,7 @@ Version : v1.27.0 Time : 2024-02-20T20:55:06Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.27.0/LICENSE: Copyright (c) 2016-2017 Uber Technologies, Inc. @@ -3888,7 +3888,7 @@ Version : v0.0.0-20240808152545-0cdaa3abc0fa Time : 2024-08-08T15:25:45Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/exp@v0.0.0-20240808152545-0cdaa3abc0fa/LICENSE: Copyright 2009 The Go Authors. @@ -3925,7 +3925,7 @@ Version : v3.0.1 Time : 2022-05-27T08:35:30Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/yaml.v3@v3.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v3@v3.0.1/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -3985,7 +3985,7 @@ Version : v0.34.1 Time : 2025-09-10T04:39:36Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/api@v0.34.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/api@v0.34.1/LICENSE: Apache License @@ -4197,7 +4197,7 @@ Version : v0.34.1 Time : 2025-08-16T07:57:26Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/apimachinery@v0.34.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/apimachinery@v0.34.1/LICENSE: Apache License @@ -4409,7 +4409,7 @@ Version : v0.34.1 Time : 2025-09-10T04:55:33Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/client-go@v0.34.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/client-go@v0.34.1/LICENSE: Apache License @@ -4621,7 +4621,7 @@ Version : v2.130.1 Time : 2024-06-20T00:51:19Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/klog/v2@v2.130.1/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/klog/v2@v2.130.1/LICENSE: Apache License Version 2.0, January 2004 @@ -4822,7 +4822,7 @@ Version : v0.0.0-20250604170112-4c0f3b243397 Time : 2025-06-04T17:01:12Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/utils@v0.0.0-20250604170112-4c0f3b243397/LICENSE: Apache License @@ -5245,7 +5245,7 @@ Version : v0.19.0 Time : 2025-08-28T05:51:10Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/controller-tools@v0.19.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5462,7 +5462,7 @@ Version : v0.24.0 Time : 2025-05-07T15:31:15Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/cel.dev/expr@v0.24.0/LICENSE: +Contents of probable licence file $GOMODCACHE/cel.dev/expr@v0.24.0/LICENSE: Apache License @@ -5674,7 +5674,7 @@ Version : v1.1.1 Time : 2021-02-04T20:06:53Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/!masterminds/goutils@v1.1.1/LICENSE.txt: Apache License @@ -5886,7 +5886,7 @@ Version : v3.3.0 Time : 2024-08-27T21:33:28Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/!masterminds/semver/v3@v3.3.0/LICENSE.txt: Copyright (C) 2014-2019, Matt Butcher and Matt Farina @@ -5915,7 +5915,7 @@ Version : v4.13.0 Time : 2023-05-19T05:49:53Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/antlr4-go/antlr/v4@v4.13.0/LICENSE: Copyright (c) 2012-2023 The ANTLR Project. All rights reserved. @@ -5953,7 +5953,7 @@ Version : v1.0.0 Time : 2018-08-24T02:57:28Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/armon/go-radix@v1.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/armon/go-radix@v1.0.0/LICENSE: The MIT License (MIT) @@ -5983,7 +5983,7 @@ Version : v0.0.0-20160902184237-e75332964ef5 Time : 2016-09-02T18:42:37Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/armon/go-socks5@v0.0.0-20160902184237-e75332964ef5/LICENSE: The MIT License (MIT) @@ -6013,7 +6013,7 @@ Version : v1.0.1 Time : 2019-07-31T12:00:54Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/beorn7/perks@v1.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/beorn7/perks@v1.0.1/LICENSE: Copyright (C) 2013 Blake Mizerany @@ -6043,7 +6043,7 @@ Version : v4.3.0 Time : 2024-01-02T22:56:19Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/cenkalti/backoff/v4@v4.3.0/LICENSE: The MIT License (MIT) @@ -6073,7 +6073,7 @@ Version : v2.3.0 Time : 2024-04-04T20:00:10Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/cespare/xxhash/v2@v2.3.0/LICENSE.txt: Copyright (c) 2016 Caleb Spare @@ -6105,7 +6105,7 @@ Version : v0.16.3 Time : 2024-12-12T14:42:49Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/containerd/stargz-snapshotter/estargz@v0.16.3/LICENSE: Apache License @@ -6317,7 +6317,7 @@ Version : v28.2.2+incompatible Time : 2025-05-30T09:39:08Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/cli@v28.2.2+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/docker/cli@v28.2.2+incompatible/LICENSE: Apache License @@ -6518,7 +6518,7 @@ Version : v2.8.3+incompatible Time : 2023-10-02T17:09:30Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/docker/distribution@v2.8.3+incompatible/LICENSE: Apache License Version 2.0, January 2004 @@ -6730,7 +6730,7 @@ Version : v0.9.3 Time : 2025-03-14T11:52:36Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/docker/docker-credential-helpers@v0.9.3/LICENSE: Copyright (c) 2016 David Calavera @@ -6760,7 +6760,7 @@ Version : v1.15.2 Time : 2025-03-25T02:52:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.15.2/LICENSE.txt: Apache License @@ -6972,7 +6972,7 @@ Version : v1.0.2 Time : 2024-03-25T02:36:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-windows@v1.0.2/LICENSE.txt: Apache License @@ -7184,7 +7184,7 @@ Version : v3.12.2 Time : 2025-02-26T09:20:34Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/emicklei/go-restful/v3@v3.12.2/LICENSE: Copyright (c) 2012,2013 Ernest Micklei @@ -7215,7 +7215,7 @@ Version : v5.6.0+incompatible Time : 2021-10-20T18:47:23Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch@v5.6.0+incompatible/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7250,7 +7250,7 @@ Version : v5.9.11 Time : 2025-01-28T17:43:52Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/evanphx/json-patch/v5@v5.9.11/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -7285,7 +7285,7 @@ Version : v1.18.0 Time : 2024-10-03T07:06:28Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fatih/color@v1.18.0/LICENSE.md: +Contents of probable licence file $GOMODCACHE/github.com/fatih/color@v1.18.0/LICENSE.md: The MIT License (MIT) @@ -7315,7 +7315,7 @@ Version : v1.0.4 Time : 2023-03-12T10:31:09Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/felixge/httpsnoop@v1.0.4/LICENSE.txt: Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) @@ -7344,7 +7344,7 @@ Version : v1.14.6 Time : 2023-08-01T06:27:26Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/frankban/quicktest@v1.14.6/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/frankban/quicktest@v1.14.6/LICENSE: MIT License @@ -7375,7 +7375,7 @@ Version : v1.9.0 Time : 2025-04-04T15:13:49Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/fsnotify/fsnotify@v1.9.0/LICENSE: Copyright © 2012 The Go Authors. All rights reserved. Copyright © fsnotify Authors. All rights reserved. @@ -7410,7 +7410,7 @@ Version : v2.9.0 Time : 2025-07-14T04:00:34Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/fxamacker/cbor/v2@v2.9.0/LICENSE: MIT License @@ -7440,7 +7440,7 @@ Version : v0.3.2 Time : 2025-02-02T10:01:22Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gkampitakis/ciinfo@v0.3.2/LICENSE: MIT License @@ -7471,7 +7471,7 @@ Version : v1.3.2 Time : 2023-02-18T11:30:13Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gkampitakis/go-diff@v1.3.2/LICENSE: Copyright (c) 2012-2016 The go-diff Authors. All rights reserved. @@ -7501,7 +7501,7 @@ Version : v4.1.1 Time : 2025-06-23T23:41:10Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-jose/go-jose/v4@v4.1.1/LICENSE: Apache License @@ -7713,7 +7713,7 @@ Version : v1.2.2 Time : 2021-12-14T08:00:35Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/stdr@v1.2.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-logr/stdr@v1.2.2/LICENSE: Apache License Version 2.0, January 2004 @@ -7924,7 +7924,7 @@ Version : v1.3.0 Time : 2023-11-03T09:58:42Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-logr/zapr@v1.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-logr/zapr@v1.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -8135,7 +8135,7 @@ Version : v0.21.0 Time : 2024-03-09T18:18:34Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-openapi/jsonpointer@v0.21.0/LICENSE: Apache License @@ -8347,7 +8347,7 @@ Version : v0.21.0 Time : 2024-03-09T18:23:36Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-openapi/jsonreference@v0.21.0/LICENSE: Apache License @@ -8559,7 +8559,7 @@ Version : v0.23.0 Time : 2024-03-09T18:11:11Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-openapi/swag@v0.23.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-openapi/swag@v0.23.0/LICENSE: Apache License @@ -8771,7 +8771,7 @@ Version : v3.0.0 Time : 2023-09-14T01:46:41Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/go-task/slim-sprig/v3@v3.0.0/LICENSE.txt: Copyright (C) 2013-2020 Masterminds @@ -8800,7 +8800,7 @@ Version : v2.4.0 Time : 2025-07-15T08:59:08Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-viper/mapstructure/v2@v2.4.0/LICENSE: The MIT License (MIT) @@ -8831,7 +8831,7 @@ Version : v1.18.0 Time : 2025-05-29T05:13:29Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/goccy/go-yaml@v1.18.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/goccy/go-yaml@v1.18.0/LICENSE: MIT License @@ -8862,7 +8862,7 @@ Version : v1.3.2 Time : 2021-01-10T08:01:47Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gogo/protobuf@v1.3.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gogo/protobuf@v1.3.2/LICENSE: Copyright (c) 2013, The GoGo Authors. All rights reserved. @@ -8907,7 +8907,7 @@ Version : v1.5.4 Time : 2024-03-06T06:45:40Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/golang/protobuf@v1.5.4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/golang/protobuf@v1.5.4/LICENSE: Copyright 2010 The Go Authors. All rights reserved. @@ -8945,7 +8945,7 @@ Version : v1.1.3 Time : 2024-08-21T16:26:17Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/btree@v1.1.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/btree@v1.1.3/LICENSE: Apache License @@ -9157,7 +9157,7 @@ Version : v0.26.0 Time : 2025-07-14T20:45:46Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/cel-go@v0.26.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/cel-go@v0.26.0/LICENSE: Apache License @@ -9400,7 +9400,7 @@ Version : v0.7.0 Time : 2025-06-26T15:23:00Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/gnostic-models@v0.7.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/gnostic-models@v0.7.0/LICENSE: Apache License @@ -9613,7 +9613,7 @@ Version : v1.2.0 Time : 2020-08-04T22:43:24Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/gofuzz@v1.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/gofuzz@v1.2.0/LICENSE: Apache License @@ -9825,7 +9825,7 @@ Version : v0.0.0-20241029153458-d1b30febd7db Time : 2024-10-29T15:34:58Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/pprof@v0.0.0-20241029153458-d1b30febd7db/LICENSE: Apache License @@ -10037,7 +10037,7 @@ Version : v1.5.4-0.20250319132907-e064f32e3674 Time : 2025-03-19T13:29:07Z Licence : BSD-2-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gorilla/websocket@v1.5.4-0.20250319132907-e064f32e3674/LICENSE: Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. @@ -10069,7 +10069,7 @@ Version : v2.26.3 Time : 2025-03-04T17:40:45Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3/LICENSE: Copyright (c) 2015, Gengo, Inc. All rights reserved. @@ -10106,7 +10106,7 @@ Version : v1.1.0 Time : 2020-07-14T15:51:01Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/errwrap@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/errwrap@v1.1.0/LICENSE: Mozilla Public License, version 2.0 @@ -10470,7 +10470,7 @@ Version : v0.5.2 Time : 2021-02-03T18:51:13Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-cleanhttp@v0.5.2/LICENSE: Mozilla Public License, version 2.0 @@ -10843,7 +10843,7 @@ Version : v1.6.3 Time : 2024-04-01T20:03:54Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-hclog@v1.6.3/LICENSE: Copyright (c) 2017 HashiCorp, Inc. @@ -10872,7 +10872,7 @@ Version : v0.7.8 Time : 2025-06-18T14:25:10Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-retryablehttp@v0.7.8/LICENSE: Copyright (c) 2015 HashiCorp, Inc. @@ -11247,7 +11247,7 @@ Version : v1.0.2 Time : 2019-12-10T09:55:28Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-rootcerts@v1.0.2/LICENSE: Mozilla Public License, version 2.0 @@ -11620,7 +11620,7 @@ Version : v0.2.0 Time : 2025-03-06T22:34:24Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0/LICENSE: Copyright (c) 2020 HashiCorp, Inc. @@ -11995,7 +11995,7 @@ Version : v0.1.2 Time : 2021-11-22T19:44:14Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2/LICENSE: Mozilla Public License, version 2.0 @@ -12368,7 +12368,7 @@ Version : v1.0.7 Time : 2024-09-19T09:47:04Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-sockaddr@v1.0.7/LICENSE: Copyright (c) 2016 HashiCorp, Inc. @@ -12753,7 +12753,7 @@ Version : v1.0.1-vault-7 Time : 2024-11-07T22:23:56Z Licence : MPL-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/hcl@v1.0.1-vault-7/LICENSE: Mozilla Public License, version 2.0 @@ -13117,7 +13117,7 @@ Version : v1.5.0 Time : 2024-06-06T08:07:36Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/huandu/xstrings@v1.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/huandu/xstrings@v1.5.0/LICENSE: The MIT License (MIT) @@ -13149,7 +13149,7 @@ Version : v1.1.0 Time : 2022-11-27T22:01:53Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -13360,7 +13360,7 @@ Version : v1.0.0 Time : 2019-12-14T22:12:22Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/josharian/intern@v1.0.0/license.md: +Contents of probable licence file $GOMODCACHE/github.com/josharian/intern@v1.0.0/license.md: MIT License @@ -13391,7 +13391,7 @@ Version : v1.1.12 Time : 2021-09-11T02:17:26Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/json-iterator/go@v1.1.12/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.12/LICENSE: MIT License @@ -13422,7 +13422,7 @@ Version : v1.18.0 Time : 2025-02-19T09:26:03Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/klauspost/compress@v1.18.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/klauspost/compress@v1.18.0/LICENSE: Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. @@ -13736,7 +13736,7 @@ Version : v0.3.1 Time : 2022-08-29T23:03:05Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kr/pretty@v0.3.1/License: +Contents of probable licence file $GOMODCACHE/github.com/kr/pretty@v0.3.1/License: Copyright 2012 Keith Rarick @@ -13765,7 +13765,7 @@ Version : v0.2.0 Time : 2020-02-14T20:31:06Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kr/text@v0.2.0/License: +Contents of probable licence file $GOMODCACHE/github.com/kr/text@v0.2.0/License: Copyright 2012 Keith Rarick @@ -13794,7 +13794,7 @@ Version : v1.1.0 Time : 2019-05-05T01:16:37Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/kylelemons/godebug@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/kylelemons/godebug@v1.1.0/LICENSE: Apache License @@ -14006,7 +14006,7 @@ Version : v0.7.7 Time : 2021-02-06T19:00:08Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mailru/easyjson@v0.7.7/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mailru/easyjson@v0.7.7/LICENSE: Copyright (c) 2016 Mail.Ru Group @@ -14023,7 +14023,7 @@ Version : v1.1.1 Time : 2023-11-03T01:37:02Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/maruel/natural@v1.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/maruel/natural@v1.1.1/LICENSE: Apache License Version 2.0, January 2004 @@ -14234,7 +14234,7 @@ Version : v0.1.14 Time : 2025-01-10T08:29:27Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mattn/go-colorable@v0.1.14/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mattn/go-colorable@v0.1.14/LICENSE: The MIT License (MIT) @@ -14265,7 +14265,7 @@ Version : v0.0.20 Time : 2023-10-17T07:28:21Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mattn/go-isatty@v0.0.20/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mattn/go-isatty@v0.0.20/LICENSE: Copyright (c) Yasuhiro MATSUMOTO @@ -14284,7 +14284,7 @@ Version : v1.2.0 Time : 2021-05-05T17:08:07Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/copystructure@v1.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/copystructure@v1.2.0/LICENSE: The MIT License (MIT) @@ -14315,7 +14315,7 @@ Version : v1.1.0 Time : 2019-01-27T04:21:35Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/go-homedir@v1.1.0/LICENSE: The MIT License (MIT) @@ -14346,7 +14346,7 @@ Version : v1.5.0 Time : 2022-04-20T22:31:31Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/mapstructure@v1.5.0/LICENSE: The MIT License (MIT) @@ -14377,7 +14377,7 @@ Version : v1.0.2 Time : 2021-05-03T23:34:11Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/reflectwalk@v1.0.2/LICENSE: The MIT License (MIT) @@ -14408,7 +14408,7 @@ Version : v0.5.0 Time : 2024-07-23T13:25:06Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/moby/spdystream@v0.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/moby/spdystream@v0.5.0/LICENSE: Apache License @@ -14620,7 +14620,7 @@ Version : v0.0.0-20180306012644-bacd9c7ef1dd Time : 2018-03-06T01:26:44Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: Apache License Version 2.0, January 2004 @@ -14831,7 +14831,7 @@ Version : v1.0.3-0.20250322232337-35a7c28c31ee Time : 2025-03-22T23:23:37Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.3-0.20250322232337-35a7c28c31ee/LICENSE: Apache License Version 2.0, January 2004 @@ -15083,7 +15083,7 @@ Version : v0.0.0-20140419014527-cca7078d478f Time : 2014-04-19T01:45:27Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mxk/go-flowrate@v0.0.0-20140419014527-cca7078d478f/LICENSE: Copyright (c) 2014 The Go-FlowRate Authors. All rights reserved. @@ -15122,7 +15122,7 @@ Version : v1.4.8 Time : 2021-02-07T16:08:07Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/nxadm/tail@v1.4.8/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/nxadm/tail@v1.4.8/LICENSE: # The MIT License (MIT) @@ -15153,7 +15153,7 @@ Version : v1.16.5 Time : 2021-10-11T17:27:58Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/ginkgo@v1.16.5/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo@v1.16.5/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15183,7 +15183,7 @@ Version : v2.22.0 Time : 2024-11-21T01:19:21Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/onsi/ginkgo/v2@v2.22.0/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15213,7 +15213,7 @@ Version : v1.38.1 Time : 2025-08-22T13:45:44Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/onsi/gomega@v1.38.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/onsi/gomega@v1.38.1/LICENSE: Copyright (c) 2013-2014 Onsi Fakhouri @@ -15243,7 +15243,7 @@ Version : v1.0.0 Time : 2020-05-14T01:46:00Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/opencontainers/go-digest@v1.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/opencontainers/go-digest@v1.0.0/LICENSE: Apache License @@ -15445,7 +15445,7 @@ Version : v1.1.1 Time : 2025-02-24T17:26:57Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/opencontainers/image-spec@v1.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/opencontainers/image-spec@v1.1.1/LICENSE: Apache License @@ -15646,7 +15646,7 @@ Version : v0.0.0-20210728143218-7b4eea64cf58 Time : 2021-07-28T14:32:18Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: BSD 3-Clause License @@ -15685,7 +15685,7 @@ Version : v2.2.4 Time : 2025-04-07T11:11:38Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/pelletier/go-toml/v2@v2.2.4/LICENSE: The MIT License (MIT) @@ -15717,7 +15717,7 @@ Version : v1.1.0 Time : 2021-12-11T19:29:36Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prashantv/gostub@v1.1.0/LICENSE.md: +Contents of probable licence file $GOMODCACHE/github.com/prashantv/gostub@v1.1.0/LICENSE.md: The MIT License (MIT) @@ -15748,7 +15748,7 @@ Version : v0.6.2 Time : 2025-04-11T05:38:16Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/client_model@v0.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model@v0.6.2/LICENSE: Apache License Version 2.0, January 2004 @@ -15959,7 +15959,7 @@ Version : v0.16.1 Time : 2025-04-19T15:43:08Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/prometheus/procfs@v0.16.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.16.1/LICENSE: Apache License Version 2.0, January 2004 @@ -16170,7 +16170,7 @@ Version : v1.13.1 Time : 2024-09-23T11:44:11Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: Copyright (c) 2018 The Go Authors. All rights reserved. @@ -16207,7 +16207,7 @@ Version : v1.0.0 Time : 2019-01-24T19:22:32Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/ryanuber/go-glob@v1.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/ryanuber/go-glob@v1.0.0/LICENSE: The MIT License (MIT) @@ -16238,7 +16238,7 @@ Version : v0.11.0 Time : 2025-09-08T16:42:20Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/sagikazarmark/locafero@v0.11.0/LICENSE: Copyright (c) 2023 Márk Sági-Kazár @@ -16267,7 +16267,7 @@ Version : v1.4.0 Time : 2024-04-12T14:15:38Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/shopspring/decimal@v1.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/shopspring/decimal@v1.4.0/LICENSE: The MIT License (MIT) @@ -16322,7 +16322,7 @@ Version : v1.9.3 Time : 2023-05-21T12:59:35Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sirupsen/logrus@v1.9.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/sirupsen/logrus@v1.9.3/LICENSE: The MIT License (MIT) @@ -16353,7 +16353,7 @@ Version : v0.3.1-0.20240121214520-5f936abd7ae8 Time : 2024-01-21T21:45:20Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8/LICENSE: MIT License @@ -16384,7 +16384,7 @@ Version : v1.15.0 Time : 2025-09-08T16:25:29Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/afero@v1.15.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/spf13/afero@v1.15.0/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -16568,7 +16568,7 @@ Version : v1.10.0 Time : 2025-09-08T16:45:31Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/spf13/cast@v1.10.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/spf13/cast@v1.10.0/LICENSE: The MIT License (MIT) @@ -16598,7 +16598,7 @@ Version : v1.3.0 Time : 2023-03-27T23:57:07Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stoewer/go-strcase@v1.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/stoewer/go-strcase@v1.3.0/LICENSE: The MIT License (MIT) @@ -16629,7 +16629,7 @@ Version : v0.5.2 Time : 2024-02-29T09:57:51Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/stretchr/objx@v0.5.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/stretchr/objx@v0.5.2/LICENSE: The MIT License @@ -16661,7 +16661,7 @@ Version : v1.6.0 Time : 2023-08-15T12:05:45Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/subosito/gotenv@v1.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/subosito/gotenv@v1.6.0/LICENSE: The MIT License (MIT) @@ -16692,7 +16692,7 @@ Version : v1.18.0 Time : 2024-10-02T03:45:20Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/gjson@v1.18.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/tidwall/gjson@v1.18.0/LICENSE: The MIT License (MIT) @@ -16722,7 +16722,7 @@ Version : v1.1.1 Time : 2021-10-08T14:36:13Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/match@v1.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/tidwall/match@v1.1.1/LICENSE: The MIT License (MIT) @@ -16752,7 +16752,7 @@ Version : v1.2.1 Time : 2022-10-01T20:21:24Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/pretty@v1.2.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/tidwall/pretty@v1.2.1/LICENSE: The MIT License (MIT) @@ -16782,7 +16782,7 @@ Version : v1.2.5 Time : 2022-08-05T01:15:59Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/tidwall/sjson@v1.2.5/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/tidwall/sjson@v1.2.5/LICENSE: The MIT License (MIT) @@ -16813,7 +16813,7 @@ Version : v0.12.1 Time : 2025-01-30T22:58:54Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/vbatts/tar-split@v0.12.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/vbatts/tar-split@v0.12.1/LICENSE: Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA @@ -16851,7 +16851,7 @@ Version : v0.8.4 Time : 2020-01-17T18:31:28Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/github.com/x448/float16@v0.8.4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/x448/float16@v0.8.4/LICENSE: MIT License @@ -16883,7 +16883,7 @@ Version : v1.5.1 Time : 2025-05-06T14:56:09Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.elastic.co/fastjson@v1.5.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/fastjson@v1.5.1/LICENSE: Copyright 2018 Elasticsearch BV @@ -16916,7 +16916,7 @@ Version : v1.1.0 Time : 2024-12-05T17:49:43Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17127,7 +17127,7 @@ Version : v0.61.0 Time : 2025-05-22T14:29:43Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17338,7 +17338,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel@v1.36.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17549,7 +17549,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17760,7 +17760,7 @@ Version : v1.34.0 Time : 2025-01-17T16:21:54Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17971,7 +17971,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18182,7 +18182,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18393,7 +18393,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18604,7 +18604,7 @@ Version : v1.36.0 Time : 2025-05-21T07:35:39Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.36.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18815,7 +18815,7 @@ Version : v1.5.0 Time : 2025-01-06T12:02:47Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/proto/otlp@v1.5.0/LICENSE: Apache License Version 2.0, January 2004 @@ -19026,7 +19026,7 @@ Version : v1.3.0 Time : 2023-10-24T16:28:03Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/goleak@v1.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.uber.org/goleak@v1.3.0/LICENSE: The MIT License (MIT) @@ -19057,7 +19057,7 @@ Version : v1.11.0 Time : 2023-03-29T23:00:37Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.uber.org/multierr@v1.11.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.11.0/LICENSE.txt: Copyright (c) 2017-2021 Uber Technologies, Inc. @@ -19297,7 +19297,7 @@ Version : v3.0.4 Time : 2025-06-29T14:09:51Z Licence : MIT -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/go.yaml.in/yaml/v3@v3.0.4/LICENSE: +Contents of probable licence file $GOMODCACHE/go.yaml.in/yaml/v3@v3.0.4/LICENSE: This project is covered by two different licenses: MIT and Apache. @@ -19616,7 +19616,7 @@ Version : v0.12.0 Time : 2025-06-04T19:36:50Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/time@v0.12.0/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.12.0/LICENSE: Copyright 2009 The Go Authors. @@ -19690,7 +19690,7 @@ Version : v0.1.0-deprecated Time : 2025-06-12T15:17:39Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/tools/go/expect@v0.1.0-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19727,7 +19727,7 @@ Version : v0.1.1-deprecated Time : 2025-06-13T18:44:18Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated/LICENSE: Copyright 2009 The Go Authors. @@ -19764,7 +19764,7 @@ Version : v2.4.0 Time : 2023-08-14T02:23:48Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/gomodules.xyz/jsonpatch/v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -19976,7 +19976,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20188,7 +20188,7 @@ Version : v0.0.0-20250303144028-a0af3efb3deb Time : 2025-03-03T14:40:28Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: +Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb/LICENSE: Apache License @@ -20400,7 +20400,7 @@ Version : v1.72.1 Time : 2025-05-14T09:00:17Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/google.golang.org/grpc@v1.72.1/LICENSE: +Contents of probable licence file $GOMODCACHE/google.golang.org/grpc@v1.72.1/LICENSE: Apache License @@ -20649,7 +20649,7 @@ Version : v1.0.0-20201130134442-10cb98267c6c Time : 2020-11-30T13:44:42Z Licence : BSD-2-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c/LICENSE: Gocheck - A rich testing framework for Go @@ -20684,7 +20684,7 @@ Version : v4.12.0 Time : 2021-10-21T16:40:42Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/evanphx/json-patch.v4@v4.12.0/LICENSE: Copyright (c) 2014, Evan Phoenix All rights reserved. @@ -20719,7 +20719,7 @@ Version : v0.9.1 Time : 2018-03-26T17:23:32Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/inf.v0@v0.9.1/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/inf.v0@v0.9.1/LICENSE: Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go Authors. All rights reserved. @@ -20757,7 +20757,7 @@ Version : v1.0.0-20141024135613-dd632973f1e7 Time : 2014-10-24T13:56:13Z Licence : BSD-3-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7/LICENSE: tomb - support for clean goroutine termination in Go. @@ -20796,7 +20796,7 @@ Version : v2.4.0 Time : 2020-11-17T15:46:20Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gopkg.in/yaml.v2@v2.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -21007,7 +21007,7 @@ Version : v3.0.3 Time : 2020-09-27T20:53:12Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/gotest.tools/v3@v3.0.3/LICENSE: +Contents of probable licence file $GOMODCACHE/gotest.tools/v3@v3.0.3/LICENSE: Copyright 2018 gotest.tools authors @@ -21030,7 +21030,7 @@ Version : v1.0.1 Time : 2023-10-24T16:34:31Z Licence : BSD-2-Clause -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/howett.net/plist@v1.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/howett.net/plist@v1.0.1/LICENSE: Copyright (c) 2013, Dustin L. Howett. All rights reserved. @@ -21946,7 +21946,7 @@ Version : v2.0.0-20250604051438-85fd79dbfd9f Time : 2025-06-04T05:14:38Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/gengo/v2@v2.0.0-20250604051438-85fd79dbfd9f/LICENSE: Apache License @@ -22158,7 +22158,7 @@ Version : v0.0.0-20250710124328-f3f2b991d03b Time : 2025-07-10T12:43:28Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: +Contents of probable licence file $GOMODCACHE/k8s.io/kube-openapi@v0.0.0-20250710124328-f3f2b991d03b/LICENSE: Apache License @@ -22370,7 +22370,7 @@ Version : v0.31.2 Time : 2025-02-07T00:45:56Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.31.2/LICENSE: Apache License Version 2.0, January 2004 @@ -22581,7 +22581,7 @@ Version : v0.0.0-20241014173422-cfa47c3a1cc8 Time : 2024-10-14T17:34:22Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/json@v0.0.0-20241014173422-cfa47c3a1cc8/LICENSE: Files other than internal/golang/* licensed under: @@ -22829,7 +22829,7 @@ Version : v1.0.0 Time : 2025-03-04T18:23:53Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/randfill@v1.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/randfill@v1.0.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23041,7 +23041,7 @@ Version : v6.3.0 Time : 2025-07-16T20:34:24Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/structured-merge-diff/v6@v6.3.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23252,7 +23252,7 @@ Version : v1.6.0 Time : 2025-07-24T18:12:28Z Licence : Apache-2.0 -Contents of probable licence file /home/mmontgomery/.asdf/installs/golang/1.23.4/packages/pkg/mod/sigs.k8s.io/yaml@v1.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/sigs.k8s.io/yaml@v1.6.0/LICENSE: The MIT License (MIT) From edadd1cabe4eed3aa9810aa502a8fe8a9bddffff Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:13:21 -0600 Subject: [PATCH 16/90] Better handle the state/status. Signed-off-by: Michael Montgomery --- .../v1alpha1/autoopsagentpolicy_types.go | 1 - pkg/controller/autoops/controller.go | 65 ++++++++++------- pkg/controller/autoops/reconcile.go | 72 ++++++++++++------- 3 files changed, 84 insertions(+), 54 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 4fbc15c4a45..e04417b1398 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -62,7 +62,6 @@ type AutoOpsAgentPolicySpec struct { // name: autoops-agent-policy-config // stringData: // ccmApiKey: aslkfjsldkjfslkdjflksdjfl - // tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao // autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co // autoOpsToken: skdfjdskjf Config commonv1.ConfigSource `json:"config,omitempty"` diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 08000768a70..595399cccfc 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -112,30 +112,32 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, tracing.CaptureError(ctx, err) } - status := autoopsv1alpha1.NewStatus(policy) + state := NewState(policy) results := reconciler.NewResult(ctx) - defer func() { - // update status - if err := r.updateStatus(ctx, policy, status); err != nil { - if apierrors.IsConflict(err) { - results.WithRequeue().Aggregate() - } - results.WithError(err) - } - }() - _, err = ParseConfigSecret(ctx, r.Client, types.NamespacedName{ Namespace: policy.Namespace, Name: policy.Spec.Config.SecretRef.SecretName, }) if err != nil { if apierrors.IsNotFound(err) { - status.Phase = autoopsv1alpha1.InvalidPhase - r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, "Config secret not found") + state.UpdateInvalidPhaseWithEvent("Config secret not found") + // update status before returning + if err := r.updateStatusFromState(ctx, state); err != nil { + if apierrors.IsConflict(err) { + return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil + } + return reconcile.Result{}, tracing.CaptureError(ctx, err) + } return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil } - status.Phase = autoopsv1alpha1.ErrorPhase + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + // update status before returning + if err := r.updateStatusFromState(ctx, state); err != nil { + if apierrors.IsConflict(err) { + return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil + } + } return reconcile.Result{}, tracing.CaptureError(ctx, err) } @@ -150,10 +152,19 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } // main reconciliation logic - results, status = r.doReconcile(ctx, policy) + results = r.doReconcile(ctx, policy, state) + + // Update phase based on reconciliation state + if state.status.Phase != autoopsv1alpha1.InvalidPhase && state.status.Phase != autoopsv1alpha1.ErrorPhase { + if isReconciled, _ := results.IsReconciled(); !isReconciled { + state.UpdateWithPhase(autoopsv1alpha1.ApplyingChangesPhase) + } else { + state.UpdateWithPhase(autoopsv1alpha1.ReadyPhase) + } + } // update status - if err := r.updateStatus(ctx, policy, status); err != nil { + if err := r.updateStatusFromState(ctx, state); err != nil { if apierrors.IsConflict(err) { return results.WithRequeue().Aggregate() } @@ -176,25 +187,25 @@ func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *auto return nil } -func (r *ReconcileAutoOpsAgentPolicy) updateStatus(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, status autoopsv1alpha1.AutoOpsAgentPolicyStatus) error { +func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, state *State) error { span, _ := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() - if status.ObservedGeneration == policy.Status.ObservedGeneration && - status.Resources == policy.Status.Resources && - status.Ready == policy.Status.Ready && - status.Errors == policy.Status.Errors && - status.Phase == policy.Status.Phase { - ulog.FromContext(ctx).V(1).Info("Status is up to date", "iteration", atomic.LoadUint64(&r.iteration), "status", status) - return nil // nothing to do + events, policy := state.Apply() + for _, evt := range events { + ulog.FromContext(ctx).V(1).Info("Recording event", "event", evt) + r.recorder.Event(&state.policy, evt.EventType, evt.Reason, evt.Message) + } + if policy == nil { + ulog.FromContext(ctx).V(1).Info("Status is up to date", "iteration", atomic.LoadUint64(&r.iteration)) + return nil } ulog.FromContext(ctx).V(1).Info("Updating status", "iteration", atomic.LoadUint64(&r.iteration), - "status", status, + "status", policy.Status, ) - policy.Status = status - return common.UpdateStatus(ctx, r.Client, &policy) + return common.UpdateStatus(ctx, r.Client, policy) } func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 00985464d00..9ffcddc11ca 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -4,6 +4,7 @@ import ( "context" "time" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -11,53 +12,48 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/deployment" - "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" ) -func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy) (*reconciler.Results, autoopsv1alpha1.AutoOpsAgentPolicyStatus) { +func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, state *State) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Reconcile AutoOpsAgentPolicy") results := reconciler.NewResult(ctx) - status := autoopsv1alpha1.NewStatus(policy) // Enterprise license check enabled, err := r.licenseChecker.EnterpriseFeaturesEnabled(ctx) if err != nil { - return results.WithError(err), status + return results.WithError(err) } if !enabled { msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" log.Info(msg) - r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReconciliationError, msg) - status.Phase = autoopsv1alpha1.InvalidPhase - return results.WithRequeue(5 * time.Minute), status + state.UpdateInvalidPhaseWithEvent(msg) + return results.WithRequeue(5 * time.Minute) } // run validation in case the webhook is disabled if err := r.validate(ctx, &policy); err != nil { - r.recorder.Eventf(&policy, corev1.EventTypeWarning, events.EventReasonValidation, err.Error()) - status.Phase = autoopsv1alpha1.InvalidPhase - return results.WithError(err), status + state.UpdateInvalidPhaseWithEvent(err.Error()) + return results.WithError(err) } // reconcile dynamic watch for secret referenced in the spec if err := r.reconcileWatches(policy); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase - return results.WithError(err), status + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + return results.WithError(err) } - result := r.internalReconcile(ctx, policy, results, &status) - return result, status + return r.internalReconcile(ctx, policy, results, state) } func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, - status *autoopsv1alpha1.AutoOpsAgentPolicyStatus) *reconciler.Results { + state *State) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") @@ -67,7 +63,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( MatchExpressions: policy.Spec.ResourceSelector.MatchExpressions, }) if err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } listOpts := client.ListOptions{LabelSelector: selector} @@ -81,17 +77,21 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( var esList esv1.ElasticsearchList if err := r.Client.List(ctx, &esList, &listOpts); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } if len(esList.Items) == 0 { log.Info("No Elasticsearch resources found for the AutoOpsAgentPolicy", "namespace", policy.Namespace, "name", policy.Name) - status.Phase = autoopsv1alpha1.NoResourcesPhase - status.Resources = len(esList.Items) + state.UpdateWithPhase(autoopsv1alpha1.NoResourcesPhase). + UpdateResources(len(esList.Items)) return results } + state.UpdateResources(len(esList.Items)) + readyCount := 0 + errorCount := 0 + for _, es := range esList.Items { if es.Status.Phase != esv1.ElasticsearchReadyPhase { results = results.WithRequeue(defaultRequeue) @@ -100,35 +100,55 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( if es.Spec.HTTP.TLS.Enabled() { if err := reconcileAutoOpsESCASecret(ctx, r.Client, policy, es); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + errorCount++ + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } } // Reconcile API key for this Elasticsearch cluster if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + errorCount++ + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy, es); err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + errorCount++ + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } expectedResources, err := r.generateExpectedResources(ctx, policy, es) if err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + errorCount++ + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } - _, err = deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &policy) + reconciledDeployment, err := deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &policy) if err != nil { - status.Phase = autoopsv1alpha1.ErrorPhase + errorCount++ + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } + + if isDeploymentReady(reconciledDeployment) { + readyCount++ + } } - status.Phase = autoopsv1alpha1.ReadyPhase + state.UpdateReady(readyCount). + UpdateErrors(errorCount) return results } + +// isDeploymentReady checks if a deployment is ready by verifying that the DeploymentAvailable condition is true. +func isDeploymentReady(dep appsv1.Deployment) bool { + for _, condition := range dep.Status.Conditions { + if condition.Type == appsv1.DeploymentAvailable && condition.Status == corev1.ConditionTrue { + return true + } + } + return false +} From db9cb3befccf16b6694c4956212572ccf83a1264 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:35:17 -0600 Subject: [PATCH 17/90] cleanup Signed-off-by: Michael Montgomery --- .../v1alpha1/autoopsagentpolicy_types.go | 5 -- pkg/controller/autoops/api_key.go | 67 ++++++++++--------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index e04417b1398..1538d7094c9 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -96,17 +96,12 @@ const ( func NewStatus(policy AutoOpsAgentPolicy) AutoOpsAgentPolicyStatus { status := AutoOpsAgentPolicyStatus{ - // Details: map[ResourceType]map[string]ResourcePolicyStatus{}, Phase: UnknownPhase, ObservedGeneration: policy.Generation, } return status } -// Update updates the policy status from its resources statuses. -func (s *AutoOpsAgentPolicyStatus) Update() { -} - // IsMarkedForDeletion returns true if the AutoOpsAgentPolicy resource is going to be deleted. func (p *AutoOpsAgentPolicy) IsMarkedForDeletion() bool { return !p.DeletionTimestamp.IsZero() diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 93be9e13fed..725b35a4257 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -34,23 +34,25 @@ var ( ) const ( - // autoOpsESAPIKeySecretNamePrefix is the prefix for API key secrets created for each ES instance - autoOpsESAPIKeySecretNamePrefix = "autoops-es-api-key" - // managedByMetadataKey is the metadata key indicating the secret is managed by ECK + // autoOpsESAPIKeySecretNameSuffix is the suffix for API key secrets created for each ES instance + autoOpsESAPIKeySecretNameSuffix = "autoops-es-api-key" + // managedByMetadataKey is the metadata key indicating the API key is managed by ECK. + // This is used when storing the API key in Elasticsearch to clearly identify it as managed by ECK. + // This is not included in the labels of the secret. managedByMetadataKey = "elasticsearch.k8s.elastic.co/managed-by" - // configHashMetadataKey is the metadata key storing the hash API key - configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" // managedByValue is the value for the managed-by metadata managedByValue = "eck" + // configHashMetadataKey is the metadata key storing the hash API key + configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" // policyNameLabelKey is the label key for the AutoOpsAgentPolicy name policyNameLabelKey = "autoops.k8s.elastic.co/policy-name" // policyNamespaceLabelKey is the label key for the AutoOpsAgentPolicy namespace policyNamespaceLabelKey = "autoops.k8s.elastic.co/policy-namespace" ) -// APIKeySpec represents the specification for an autoops API key -type APIKeySpec struct { - RoleDescriptors map[string]esclient.Role +// apiKeySpec represents the specification for an autoops API key +type apiKeySpec struct { + roleDescriptors map[string]esclient.Role } // reconcileAutoOpsESAPIKey reconciles the API key and secret for a specific Elasticsearch cluster. @@ -75,16 +77,14 @@ func reconcileAutoOpsESAPIKey( return nil } - // Get Elasticsearch client esClient, err := esClientProvider(ctx, c, dialer, es) if err != nil { return fmt.Errorf("while creating Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) } defer esClient.Close() - // Build API key specification - apiKeySpec := APIKeySpec{ - RoleDescriptors: map[string]esclient.Role{ + apiKeySpec := apiKeySpec{ + roleDescriptors: map[string]esclient.Role{ "eck_autoops_role": defaultMonitoringRole, }, } @@ -92,7 +92,6 @@ func reconcileAutoOpsESAPIKey( // Calculate expected hash expectedHash := hash.HashObject(apiKeySpec) - // Generate API key name apiKeyName := apiKeyNameFor(policy, es) // Check if API key exists @@ -123,7 +122,7 @@ func createAPIKey( c k8s.Client, esClient esclient.Client, apiKeyName string, - apiKeySpec APIKeySpec, + apiKeySpec apiKeySpec, expectedHash string, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -131,6 +130,8 @@ func createAPIKey( log.Info("Creating API key", "key", apiKeyName) metadata := newMetadataFor(&policy, &es, expectedHash) + // Unfortunatelly we need to convert the metadata to a map[string]any to satisfy the APIKeyCreateRequest type. + // We return map[string]string because this is also used when storing the API key in a secret. metadataAny := make(map[string]any, len(metadata)) for k, v := range metadata { metadataAny[k] = v @@ -139,7 +140,7 @@ func createAPIKey( apiKeyResp, err := esClient.CreateAPIKey(ctx, esclient.APIKeyCreateRequest{ Name: apiKeyName, APIKeyUpdateRequest: esclient.APIKeyUpdateRequest{ - RoleDescriptors: apiKeySpec.RoleDescriptors, + RoleDescriptors: apiKeySpec.roleDescriptors, Metadata: metadataAny, }, }) @@ -147,7 +148,7 @@ func createAPIKey( return fmt.Errorf("while creating API key %s: %w", apiKeyName, err) } - return storeAPIKeyInSecret(ctx, c, apiKeyName, apiKeyResp.Encoded, expectedHash, policy, es) + return storeAPIKeyInSecret(ctx, c, apiKeyResp.Encoded, expectedHash, policy, es) } // maybeUpdateAPIKey checks if the API key needs to be updated and handles it. @@ -158,7 +159,7 @@ func maybeUpdateAPIKey( esClient esclient.Client, activeAPIKey *esclient.APIKey, apiKeyName string, - apiKeySpec APIKeySpec, + apiKeySpec apiKeySpec, expectedHash string, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -168,7 +169,7 @@ func maybeUpdateAPIKey( return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } - // The api key is seemlingly up to date, so we need to ensure the secret exists with correct value + // The API key is seemingly up to date, so we need to ensure the secret exists with correct value secretName := apiKeySecretNameFrom(es) var secret corev1.Secret nsn := types.NamespacedName{ @@ -177,14 +178,14 @@ func maybeUpdateAPIKey( } if err := c.Get(ctx, nsn, &secret); err != nil { if apierrors.IsNotFound(err) { - // Secret doesn't exist so again we need to invalidate and recreate the api key. + // Secret doesn't exist so again we need to invalidate and recreate the API key. log.Info("API key secret not found, recreating key", "key", apiKeyName) return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } return fmt.Errorf("while retrieving API key secret %s: %w", secretName, err) } - // Since the secret exists, just just need to verify the data is correct. + // Since the secret exists, we just need to verify the data is correct. if encodedKey, ok := secret.Data["api_key"]; !ok || string(encodedKey) == "" { log.Info("API key secret exists but is missing api_key, recreating key", "key", apiKeyName) return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) @@ -201,7 +202,7 @@ func invalidateAndCreateAPIKey( esClient esclient.Client, activeAPIKey *esclient.APIKey, apiKeyName string, - apiKeySpec APIKeySpec, + apiKeySpec apiKeySpec, expectedHash string, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -212,6 +213,11 @@ func invalidateAndCreateAPIKey( return createAPIKey(ctx, log, c, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) } +// apiKeyNeedsRecreation checks if the API key needs to be recreated. +// It will be recreated in the following cases: +// - The API key has no metadata +// - The API key has the wrong "managed-by" value +// - The API key has the wrong "config-hash" value func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { if apiKey.Metadata == nil { return true @@ -228,7 +234,7 @@ func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { return false } -// invalidateAPIKey invalidates an API key by its ID. +// invalidateAPIKey invalidates an API key by its key ID by calling the Elasticsearch API. func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID string) error { _, err := esClient.InvalidateAPIKeys(ctx, esclient.APIKeysInvalidateRequest{ IDs: []string{keyID}, @@ -240,7 +246,6 @@ func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID strin func storeAPIKeyInSecret( ctx context.Context, c k8s.Client, - apiKeyName string, encodedKey string, expectedHash string, policy autoopsv1alpha1.AutoOpsAgentPolicy, @@ -302,7 +307,7 @@ func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsea // apiKeySecretNameFrom generates the name for the API key secret from an ES instance. func apiKeySecretNameFrom(es esv1.Elasticsearch) string { - return fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESAPIKeySecretNamePrefix) + return fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESAPIKeySecretNameSuffix) } // newMetadataFor returns the metadata to be set in the Elasticsearch API key. @@ -346,13 +351,12 @@ func cleanupAutoOpsESAPIKey( } defer esClient.Close() - // Generate API key name - apiKeyName := fmt.Sprintf("eck-autoops-%s-%s-%s-%s", policyNamespace, policyName, es.Namespace, es.Name) + apiKeyName := apiKeyNameFor(autoopsv1alpha1.AutoOpsAgentPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: policyNamespace, Name: policyName}}, es) // Check if API key exists activeAPIKeys, err := esClient.GetAPIKeysByName(ctx, apiKeyName) if err != nil { - return fmt.Errorf("failed to get API keys by name %s: %w", apiKeyName, err) + return fmt.Errorf("while getting API keys by name %s: %w", apiKeyName, err) } // Invalidate all matching API keys @@ -360,13 +364,11 @@ func cleanupAutoOpsESAPIKey( if key.Name == apiKeyName { log.Info("Invalidating API key", "key", apiKeyName, "id", key.ID) if err := invalidateAPIKey(ctx, esClient, key.ID); err != nil { - log.Error(err, "Failed to invalidate API key", "key", apiKeyName, "id", key.ID) - // Continue to try to invalidate other keys + log.Error(err, "while invalidating API key", "key", apiKeyName, "id", key.ID) } } } - // Delete the secret secretName := apiKeySecretNameFrom(es) secretKey := types.NamespacedName{ Namespace: policyNamespace, @@ -378,16 +380,15 @@ func cleanupAutoOpsESAPIKey( // Secret already deleted, nothing to do return nil } - return fmt.Errorf("failed to get API key secret %s: %w", secretName, err) + return fmt.Errorf("while getting API key secret %s: %w", secretName, err) } log.Info("Deleting API key secret", "secret", secretName) if err := c.Delete(ctx, &secret); err != nil { if apierrors.IsNotFound(err) { - // Already deleted return nil } - return fmt.Errorf("failed to delete API key secret %s: %w", secretName, err) + return fmt.Errorf("while deleting API key secret %s: %w", secretName, err) } return nil From 578c3a9cfbe1f8a2f3a8d34d463bd8c49d73c492 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:40:02 -0600 Subject: [PATCH 18/90] More cleanup Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configuration.go | 27 +++++++----------- pkg/controller/autoops/configuration_test.go | 30 ++++++++++---------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 808538494f4..196bfe10a8c 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -25,14 +25,13 @@ type Config struct { const ( // Secret key names for the configuration fields - CCMApiKey = "cloud-connected-mode-api-key" - // TempResourceID = "temp-resource-id" - AutoOpsOTelURL = "autoops-otel-url" - AutoOpsToken = "autoops-token" + ccmApiKey = "cloud-connected-mode-api-key" + autoOpsOTelURL = "autoops-otel-url" + autoOpsToken = "autoops-token" ) // ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. -// It returns a Config struct containing the parsed configuration values and an error if encountered. +// It returns a Config struct containing the parsed configuration values and any error encountered. func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.NamespacedName) (*Config, error) { if secretKey.Name == "" { return nil, fmt.Errorf("secret name cannot be empty") @@ -52,28 +51,22 @@ func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.N func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedName) (*Config, error) { var config Config - if data, exists := secret.Data[CCMApiKey]; exists && len(data) > 0 { + if data, exists := secret.Data[ccmApiKey]; exists && len(data) > 0 { config.CCMApiKey = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", CCMApiKey, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", ccmApiKey, secretKey.Namespace, secretKey.Name) } - // if data, exists := secret.Data[TempResourceID]; exists { - // config.TempResourceID = string(data) - // } else { - // return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", TempResourceID, secretKey.Namespace, secretKey.Name) - // } - - if data, exists := secret.Data[AutoOpsOTelURL]; exists && len(data) > 0 { + if data, exists := secret.Data[autoOpsOTelURL]; exists && len(data) > 0 { config.AutoOpsOTelURL = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsOTelURL, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsOTelURL, secretKey.Namespace, secretKey.Name) } - if data, exists := secret.Data[AutoOpsToken]; exists && len(data) > 0 { + if data, exists := secret.Data[autoOpsToken]; exists && len(data) > 0 { config.AutoOpsToken = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", AutoOpsToken, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsToken, secretKey.Namespace, secretKey.Name) } return &config, nil diff --git a/pkg/controller/autoops/configuration_test.go b/pkg/controller/autoops/configuration_test.go index 8a6e24bee43..1174ca90f13 100644 --- a/pkg/controller/autoops/configuration_test.go +++ b/pkg/controller/autoops/configuration_test.go @@ -28,9 +28,9 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - CCMApiKey: []byte("ccm-api-key-value"), - AutoOpsOTelURL: []byte("https://otel.example.com"), - AutoOpsToken: []byte("token-value"), + ccmApiKey: []byte("ccm-api-key-value"), + autoOpsOTelURL: []byte("https://otel.example.com"), + autoOpsToken: []byte("token-value"), }, }, secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, @@ -49,8 +49,8 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - AutoOpsOTelURL: []byte("https://otel.example.com"), - AutoOpsToken: []byte("token-value"), + autoOpsOTelURL: []byte("https://otel.example.com"), + autoOpsToken: []byte("token-value"), }, }, secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, @@ -65,8 +65,8 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - CCMApiKey: []byte("ccm-api-key-value"), - AutoOpsToken: []byte("token-value"), + ccmApiKey: []byte("ccm-api-key-value"), + autoOpsToken: []byte("token-value"), }, }, secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, @@ -81,8 +81,8 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - CCMApiKey: []byte("ccm-api-key-value"), - AutoOpsOTelURL: []byte("https://otel.example.com"), + ccmApiKey: []byte("ccm-api-key-value"), + autoOpsOTelURL: []byte("https://otel.example.com"), }, }, secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, @@ -97,9 +97,9 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - CCMApiKey: []byte(""), - AutoOpsOTelURL: []byte(""), - AutoOpsToken: []byte(""), + ccmApiKey: []byte(""), + autoOpsOTelURL: []byte(""), + autoOpsToken: []byte(""), }, }, secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, @@ -140,9 +140,9 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - CCMApiKey: []byte("ccm-api-key-value"), - AutoOpsOTelURL: []byte("https://otel.example.com"), - AutoOpsToken: []byte("token-value"), + ccmApiKey: []byte("ccm-api-key-value"), + autoOpsOTelURL: []byte("https://otel.example.com"), + autoOpsToken: []byte("token-value"), "extra-field": []byte("extra-value"), }, }, From 275e1a1376b149e5b45ae36b7ccfd28d558a93b2 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:41:01 -0600 Subject: [PATCH 19/90] lowercase Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configuration_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/controller/autoops/configuration_test.go b/pkg/controller/autoops/configuration_test.go index 1174ca90f13..5fc26823ca5 100644 --- a/pkg/controller/autoops/configuration_test.go +++ b/pkg/controller/autoops/configuration_test.go @@ -42,7 +42,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { wantErr: false, }, { - name: "missing CCMApiKey returns an error", + name: "missing ccmApiKey returns an error", secret: corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "config-secret", @@ -58,7 +58,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { wantErr: true, }, { - name: "missing AutoOpsOTelURL returns an error", + name: "missing autoOpsOTelURL returns an error", secret: corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "config-secret", @@ -74,7 +74,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { wantErr: true, }, { - name: "missing AutoOpsToken returns an error", + name: "missing autoOpsToken returns an error", secret: corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "config-secret", @@ -168,13 +168,13 @@ func Test_validateAndPopulateConfig(t *testing.T) { return } if got.CCMApiKey != tt.want.CCMApiKey { - t.Errorf("validateAndPopulateConfig() CCMApiKey = %v, want %v", got.CCMApiKey, tt.want.CCMApiKey) + t.Errorf("validateAndPopulateConfig() ccmApiKey = %v, want %v", got.CCMApiKey, tt.want.CCMApiKey) } if got.AutoOpsOTelURL != tt.want.AutoOpsOTelURL { - t.Errorf("validateAndPopulateConfig() AutoOpsOTelURL = %v, want %v", got.AutoOpsOTelURL, tt.want.AutoOpsOTelURL) + t.Errorf("validateAndPopulateConfig() autoOpsOTelURL = %v, want %v", got.AutoOpsOTelURL, tt.want.AutoOpsOTelURL) } if got.AutoOpsToken != tt.want.AutoOpsToken { - t.Errorf("validateAndPopulateConfig() AutoOpsToken = %v, want %v", got.AutoOpsToken, tt.want.AutoOpsToken) + t.Errorf("validateAndPopulateConfig() autoOpsToken = %v, want %v", got.AutoOpsToken, tt.want.AutoOpsToken) } } }) From a7e362004ca6a1afc26d94710b207ac325740b45 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:43:52 -0600 Subject: [PATCH 20/90] cleanup Signed-off-by: Michael Montgomery --- pkg/controller/autoops/controller.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 595399cccfc..0df43789bdd 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -91,8 +91,7 @@ type ReconcileAutoOpsAgentPolicy struct { iteration uint64 } -// Reconcile reads that state of the cluster for an AutoOpsAgentPolicy object and makes changes based on the state read and what is -// in the AutoOpsAgentPolicy.Spec. +// Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any deployments are created/updated/deleted as needed. func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) defer common.LogReconciliationRun(ulog.FromContext(ctx))() @@ -141,7 +140,6 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, tracing.CaptureError(ctx, err) } - // skip unmanaged resources if common.IsUnmanaged(ctx, &policy) { ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") return reconcile.Result{}, nil @@ -151,10 +149,8 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } - // main reconciliation logic results = r.doReconcile(ctx, policy, state) - // Update phase based on reconciliation state if state.status.Phase != autoopsv1alpha1.InvalidPhase && state.status.Phase != autoopsv1alpha1.ErrorPhase { if isReconciled, _ := results.IsReconciled(); !isReconciled { state.UpdateWithPhase(autoopsv1alpha1.ApplyingChangesPhase) @@ -163,7 +159,6 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } } - // update status if err := r.updateStatusFromState(ctx, state); err != nil { if apierrors.IsConflict(err) { return results.WithRequeue().Aggregate() From 335bc67865c258d642ebd7a96f0d9ec5949822bb Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:47:17 -0600 Subject: [PATCH 21/90] const for label name Signed-off-by: Michael Montgomery --- pkg/controller/autoops/expected.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 46bdd27bfc4..caa0894d4f2 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -28,6 +28,7 @@ import ( ) const ( + autoOpsLabelName = "autoops.k8s.elastic.co/name" configVolumeName = "config-volume" configVolumePath = "/mnt/config" configHashAnnotationName = "autoops.k8s.elastic.co/config-hash" @@ -70,8 +71,8 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli return appsv1.Deployment{}, err } labels := map[string]string{ - commonv1.TypeLabelName: "autoops-agent", - "autoops.k8s.elastic.co/name": policy.Name, + commonv1.TypeLabelName: "autoops-agent", + autoOpsLabelName: policy.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ Name: AutoOpsNamer.Suffix(es.Name, es.GetNamespace(), "deploy"), @@ -82,7 +83,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli Replicas: pointer.Int32(1), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "autoops.k8s.elastic.co/name": policy.Name, + autoOpsLabelName: policy.Name, }, }, } From 222589b3ca40be3960661f3fbf8332b4599503f4 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:49:11 -0600 Subject: [PATCH 22/90] cleanup Signed-off-by: Michael Montgomery --- pkg/controller/autoops/reconcile.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 9ffcddc11ca..7140cb3fbba 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -68,7 +68,8 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } listOpts := client.ListOptions{LabelSelector: selector} - // restrict the search to the policy namespace if it is different from the operator namespace + // Restrict the search to the policy namespace if it is different from the operator namespace + // This follows the same behavior as the stackconfigpolicy controller for consistency. log.V(1).Info("comparing policy namespace with operator namespace", "policy namespace", policy.Namespace, "operator namespace", r.params.OperatorNamespace) if policy.Namespace != r.params.OperatorNamespace { log.V(1).Info("Restricting search to policy namespace", "namespace", policy.Namespace) @@ -106,7 +107,6 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } } - // Reconcile API key for this Elasticsearch cluster if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) From 0c190d40ab7320f7e0c28535e97ffea685cc5414 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 15:53:44 -0600 Subject: [PATCH 23/90] more cleanup Signed-off-by: Michael Montgomery --- pkg/controller/autoops/expected.go | 2 +- pkg/controller/autoops/secret.go | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index caa0894d4f2..16faf757c35 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -96,7 +96,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli // Add CA certificate volume for this ES instance only if TLS is enabled if es.Spec.HTTP.TLS.Enabled() { - caSecretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretPrefix) + caSecretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretSuffix) caVolume := volume.NewSecretVolumeWithMountPath( caSecretName, fmt.Sprintf("es-ca-%s-%s", es.Name, es.Namespace), diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 42f455c7a4e..9e0c8f8550a 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -16,6 +16,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -24,8 +25,8 @@ import ( ) const ( - // autoOpsESCASecretPrefix is the prefix for CA secrets created for each ES instance - autoOpsESCASecretPrefix = "autoops-es-ca" + // autoOpsESCASecretSuffix is the suffix for CA secrets created for each ES instance + autoOpsESCASecretSuffix = "autoops-es-ca" ) // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate @@ -46,7 +47,7 @@ func reconcileAutoOpsESCASecret( sourceSecretKey := types.NamespacedName{ Namespace: es.Namespace, - Name: fmt.Sprintf("%s-es-http-ca-internal", es.Name), + Name: certificates.CAInternalSecretName(esv1.ESNamer, es.Name, certificates.HTTPCAType), } var sourceSecret corev1.Secret if err := c.Get(ctx, sourceSecretKey, &sourceSecret); err != nil { @@ -57,14 +58,14 @@ func reconcileAutoOpsESCASecret( return fmt.Errorf("while retrieving http-ca-internal secret for ES cluster %s/%s: %w", es.Namespace, es.Name, err) } - caCert, ok := sourceSecret.Data["tls.crt"] + caCert, ok := sourceSecret.Data[certificates.CertFileName] if !ok || len(caCert) == 0 { log.V(1).Info("tls.crt not found in http-ca-internal secret, skipping", "namespace", es.Namespace, "name", es.Name) return nil } - secretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretPrefix) - expected := buildAutoOpsESCASecret(policy, es, secretName, caCert) + secretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretSuffix) + expected := buildAutoOpsESCASecret(policy, secretName, caCert) reconciled := &corev1.Secret{} return reconciler.ReconcileResource( @@ -89,7 +90,7 @@ func reconcileAutoOpsESCASecret( } // buildAutoOpsESCASecret builds the expected Secret for autoops ES CA certificate. -func buildAutoOpsESCASecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, secretName string, caCert []byte) corev1.Secret { +func buildAutoOpsESCASecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, secretName string, caCert []byte) corev1.Secret { if len(caCert) == 0 { return corev1.Secret{} } @@ -107,7 +108,7 @@ func buildAutoOpsESCASecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.E Annotations: meta.Annotations, }, Data: map[string][]byte{ - "ca.crt": caCert, + certificates.CAFileName: caCert, }, } } From 68ca2003d562988f3d77dab62e1c5f34c5a51248 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 16:07:14 -0600 Subject: [PATCH 24/90] Skip api keys in remote cluster controller managed by autoops Signed-off-by: Michael Montgomery --- .../eck-operator/charts/eck-operator-crds/Chart.yaml | 1 + pkg/controller/autoops/api_key.go | 7 ++++--- pkg/controller/autoops/api_key_test.go | 2 +- pkg/controller/autoops/controller.go | 2 +- pkg/controller/autoops/controller_test.go | 10 +++++----- pkg/controller/remotecluster/controller.go | 5 +++++ 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/deploy/eck-operator/charts/eck-operator-crds/Chart.yaml b/deploy/eck-operator/charts/eck-operator-crds/Chart.yaml index 59a45a8ca4b..c3d16cfbf9e 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/Chart.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/Chart.yaml @@ -17,6 +17,7 @@ home: https://github.com/elastic/cloud-on-k8s kubeVersion: ">=1.21.0-0" keywords: + - AutoOps - Logstash - Elasticsearch - Kibana diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 725b35a4257..70bd189263d 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -44,8 +44,9 @@ const ( managedByValue = "eck" // configHashMetadataKey is the metadata key storing the hash API key configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" - // policyNameLabelKey is the label key for the AutoOpsAgentPolicy name - policyNameLabelKey = "autoops.k8s.elastic.co/policy-name" + // PolicyNameLabelKey is the label key for the AutoOpsAgentPolicy name. + // This is exported as its used in the remotecluster controller to identify API keys managed by the autoops controller. + PolicyNameLabelKey = "autoops.k8s.elastic.co/policy-name" // policyNamespaceLabelKey is the label key for the AutoOpsAgentPolicy namespace policyNamespaceLabelKey = "autoops.k8s.elastic.co/policy-namespace" ) @@ -317,7 +318,7 @@ func newMetadataFor(policy *autoopsv1alpha1.AutoOpsAgentPolicy, es *esv1.Elastic "elasticsearch.k8s.elastic.co/name": es.Name, "elasticsearch.k8s.elastic.co/namespace": es.Namespace, managedByMetadataKey: managedByValue, - policyNameLabelKey: policy.Name, + PolicyNameLabelKey: policy.Name, policyNamespaceLabelKey: policy.Namespace, } } diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go index 89d6e2448b6..e1f0924b45b 100644 --- a/pkg/controller/autoops/api_key_test.go +++ b/pkg/controller/autoops/api_key_test.go @@ -117,7 +117,7 @@ func Test_newMetadataFor(t *testing.T) { "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", managedByMetadataKey: managedByValue, - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", }, }, diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 0df43789bdd..1c62d556b53 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -215,7 +215,7 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na // Query for secrets labeled with this policy to find all associated ES clusters. var secrets corev1.SecretList matchLabels := client.MatchingLabels{ - policyNameLabelKey: obj.Name, + PolicyNameLabelKey: obj.Name, policyNamespaceLabelKey: obj.Namespace, } if err := r.Client.List(ctx, &secrets, matchLabels); err != nil { diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index 84f9873177f..aa273fe3f70 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -81,7 +81,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { Name: "es-1-ns-2-autoops-es-api-key", Namespace: "ns-1", Labels: map[string]string{ - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", @@ -117,7 +117,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { Name: "es-1-ns-2-autoops-es-api-key", Namespace: "ns-1", Labels: map[string]string{ - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", @@ -199,7 +199,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { Name: "es-1-ns-2-autoops-es-api-key", Namespace: "ns-1", Labels: map[string]string{ - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", @@ -222,7 +222,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { Name: "es-1-ns-2-autoops-es-api-key", Namespace: "ns-1", Labels: map[string]string{ - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", @@ -234,7 +234,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { Name: "es-1-ns-2-autoops-es-api-key-duplicate", Namespace: "ns-1", Labels: map[string]string{ - policyNameLabelKey: "policy-1", + PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", "elasticsearch.k8s.elastic.co/name": "es-1", "elasticsearch.k8s.elastic.co/namespace": "ns-2", diff --git a/pkg/controller/remotecluster/controller.go b/pkg/controller/remotecluster/controller.go index 4cb73bab3d9..bb4f98aec88 100644 --- a/pkg/controller/remotecluster/controller.go +++ b/pkg/controller/remotecluster/controller.go @@ -21,6 +21,7 @@ import ( commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/association" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoops" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common" commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" @@ -270,6 +271,10 @@ func doReconcile( // Delete orphaned API keys from clusters which have been deleted // ************************************************************** for _, activeAPIKey := range activeAPIKeys.APIKeys { + // Skip API keys managed by the autoops controller. + if activeAPIKey.Metadata != nil && activeAPIKey.Metadata[autoops.PolicyNameLabelKey] != nil { + continue + } clientCluster, err := activeAPIKey.GetElasticsearchName() if err != nil { results.WithError(err) From 2204c47a023b45c0b3bd82851bb8a919bb6da403 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 16:42:33 -0600 Subject: [PATCH 25/90] Add helm charts Signed-off-by: Michael Montgomery --- deploy/eck-operator/templates/_helpers.tpl | 13 +++ .../eck-operator/templates/cluster-roles.yaml | 6 ++ deploy/eck-operator/templates/webhook.yaml | 31 ++++++ deploy/eck-stack/Chart.yaml | 3 + .../eck-stack/charts/eck-autoops/Chart.yaml | 9 ++ deploy/eck-stack/charts/eck-autoops/LICENSE | 94 +++++++++++++++++++ .../charts/eck-autoops/examples/basic.yaml | 24 +++++ .../charts/eck-autoops/templates/NOTES.txt | 7 ++ .../charts/eck-autoops/templates/_helpers.tpl | 63 +++++++++++++ .../templates/autoopsagentpolicy.yaml | 21 +++++ .../charts/eck-autoops/templates/secret.yaml | 20 ++++ .../eck-stack/charts/eck-autoops/values.yaml | 59 ++++++++++++ deploy/eck-stack/examples/autoops/basic.yaml | 32 +++++++ pkg/controller/autoops/state.go | 90 ++++++++++++++++++ 14 files changed, 472 insertions(+) create mode 100644 deploy/eck-stack/charts/eck-autoops/Chart.yaml create mode 100644 deploy/eck-stack/charts/eck-autoops/LICENSE create mode 100644 deploy/eck-stack/charts/eck-autoops/examples/basic.yaml create mode 100644 deploy/eck-stack/charts/eck-autoops/templates/NOTES.txt create mode 100644 deploy/eck-stack/charts/eck-autoops/templates/_helpers.tpl create mode 100644 deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml create mode 100644 deploy/eck-stack/charts/eck-autoops/templates/secret.yaml create mode 100644 deploy/eck-stack/charts/eck-autoops/values.yaml create mode 100644 deploy/eck-stack/examples/autoops/basic.yaml create mode 100644 pkg/controller/autoops/state.go diff --git a/deploy/eck-operator/templates/_helpers.tpl b/deploy/eck-operator/templates/_helpers.tpl index ddfd8b75272..432694bce0f 100644 --- a/deploy/eck-operator/templates/_helpers.tpl +++ b/deploy/eck-operator/templates/_helpers.tpl @@ -340,6 +340,19 @@ updating docs/operating-eck/eck-permissions.asciidoc file. - create - update - patch +- apiGroups: + - autoops.k8s.elastic.co + resources: + - autoopsagentpolicies + - autoopsagentpolicies/status + - autoopsagentpolicies/finalizers # needed for ownerReferences with blockOwnerDeletion on OCP + verbs: + - get + - list + - watch + - create + - update + - patch {{- end -}} {{/* diff --git a/deploy/eck-operator/templates/cluster-roles.yaml b/deploy/eck-operator/templates/cluster-roles.yaml index dbd0fba3e2f..9c080d80e41 100644 --- a/deploy/eck-operator/templates/cluster-roles.yaml +++ b/deploy/eck-operator/templates/cluster-roles.yaml @@ -56,6 +56,9 @@ rules: - apiGroups: ["logstash.k8s.elastic.co"] resources: ["logstashes"] verbs: ["get", "list", "watch"] + - apiGroups: ["autoops.k8s.elastic.co"] + resources: ["autoopsagentpolicies"] + verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -96,6 +99,9 @@ rules: - apiGroups: ["logstash.k8s.elastic.co"] resources: ["logstashes"] verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["autoops.k8s.elastic.co"] + resources: ["autoopsagentpolicies"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] {{- if .Values.config.metrics.secureMode.enabled }} --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/deploy/eck-operator/templates/webhook.yaml b/deploy/eck-operator/templates/webhook.yaml index e31df165674..d7522eb9290 100644 --- a/deploy/eck-operator/templates/webhook.yaml +++ b/deploy/eck-operator/templates/webhook.yaml @@ -445,6 +445,37 @@ webhooks: - UPDATE resources: - logstashes +- clientConfig: + {{- if and (not .Values.webhook.manageCerts) (not .Values.webhook.certManagerCert) }} + caBundle: {{ .Values.webhook.caBundle }} + {{- end }} + service: + name: {{ include "eck-operator.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-autoops-k8s-elastic-co-v1alpha1-autoopsagentpolicies + failurePolicy: {{ .Values.webhook.failurePolicy }} +{{- with .Values.webhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- with .Values.webhook.objectSelector }} + objectSelector: + {{- toYaml . | nindent 4 }} +{{- end }} + name: elastic-autoops-validation-v1alpha1.k8s.elastic.co + matchPolicy: Exact + admissionReviewVersions: [v1] + sideEffects: None + rules: + - apiGroups: + - autoops.k8s.elastic.co + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - autoopsagentpolicies --- apiVersion: v1 kind: Service diff --git a/deploy/eck-stack/Chart.yaml b/deploy/eck-stack/Chart.yaml index 7b9d735f06c..fbb89126dc3 100644 --- a/deploy/eck-stack/Chart.yaml +++ b/deploy/eck-stack/Chart.yaml @@ -30,3 +30,6 @@ dependencies: - name: eck-enterprise-search condition: eck-enterprise-search.enabled version: "0.18.0-SNAPSHOT" + - name: eck-autoops + condition: eck-autoops.enabled + version: "0.18.0-SNAPSHOT" \ No newline at end of file diff --git a/deploy/eck-stack/charts/eck-autoops/Chart.yaml b/deploy/eck-stack/charts/eck-autoops/Chart.yaml new file mode 100644 index 00000000000..a3feed0b277 --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: eck-autoops +description: AutoOps Agent Policy managed by the ECK operator +kubeVersion: ">= 1.21.0-0" +type: application +version: 0.18.0-SNAPSHOT +sources: + - https://github.com/elastic/cloud-on-k8s + diff --git a/deploy/eck-stack/charts/eck-autoops/LICENSE b/deploy/eck-stack/charts/eck-autoops/LICENSE new file mode 100644 index 00000000000..7be32fc6c3e --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/LICENSE @@ -0,0 +1,94 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor's trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. + diff --git a/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml new file mode 100644 index 00000000000..e0cb05817c2 --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml @@ -0,0 +1,24 @@ +--- +# Version of AutoOps Agent Policy. +# +version: 9.2.0 + +# AutoOps configuration values. +# These values are required and will be used to create a Kubernetes Secret. +# +ccmApiKey: "your-api-key-here" +autoOpsOTelURL: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" +autoOpsToken: "your-token-here" + +# Optional: Override the default secret name. +# If not specified, defaults to the fullname of the chart with '-secret' suffix. +# +# secretName: "custom-secret-name" + +# ResourceSelector is a label selector for the resources to be configured. +# Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. +# +resourceSelector: + matchLabels: + autoops: enabled + diff --git a/deploy/eck-stack/charts/eck-autoops/templates/NOTES.txt b/deploy/eck-stack/charts/eck-autoops/templates/NOTES.txt new file mode 100644 index 00000000000..a2eaeece9d5 --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/templates/NOTES.txt @@ -0,0 +1,7 @@ + +1. Check AutoOps Agent Policy status + $ kubectl get autoops {{ include "autoops.fullname" . }} -n {{ .Release.Namespace }} + +2. Check AutoOps Agent Policy details + $ kubectl describe autoops {{ include "autoops.fullname" . }} -n {{ .Release.Namespace }} + diff --git a/deploy/eck-stack/charts/eck-autoops/templates/_helpers.tpl b/deploy/eck-stack/charts/eck-autoops/templates/_helpers.tpl new file mode 100644 index 00000000000..b3098b0ce56 --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "autoops.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "autoops.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "autoops.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "autoops.labels" -}} +helm.sh/chart: {{ include "autoops.chart" . }} +{{ include "autoops.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.labels }} +{{ toYaml .Values.labels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "autoops.selectorLabels" -}} +app.kubernetes.io/name: {{ include "autoops.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Secret name for AutoOps configuration +*/}} +{{- define "autoops.secretName" -}} +{{- if .Values.secretName }} +{{- .Values.secretName | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-secret" (include "autoops.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml new file mode 100644 index 00000000000..0948dc030db --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: autoops.k8s.elastic.co/v1alpha1 +kind: AutoOpsAgentPolicy +metadata: + name: {{ include "autoops.fullname" . }} + labels: + {{- include "autoops.labels" . | nindent 4 }} + annotations: + eck.k8s.elastic.co/license: basic + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + version: {{ required "An AutoOps Agent Policy version is required" .Values.version }} + config: + secretName: {{ include "autoops.secretName" . }} + {{- with .Values.resourceSelector }} + resourceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + diff --git a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml new file mode 100644 index 00000000000..2b46b4c3e14 --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "autoops.secretName" . }} + labels: + {{- include "autoops.labels" . | nindent 4 }} + annotations: + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +stringData: + cloud-connected-mode-api-key: {{ required "ccmApiKey is required" .Values.ccmApiKey }} + autoops-otel-url: {{ required "autoOpsOTelURL is required" .Values.autoOpsOTelURL }} + autoops-token: {{ required "autoOpsToken is required" .Values.autoOpsToken }} + {{ with .Values.cloudConnectedModeAPIURL }} + cloud-connected-mode-api-url: {{ . }} + {{ end }} + diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml new file mode 100644 index 00000000000..f3c20fe11ce --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -0,0 +1,59 @@ +--- +# Default values for eck-autoops. +# This is a YAML-formatted file. + +# Overridable names of the AutoOps Agent Policy resource. +# By default, this is the Release name set for the chart, +# followed by 'eck-autoops'. +# +# nameOverride will override the name of the Chart with the name set here, +# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart' +# +# nameOverride: "quickstart" +# +# fullnameOverride will override both the release name, and the chart name, +# and will name the AutoOps Agent Policy resource exactly as specified. +# +# fullnameOverride: "quickstart" + +# Version of AutoOps Agent Policy. +# +version: 9.2.0 + +# Labels that will be applied to AutoOps Agent Policy. +# +labels: {} + +# Annotations that will be applied to AutoOps Agent Policy. +# +annotations: {} + +# AutoOps configuration values. +# These values are required and will be used to create a Kubernetes Secret. +# +# All of these can be obtained the Elastic Cloud Console (https://cloud.elastic.co/connect-cluster-services-portal) +# by selecting the ECK connect wizard and following the instructions. +# +# This is the Cloud Connected Mode API key and is required. This is used to register the Agent with Elastic Cloud AutoOps. +ccmApiKey: "" +# This is the URL of the AutoOps OTel endpoint and is required. This is used to send Agent data to the AutoOps platform and is region specific. +# Example: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" +autoOpsOTelURL: "" +# This token is required and is how AutoOps knows how to connect Agent data to the relevant Elastic Cloud organization +autoOpsToken: "" +# URL of the Cloud Connected Mode API. +# This is not a required field. +cloudConnectedModeAPIURL: "" + +# Secret name for the AutoOps configuration. +# If not specified, defaults to the fullname of the chart with '-secret' suffix. +# +# secretName: "" + +# ResourceSelector is a label selector for the resources to be configured. +# Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. +# +resourceSelector: + matchLabels: + autoops: enabled + diff --git a/deploy/eck-stack/examples/autoops/basic.yaml b/deploy/eck-stack/examples/autoops/basic.yaml new file mode 100644 index 00000000000..7b8c4a8adfe --- /dev/null +++ b/deploy/eck-stack/examples/autoops/basic.yaml @@ -0,0 +1,32 @@ +--- +eck-autoops: + enabled: true + ccmApiKey: "your-api-key-here" + autoOpsOTelURL: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" + autoOpsToken: "your-token-here" + secretName: "autoops-secret" + resourceSelector: + matchLabels: + autoops: enabled + +eck-elasticsearch: + enabled: true + + # This label is used to select the Elasticsearch instance for AutoOps integration. + labels: + autoops: enabled + + # Name of the Elasticsearch instance. + # + fullnameOverride: elasticsearch + + nodeSets: + - name: default + count: 1 + # Comment out when setting the vm.max_map_count via initContainer, as these are mutually exclusive. + # For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count to 262144 + # and leave node.store.allow_mmap unset. + # ref: https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-virtual-memory.html + # + config: + node.store.allow_mmap: false diff --git a/pkg/controller/autoops/state.go b/pkg/controller/autoops/state.go new file mode 100644 index 00000000000..6c1fde3382e --- /dev/null +++ b/pkg/controller/autoops/state.go @@ -0,0 +1,90 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "reflect" + + corev1 "k8s.io/api/core/v1" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" +) + +// State holds the accumulated state during the reconcile loop including the response and a copy of the +// AutoOpsAgentPolicy resource from the start of reconciliation, for status updates. +type State struct { + *events.Recorder + policy autoopsv1alpha1.AutoOpsAgentPolicy + status autoopsv1alpha1.AutoOpsAgentPolicyStatus +} + +// NewState creates a new reconcile state based on the given policy +func NewState(policy autoopsv1alpha1.AutoOpsAgentPolicy) *State { + status := *policy.Status.DeepCopy() + status.ObservedGeneration = policy.Generation + // Similar to ES, we initially set the phase to an empty string so that we do not report an outdated phase + // given that certain phases are stickier than others (eg. invalid) + status.Phase = "" + return &State{ + Recorder: events.NewRecorder(), + policy: policy, + status: status, + } +} + +// UpdateWithPhase updates the phase of the AutoOpsAgentPolicy status. +// It respects phase stickiness - InvalidPhase will not be overwritten, and ApplyingChangesPhase +// will not overwrite other non-ready phases. +func (s *State) UpdateWithPhase(phase autoopsv1alpha1.PolicyPhase) *State { + switch { + // do not overwrite the Invalid phase + case s.status.Phase == autoopsv1alpha1.InvalidPhase: + return s + // do not overwrite non-ready phases like ErrorPhase or NoResourcesPhase + case s.status.Phase != "" && phase == autoopsv1alpha1.ApplyingChangesPhase: + return s + } + s.status.Phase = phase + return s +} + +// UpdateAutoOpsInvalidWithEvent is a convenient method to set the phase to InvalidPhase +// and generate an event at the same time. +func (s *State) UpdateInvalidPhaseWithEvent(msg string) { + s.status.Phase = autoopsv1alpha1.InvalidPhase + s.AddEvent(corev1.EventTypeWarning, events.EventReasonValidation, msg) +} + +// UpdateResources updates the Resources count in the status. +func (s *State) UpdateResources(count int) *State { + s.status.Resources = count + return s +} + +// UpdateReady updates the Ready count in the status. +func (s *State) UpdateReady(count int) *State { + s.status.Ready = count + return s +} + +// UpdateErrors updates the Errors count in the status. +func (s *State) UpdateErrors(count int) *State { + s.status.Errors = count + return s +} + +// Apply takes the current AutoOpsAgentPolicy status, compares it to the previous status, and updates the status accordingly. +// It returns the events to emit and an updated version of the AutoOpsAgentPolicy resource with +// the current status applied to its status sub-resource. +func (s *State) Apply() ([]events.Event, *autoopsv1alpha1.AutoOpsAgentPolicy) { + previous := s.policy.Status + current := s.status + if reflect.DeepEqual(previous, current) { + return s.Events(), nil + } + s.policy.Status = current + return s.Events(), &s.policy +} From 7e75762baebd05e160efcca4a73a9f116bb995f1 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 4 Dec 2025 17:32:12 -0600 Subject: [PATCH 26/90] Re-enable license checks Signed-off-by: Michael Montgomery --- pkg/controller/common/license/check.go | 47 +++++++++++++------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/pkg/controller/common/license/check.go b/pkg/controller/common/license/check.go index 62c81a75eb5..292c8bed33d 100644 --- a/pkg/controller/common/license/check.go +++ b/pkg/controller/common/license/check.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "sort" + "time" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" @@ -90,34 +91,32 @@ func (lc *checker) CurrentEnterpriseLicense(ctx context.Context) (*EnterpriseLic // EnterpriseFeaturesEnabled returns true if a valid enterprise license is installed. func (lc *checker) EnterpriseFeaturesEnabled(ctx context.Context) (bool, error) { - return true, nil - // license, err := lc.CurrentEnterpriseLicense(ctx) - // if err != nil { - // return false, err - // } - // return license != nil, nil + license, err := lc.CurrentEnterpriseLicense(ctx) + if err != nil { + return false, err + } + return license != nil, nil } // Valid returns true if the given Enterprise license is valid or an error if any. func (lc *checker) Valid(ctx context.Context, l EnterpriseLicense) (bool, error) { - return true, nil - // pk, err := lc.publicKeyFor(l) - // if err != nil { - // return false, errors.Wrap(err, "while loading signature secret") - // } - // if len(pk) == 0 { - // ulog.FromContext(ctx).Info("This is an unlicensed development build of ECK. License management and Enterprise features are disabled") - // return false, nil - // } - // verifier, err := NewVerifier(pk) - // if err != nil { - // return false, err - // } - // status := verifier.Valid(ctx, l, time.Now()) - // if status == LicenseStatusValid { - // return true, nil - // } - // return false, nil + pk, err := lc.publicKeyFor(l) + if err != nil { + return false, errors.Wrap(err, "while loading signature secret") + } + if len(pk) == 0 { + ulog.FromContext(ctx).Info("This is an unlicensed development build of ECK. License management and Enterprise features are disabled") + return false, nil + } + verifier, err := NewVerifier(pk) + if err != nil { + return false, err + } + status := verifier.Valid(ctx, l, time.Now()) + if status == LicenseStatusValid { + return true, nil + } + return false, nil } // ValidOperatorLicenseKeyType returns true if the current operator license key is valid From 065f3d76fb504838edacd334f78831699a864398 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 09:42:48 -0600 Subject: [PATCH 27/90] Changes from initial review. Signed-off-by: Michael Montgomery --- config/crds/v1/all-crds.yaml | 1 - ...autoops.k8s.elastic.co_autoopsagentpolicies.yaml | 1 - .../eck-operator-crds/templates/all-crds.yaml | 1 - docs/reference/api-reference/main.md | 2 +- pkg/apis/autoops/v1alpha1/validations.go | 7 +++++++ pkg/apis/autoops/v1alpha1/webhook.go | 1 + pkg/controller/autoops/api_key.go | 13 +++++++++++-- pkg/controller/autoops/configmap.go | 1 - pkg/controller/autoops/configuration.go | 1 - pkg/controller/autoops/controller.go | 10 +++++----- pkg/controller/autoops/expected.go | 8 ++++++-- pkg/controller/autoops/reconcile.go | 4 ++++ pkg/controller/remotecluster/controller.go | 2 +- 13 files changed, 36 insertions(+), 16 deletions(-) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 56f188f8df6..ac50ce23e65 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2418,7 +2418,6 @@ spec: name: autoops-agent-policy-config stringData: ccmApiKey: aslkfjsldkjfslkdjflksdjfl - tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf properties: diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index c19dc6f5268..f0453829133 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -64,7 +64,6 @@ spec: name: autoops-agent-policy-config stringData: ccmApiKey: aslkfjsldkjfslkdjflksdjfl - tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf properties: diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 17b4fabc7b5..bfbb13e6fe7 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2439,7 +2439,6 @@ spec: name: autoops-agent-policy-config stringData: ccmApiKey: aslkfjsldkjfslkdjflksdjfl - tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co autoOpsToken: skdfjdskjf properties: diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index c023d65a975..e63e941010d 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -293,7 +293,7 @@ AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes clu | --- | --- | | *`version`* __string__ | Version of the AutoOpsAgentPolicy. | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | -| *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
tempResourceID: u857abce4-9214-446b-951c-a1644b7d204ao
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | diff --git a/pkg/apis/autoops/v1alpha1/validations.go b/pkg/apis/autoops/v1alpha1/validations.go index 62d13127a8a..7d7682c2790 100644 --- a/pkg/apis/autoops/v1alpha1/validations.go +++ b/pkg/apis/autoops/v1alpha1/validations.go @@ -18,3 +18,10 @@ func checkNameLength(policy *AutoOpsAgentPolicy) field.ErrorList { func checkSupportedVersion(policy *AutoOpsAgentPolicy) field.ErrorList { return commonv1.CheckSupportedStackVersion(policy.Spec.Version, version.SupportedAutoOpsAgentVersions) } + +func checkConfigSecretName(policy *AutoOpsAgentPolicy) field.ErrorList { + if policy.Spec.Config.SecretName == "" { + return field.ErrorList{field.Required(field.NewPath("spec").Child("config").Child("secretName"), "Config secret name must be specified")} + } + return nil +} diff --git a/pkg/apis/autoops/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go index 6d9a74a7b58..8801814aa77 100644 --- a/pkg/apis/autoops/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -27,6 +27,7 @@ var ( checkNoUnknownFields, checkNameLength, checkSupportedVersion, + checkConfigSecretName, validSettings, } ) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 70bd189263d..f686581d077 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -131,7 +131,7 @@ func createAPIKey( log.Info("Creating API key", "key", apiKeyName) metadata := newMetadataFor(&policy, &es, expectedHash) - // Unfortunatelly we need to convert the metadata to a map[string]any to satisfy the APIKeyCreateRequest type. + // Unfortunately we need to convert the metadata to a map[string]any to satisfy the APIKeyCreateRequest type. // We return map[string]string because this is also used when storing the API key in a secret. metadataAny := make(map[string]any, len(metadata)) for k, v := range metadata { @@ -301,9 +301,18 @@ func buildAutoOpsESAPIKeySecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es es } } +// IsManagedByAutoOps checks if an API key is managed by the autoops controller. +func IsManagedByAutoOps(metadata map[string]any) bool { + if metadata == nil { + return false + } + _, exists := metadata[PolicyNameLabelKey] + return exists +} + // apiKeyNameFor generates a unique name for the API key according to the policy, and ES instance. func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) string { - return fmt.Sprintf("eck-autoops-%s-%s-%s-%s", policy.Namespace, policy.Name, es.Namespace, es.Name) + return fmt.Sprintf("autoops-%s-%s-%s-%s", policy.Namespace, policy.Name, es.Namespace, es.Name) } // apiKeySecretNameFrom generates the name for the API key secret from an ES instance. diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 5930149e1e5..2dcaafd1551 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -71,7 +71,6 @@ const autoOpsESConfigTemplate = `receivers: - add_fields: target: autoops_es fields: - temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} token: ${env:AUTOOPS_TOKEN} output: otelconsumer: {} diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 196bfe10a8c..5c4128c06fd 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -18,7 +18,6 @@ import ( // Config holds the parsed configuration from the AutoOpsAgentPolicy configuration secret. type Config struct { CCMApiKey string - TempResourceID string AutoOpsOTelURL string AutoOpsToken string } diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 1c62d556b53..315b4897a51 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -111,6 +111,11 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, tracing.CaptureError(ctx, err) } + if common.IsUnmanaged(ctx, &policy) { + ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") + return reconcile.Result{}, nil + } + state := NewState(policy) results := reconciler.NewResult(ctx) @@ -140,11 +145,6 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return reconcile.Result{}, tracing.CaptureError(ctx, err) } - if common.IsUnmanaged(ctx, &policy) { - ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") - return reconcile.Result{}, nil - } - if policy.IsMarkedForDeletion() { return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 16faf757c35..165c2456f0f 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + package autoops import ( @@ -75,7 +79,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli autoOpsLabelName: policy.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(es.Name, es.GetNamespace(), "deploy"), + Name: AutoOpsNamer.Suffix(policy.GetName(), policy.GetNamespace(), es.GetName(), es.GetNamespace(), "deploy"), Namespace: policy.GetNamespace(), Labels: labels, } @@ -83,7 +87,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli Replicas: pointer.Int32(1), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - autoOpsLabelName: policy.Name, + autoOpsLabelName: policy.GetName(), }, }, } diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 7140cb3fbba..3250e93c1b2 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + package autoops import ( diff --git a/pkg/controller/remotecluster/controller.go b/pkg/controller/remotecluster/controller.go index bb4f98aec88..f56caeb24cf 100644 --- a/pkg/controller/remotecluster/controller.go +++ b/pkg/controller/remotecluster/controller.go @@ -272,7 +272,7 @@ func doReconcile( // ************************************************************** for _, activeAPIKey := range activeAPIKeys.APIKeys { // Skip API keys managed by the autoops controller. - if activeAPIKey.Metadata != nil && activeAPIKey.Metadata[autoops.PolicyNameLabelKey] != nil { + if autoops.IsManagedByAutoOps(activeAPIKey.Metadata) { continue } clientCluster, err := activeAPIKey.GetElasticsearchName() From e6879454ce55bec27207e79c95bf6ff00a281ac6 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 10:22:29 -0600 Subject: [PATCH 28/90] Cleanup some of the reconcile logic. Signed-off-by: Michael Montgomery --- .../v1alpha1/autoopsagentpolicy_types.go | 2 - pkg/controller/autoops/api_key.go | 26 ++++++---- pkg/controller/autoops/configuration.go | 6 +-- pkg/controller/autoops/configuration_test.go | 10 ++-- pkg/controller/autoops/controller.go | 50 ++++++------------- pkg/controller/autoops/expected_test.go | 19 +++---- pkg/controller/autoops/reconcile.go | 10 ++++ 7 files changed, 55 insertions(+), 68 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 1538d7094c9..825e8e74943 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -14,8 +14,6 @@ const ( // Kind is inferred from the struct name using reflection in SchemeBuilder.Register() // we duplicate it as a constant here for practical purposes. Kind = "AutoOpsAgentPolicy" - - unknownVersion = 0 ) func init() { diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index f686581d077..5b13b0d2f27 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -35,7 +35,7 @@ var ( const ( // autoOpsESAPIKeySecretNameSuffix is the suffix for API key secrets created for each ES instance - autoOpsESAPIKeySecretNameSuffix = "autoops-es-api-key" + autoOpsESAPIKeySecretNameSuffix = "autoops-es-api-key" //nolint:gosec // managedByMetadataKey is the metadata key indicating the API key is managed by ECK. // This is used when storing the API key in Elasticsearch to clearly identify it as managed by ECK. // This is not included in the labels of the secret. @@ -84,9 +84,14 @@ func reconcileAutoOpsESAPIKey( } defer esClient.Close() + stackMonitoringUserRole, ok := esuser.PredefinedRoles[esuser.StackMonitoringUserRole].(esclient.Role) + if !ok { + return fmt.Errorf("stackMonitoringUserRole could not be converted to esclient.Role") + } + apiKeySpec := apiKeySpec{ roleDescriptors: map[string]esclient.Role{ - "eck_autoops_role": defaultMonitoringRole, + "eck_autoops_role": stackMonitoringUserRole, }, } @@ -222,15 +227,14 @@ func invalidateAndCreateAPIKey( func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { if apiKey.Metadata == nil { return true - } else { - managedBy, ok := apiKey.Metadata[managedByMetadataKey].(string) - if !ok || managedBy != managedByValue { - return true - } - currentHash, ok := apiKey.Metadata[configHashMetadataKey].(string) - if !ok || currentHash != expectedHash { - return true - } + } + managedBy, ok := apiKey.Metadata[managedByMetadataKey].(string) + if !ok || managedBy != managedByValue { + return true + } + currentHash, ok := apiKey.Metadata[configHashMetadataKey].(string) + if !ok || currentHash != expectedHash { + return true } return false } diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 5c4128c06fd..35656fb8b9f 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -24,7 +24,7 @@ type Config struct { const ( // Secret key names for the configuration fields - ccmApiKey = "cloud-connected-mode-api-key" + ccmAPIKey = "cloud-connected-mode-api-key" autoOpsOTelURL = "autoops-otel-url" autoOpsToken = "autoops-token" ) @@ -50,10 +50,10 @@ func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.N func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedName) (*Config, error) { var config Config - if data, exists := secret.Data[ccmApiKey]; exists && len(data) > 0 { + if data, exists := secret.Data[ccmAPIKey]; exists && len(data) > 0 { config.CCMApiKey = string(data) } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", ccmApiKey, secretKey.Namespace, secretKey.Name) + return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", ccmAPIKey, secretKey.Namespace, secretKey.Name) } if data, exists := secret.Data[autoOpsOTelURL]; exists && len(data) > 0 { diff --git a/pkg/controller/autoops/configuration_test.go b/pkg/controller/autoops/configuration_test.go index 5fc26823ca5..8d7aade9d9a 100644 --- a/pkg/controller/autoops/configuration_test.go +++ b/pkg/controller/autoops/configuration_test.go @@ -28,7 +28,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - ccmApiKey: []byte("ccm-api-key-value"), + ccmAPIKey: []byte("ccm-api-key-value"), autoOpsOTelURL: []byte("https://otel.example.com"), autoOpsToken: []byte("token-value"), }, @@ -65,7 +65,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - ccmApiKey: []byte("ccm-api-key-value"), + ccmAPIKey: []byte("ccm-api-key-value"), autoOpsToken: []byte("token-value"), }, }, @@ -81,7 +81,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - ccmApiKey: []byte("ccm-api-key-value"), + ccmAPIKey: []byte("ccm-api-key-value"), autoOpsOTelURL: []byte("https://otel.example.com"), }, }, @@ -97,7 +97,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - ccmApiKey: []byte(""), + ccmAPIKey: []byte(""), autoOpsOTelURL: []byte(""), autoOpsToken: []byte(""), }, @@ -140,7 +140,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - ccmApiKey: []byte("ccm-api-key-value"), + ccmAPIKey: []byte("ccm-api-key-value"), autoOpsOTelURL: []byte("https://otel.example.com"), autoOpsToken: []byte("token-value"), "extra-field": []byte("extra-value"), diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 315b4897a51..96154fcbda7 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -29,7 +29,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" - "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/tracing" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -117,39 +116,12 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } state := NewState(policy) - results := reconciler.NewResult(ctx) - - _, err = ParseConfigSecret(ctx, r.Client, types.NamespacedName{ - Namespace: policy.Namespace, - Name: policy.Spec.Config.SecretRef.SecretName, - }) - if err != nil { - if apierrors.IsNotFound(err) { - state.UpdateInvalidPhaseWithEvent("Config secret not found") - // update status before returning - if err := r.updateStatusFromState(ctx, state); err != nil { - if apierrors.IsConflict(err) { - return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil - } - return reconcile.Result{}, tracing.CaptureError(ctx, err) - } - return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil - } - state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - // update status before returning - if err := r.updateStatusFromState(ctx, state); err != nil { - if apierrors.IsConflict(err) { - return reconcile.Result{Requeue: true, RequeueAfter: defaultRequeue}, nil - } - } - return reconcile.Result{}, tracing.CaptureError(ctx, err) - } if policy.IsMarkedForDeletion() { return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } - results = r.doReconcile(ctx, policy, state) + results := r.doReconcile(ctx, policy, state) if state.status.Phase != autoopsv1alpha1.InvalidPhase && state.status.Phase != autoopsv1alpha1.ErrorPhase { if isReconciled, _ := results.IsReconciled(); !isReconciled { @@ -159,11 +131,11 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } } - if err := r.updateStatusFromState(ctx, state); err != nil { - if apierrors.IsConflict(err) { - return results.WithRequeue().Aggregate() - } + result, err := r.updateStatusFromState(ctx, state) + if err != nil { results.WithError(err) + } else if result.RequeueAfter > 0 { + return results.WithRequeue().Aggregate() } return results.Aggregate() @@ -182,7 +154,7 @@ func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *auto return nil } -func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, state *State) error { +func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { span, _ := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() @@ -193,14 +165,20 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, } if policy == nil { ulog.FromContext(ctx).V(1).Info("Status is up to date", "iteration", atomic.LoadUint64(&r.iteration)) - return nil + return reconcile.Result{}, nil } ulog.FromContext(ctx).V(1).Info("Updating status", "iteration", atomic.LoadUint64(&r.iteration), "status", policy.Status, ) - return common.UpdateStatus(ctx, r.Client, policy) + if err := common.UpdateStatus(ctx, r.Client, policy); err != nil { + if apierrors.IsConflict(err) { + return reconcile.Result{RequeueAfter: defaultRequeue}, nil + } + return reconcile.Result{}, tracing.CaptureError(ctx, err) + } + return reconcile.Result{}, nil } func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 176c8664e13..227282a5b32 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -60,7 +60,6 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { tests := []struct { name string args args - want appsv1.Deployment wantErr bool }{ { @@ -69,7 +68,6 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { autoops: autoopsFixture, es: esFixture, }, - want: appsv1.Deployment{}, // Will be computed in test wantErr: false, }, { @@ -86,7 +84,6 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, es: esFixture, }, - want: appsv1.Deployment{}, wantErr: true, }, } @@ -128,11 +125,11 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { } } -func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, configHashValue string) appsv1.Deployment { - v, _ := version.Parse(autoops.Spec.Version) +func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, configHashValue string) appsv1.Deployment { + v, _ := version.Parse(policy.Spec.Version) labels := map[string]string{ commonv1.TypeLabelName: "autoops-agent", - "autoops.k8s.elastic.co/name": autoops.Name, + "autoops.k8s.elastic.co/name": policy.GetName(), } annotations := map[string]string{ @@ -141,15 +138,15 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(es.Name, es.GetNamespace(), "deploy"), - Namespace: autoops.GetNamespace(), + Name: AutoOpsNamer.Suffix(policy.GetName(), policy.GetNamespace(), es.GetName(), es.GetNamespace(), "deploy"), + Namespace: policy.GetNamespace(), Labels: labels, }, Spec: appsv1.DeploymentSpec{ Replicas: pointer.Int32(1), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "autoops.k8s.elastic.co/name": autoops.Name, + "autoops.k8s.elastic.co/name": policy.GetName(), }, }, Template: corev1.PodTemplateSpec{ @@ -164,7 +161,7 @@ func expectedDeployment(autoops autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elas VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name), + Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, policy.GetNamespace(), es.GetName()), }, DefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode), Optional: ptr.To(false), @@ -352,7 +349,7 @@ func Test_autoopsEnvVars(t *testing.T) { }, { Name: "AUTOOPS_ES_URL", - Value: "http://es-1-es-internal-http.ns-1.svc:9200", + Value: "https://es-1-es-internal-http.ns-1.svc:9200", }, { Name: "AUTOOPS_OTEL_URL", diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 3250e93c1b2..222bafe94d8 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -11,6 +11,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" @@ -61,6 +62,15 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") + _, err := ParseConfigSecret(ctx, r.Client, types.NamespacedName{ + Namespace: policy.Namespace, + Name: policy.Spec.Config.SecretRef.SecretName, + }) + if err != nil { + state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + return results.WithError(err) + } + // prepare the selector to find resources. selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{ MatchLabels: policy.Spec.ResourceSelector.MatchLabels, From 8b9a87138ed05a23bd78f87d4ba58eeba890c1da Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 11:22:33 -0600 Subject: [PATCH 29/90] Adjust to allow error counts to be calculated. Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 4 ---- pkg/controller/autoops/reconcile.go | 13 +++++++------ pkg/controller/autoops/secret.go | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 5b13b0d2f27..ba6048999ad 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -29,10 +29,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/utils/net" ) -var ( - defaultMonitoringRole = esuser.PredefinedRoles[esuser.StackMonitoringUserRole].(esclient.Role) -) - const ( // autoOpsESAPIKeySecretNameSuffix is the suffix for API key secrets created for each ES instance autoOpsESAPIKeySecretNameSuffix = "autoops-es-api-key" //nolint:gosec diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 222bafe94d8..78f1161533d 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -117,37 +117,38 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( if err := reconcileAutoOpsESCASecret(ctx, r.Client, policy, es); err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - return results.WithError(err) + continue } } if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - return results.WithError(err) + continue } if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy, es); err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - return results.WithError(err) + continue } expectedResources, err := r.generateExpectedResources(ctx, policy, es) if err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - return results.WithError(err) + continue } reconciledDeployment, err := deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &policy) if err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) - return results.WithError(err) + continue } - if isDeploymentReady(reconciledDeployment) { + // Only increment readyCount if there are no errors in previous ES instances. + if isDeploymentReady(reconciledDeployment) && errorCount == 0 { readyCount++ } } diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 9e0c8f8550a..d94c95188ff 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -26,7 +26,7 @@ import ( const ( // autoOpsESCASecretSuffix is the suffix for CA secrets created for each ES instance - autoOpsESCASecretSuffix = "autoops-es-ca" + autoOpsESCASecretSuffix = "autoops-es-ca" //nolint:gosec ) // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate From f4e1734222753ddb387858ff73505ea77fed7836 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 11:47:58 -0600 Subject: [PATCH 30/90] Nolint Add header Signed-off-by: Michael Montgomery --- pkg/apis/autoops/v1alpha1/validations.go | 4 ++++ pkg/controller/remotecluster/controller.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/apis/autoops/v1alpha1/validations.go b/pkg/apis/autoops/v1alpha1/validations.go index 7d7682c2790..59e9355f25a 100644 --- a/pkg/apis/autoops/v1alpha1/validations.go +++ b/pkg/apis/autoops/v1alpha1/validations.go @@ -1,3 +1,7 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + package v1alpha1 import ( diff --git a/pkg/controller/remotecluster/controller.go b/pkg/controller/remotecluster/controller.go index f56caeb24cf..cf22f79430b 100644 --- a/pkg/controller/remotecluster/controller.go +++ b/pkg/controller/remotecluster/controller.go @@ -266,7 +266,7 @@ func doReconcile( results.WithResults(reconcileAPIKeys(ctx, r.Client, activeAPIKeys, remoteServer, remoteClient, remoteClusterRefs, esClient, r.keystoreProvider)) } - if remoteServerSupportsClusterAPIKeys.IsTrue() { + if remoteServerSupportsClusterAPIKeys.IsTrue() { //nolint:nestif // ************************************************************** // Delete orphaned API keys from clusters which have been deleted // ************************************************************** From 25ff367eb8693936a554c08c0dcc15fd9bc820ad Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 13:10:22 -0600 Subject: [PATCH 31/90] Lint issues Signed-off-by: Michael Montgomery --- cmd/manager/main.go | 4 ++-- pkg/apis/autoops/v1alpha1/doc.go | 1 - pkg/apis/autoops/v1alpha1/groupversion_info.go | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 0f207b58bc6..6d4573c2609 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -44,8 +44,8 @@ import ( agentv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/agent/v1alpha1" apmv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1" apmv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/apm/v1beta1" - beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + beatv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/beat/v1beta1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" esv1beta1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1beta1" entv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/enterprisesearch/v1" @@ -59,10 +59,10 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/apmserver" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/association" associationctl "github.com/elastic/cloud-on-k8s/v3/pkg/controller/association/controller" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoops" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling" esavalidation "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoscaling/elasticsearch/validation" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/beat" - "github.com/elastic/cloud-on-k8s/v3/pkg/controller/autoops" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container" commonlicense "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" diff --git a/pkg/apis/autoops/v1alpha1/doc.go b/pkg/apis/autoops/v1alpha1/doc.go index dbc4d5f3de0..ac95ac073a2 100644 --- a/pkg/apis/autoops/v1alpha1/doc.go +++ b/pkg/apis/autoops/v1alpha1/doc.go @@ -6,4 +6,3 @@ // +kubebuilder:object:generate=true // +groupName=autoops.k8s.elastic.co package v1alpha1 - diff --git a/pkg/apis/autoops/v1alpha1/groupversion_info.go b/pkg/apis/autoops/v1alpha1/groupversion_info.go index d7c29f750fd..967a4cdf7c6 100644 --- a/pkg/apis/autoops/v1alpha1/groupversion_info.go +++ b/pkg/apis/autoops/v1alpha1/groupversion_info.go @@ -19,4 +19,3 @@ var ( // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme ) - From 6271eed980104c36ca6fb7ed1adf33d09a8139e3 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 13:40:06 -0600 Subject: [PATCH 32/90] re-enable temp_resource_id, but generate it --- pkg/controller/autoops/configmap.go | 1 + pkg/controller/autoops/expected.go | 17 ++++++++++++++--- pkg/controller/autoops/expected_test.go | 20 ++++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 2dcaafd1551..c583d4f7c24 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -72,6 +72,7 @@ const autoOpsESConfigTemplate = `receivers: target: autoops_es fields: token: ${env:AUTOOPS_TOKEN} + temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} output: otelconsumer: {} telemetry_types: ["logs"] diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 165c2456f0f..a5f350ce302 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "encoding/base64" "fmt" "hash/fnv" "path" @@ -79,7 +80,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli autoOpsLabelName: policy.Name, } deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), policy.GetNamespace(), es.GetName(), es.GetNamespace(), "deploy"), + Name: AutoOpsNamer.Suffix(policy.GetName(), es.GetName(), es.GetNamespace()), Namespace: policy.GetNamespace(), Labels: labels, } @@ -123,7 +124,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). - WithEnv(autoopsEnvVars(es)...). + WithEnv(autoopsEnvVars(policy, es)...). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). WithPorts([]corev1.ContainerPort{{Name: "http", ContainerPort: int32(readinessProbePort), Protocol: corev1.ProtocolTCP}}). @@ -192,7 +193,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A // autoopsEnvVars returns the environment variables for the AutoOps deployment // that reference values from the autoops-secret and the ES elastic user secret. -func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { +func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) []corev1.EnvVar { esService := services.InternalServiceURL(es) return []corev1.EnvVar{ { @@ -233,6 +234,10 @@ func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { }, }, }, + { + Name: "AUTOOPS_TEMP_RESOURCE_ID", + Value: tempResourceID(policy, es), + }, { Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", ValueFrom: &corev1.EnvVarSource{ @@ -258,3 +263,9 @@ func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { }, } } + +// tempResourceID returns the base64 encoded temp resource ID for the AutoOps deployment. +// It uses the policy name, the ES name, and the ES namespace to create a unique ID. +func tempResourceID(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) string { + return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s-%s-%s", policy.GetName(), es.GetName(), es.GetNamespace()))) +} diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 227282a5b32..0af5ec9c679 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "encoding/base64" "fmt" "hash/fnv" "testing" @@ -323,9 +324,10 @@ func Test_readinessProbe(t *testing.T) { func Test_autoopsEnvVars(t *testing.T) { tests := []struct { - name string - es esv1.Elasticsearch - want []corev1.EnvVar + name string + es esv1.Elasticsearch + policy autoopsv1alpha1.AutoOpsAgentPolicy + want []corev1.EnvVar }{ { name: "Happy path", @@ -335,6 +337,12 @@ func Test_autoopsEnvVars(t *testing.T) { Namespace: "ns-1", }, }, + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-2", + }, + }, want: []corev1.EnvVar{ { Name: "AUTOOPS_TOKEN", @@ -374,6 +382,10 @@ func Test_autoopsEnvVars(t *testing.T) { }, }, }, + { + Name: "AUTOOPS_TEMP_RESOURCE_ID", + Value: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s-%s-%s", "policy-1", "es-1", "ns-1"))), + }, { Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", ValueFrom: &corev1.EnvVarSource{ @@ -402,7 +414,7 @@ func Test_autoopsEnvVars(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := autoopsEnvVars(tt.es) + got := autoopsEnvVars(tt.policy, tt.es) if !cmp.Equal(got, tt.want) { t.Errorf("autoopsEnvVars() diff = %v", cmp.Diff(got, tt.want)) } From 36b8fe58c305390091b849d3d3f2da7f7943570f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 5 Dec 2025 15:40:31 -0600 Subject: [PATCH 33/90] remove temp resource id --- pkg/controller/autoops/configmap.go | 1 - pkg/controller/autoops/expected.go | 15 ++------------- pkg/controller/autoops/expected_test.go | 9 ++------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index c583d4f7c24..2dcaafd1551 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -72,7 +72,6 @@ const autoOpsESConfigTemplate = `receivers: target: autoops_es fields: token: ${env:AUTOOPS_TOKEN} - temp_resource_id: ${env:AUTOOPS_TEMP_RESOURCE_ID} output: otelconsumer: {} telemetry_types: ["logs"] diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index a5f350ce302..b59576f8deb 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "encoding/base64" "fmt" "hash/fnv" "path" @@ -124,7 +123,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). - WithEnv(autoopsEnvVars(policy, es)...). + WithEnv(autoopsEnvVars(es)...). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). WithPorts([]corev1.ContainerPort{{Name: "http", ContainerPort: int32(readinessProbePort), Protocol: corev1.ProtocolTCP}}). @@ -193,7 +192,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A // autoopsEnvVars returns the environment variables for the AutoOps deployment // that reference values from the autoops-secret and the ES elastic user secret. -func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) []corev1.EnvVar { +func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { esService := services.InternalServiceURL(es) return []corev1.EnvVar{ { @@ -234,10 +233,6 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse }, }, }, - { - Name: "AUTOOPS_TEMP_RESOURCE_ID", - Value: tempResourceID(policy, es), - }, { Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", ValueFrom: &corev1.EnvVarSource{ @@ -263,9 +258,3 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse }, } } - -// tempResourceID returns the base64 encoded temp resource ID for the AutoOps deployment. -// It uses the policy name, the ES name, and the ES namespace to create a unique ID. -func tempResourceID(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) string { - return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s-%s-%s", policy.GetName(), es.GetName(), es.GetNamespace()))) -} diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 0af5ec9c679..26e35b99de4 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "encoding/base64" "fmt" "hash/fnv" "testing" @@ -139,7 +138,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), policy.GetNamespace(), es.GetName(), es.GetNamespace(), "deploy"), + Name: AutoOpsNamer.Suffix(policy.GetName(), es.GetName(), es.GetNamespace()), Namespace: policy.GetNamespace(), Labels: labels, }, @@ -382,10 +381,6 @@ func Test_autoopsEnvVars(t *testing.T) { }, }, }, - { - Name: "AUTOOPS_TEMP_RESOURCE_ID", - Value: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s-%s-%s", "policy-1", "es-1", "ns-1"))), - }, { Name: "ELASTIC_CLOUD_CONNECTED_MODE_API_KEY", ValueFrom: &corev1.EnvVarSource{ @@ -414,7 +409,7 @@ func Test_autoopsEnvVars(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := autoopsEnvVars(tt.policy, tt.es) + got := autoopsEnvVars(tt.es) if !cmp.Equal(got, tt.want) { t.Errorf("autoopsEnvVars() diff = %v", cmp.Diff(got, tt.want)) } From db322a5ae63501d4048ea5c0d82ea328ac8f047b Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 8 Dec 2025 09:33:11 -0600 Subject: [PATCH 34/90] adjust description of autoops crd Signed-off-by: Michael Montgomery --- config/crds/v1/all-crds.yaml | 2 +- .../resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml | 2 +- .../charts/eck-operator-crds/templates/all-crds.yaml | 2 +- docs/reference/api-reference/main.md | 2 +- pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index ac50ce23e65..5975229189f 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2386,7 +2386,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + description: AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes cluster. properties: apiVersion: diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index f0453829133..647b1635db8 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -32,7 +32,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + description: AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes cluster. properties: apiVersion: diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index bfbb13e6fe7..3466e2f282b 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2407,7 +2407,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource + description: AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes cluster. properties: apiVersion: diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index e63e941010d..29d4118ae8a 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -268,7 +268,7 @@ Package v1alpha1 contains API schema definitions for managing AutoOpsAgentPolicy ### AutoOpsAgentPolicy [#autoopsagentpolicy] -AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. +AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes cluster. diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 825e8e74943..1e29ce9a42c 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -22,7 +22,7 @@ func init() { // +kubebuilder:object:root=true -// AutoOpsAgentPolicy represents an AutoOpsAgentPolicy resource in a Kubernetes cluster. +// AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes cluster. // +kubebuilder:resource:categories=elastic,shortName=autoops // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Ready resources" // +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" From 0ba68492f4c5f941f832ec1dd2e745598595d3ad Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 8 Dec 2025 14:57:53 -0600 Subject: [PATCH 35/90] ensuring deployment name max length isnt exceeded --- deploy/eck-stack/charts/eck-autoops/examples/basic.yaml | 4 ++-- pkg/controller/autoops/expected.go | 5 +++-- pkg/controller/common/name/name.go | 6 ++++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml index e0cb05817c2..3193b5af34d 100644 --- a/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml +++ b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml @@ -10,10 +10,10 @@ ccmApiKey: "your-api-key-here" autoOpsOTelURL: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" autoOpsToken: "your-token-here" -# Optional: Override the default secret name. +# Secret name for the AutoOps configuration. # If not specified, defaults to the fullname of the chart with '-secret' suffix. # -# secretName: "custom-secret-name" +# secretName: "" # ResourceSelector is a label selector for the resources to be configured. # Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index b59576f8deb..1cf1ea143e1 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -41,8 +41,9 @@ const ( var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments - // according to the associated Elasticsearch cluster name. - AutoOpsNamer = common_name.NewNamer("autoops") + // according to the Policy name, and associated Elasticsearch name ensuring + // the name doesn't exceed the max length of 27 characters for deployments. + AutoOpsNamer = common_name.NewNamer("autoops").WithMaxNameLength(27) basePodTemplate = corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ diff --git a/pkg/controller/common/name/name.go b/pkg/controller/common/name/name.go index dbaf05dec2d..ea7b8b097de 100644 --- a/pkg/controller/common/name/name.go +++ b/pkg/controller/common/name/name.go @@ -64,6 +64,12 @@ func NewNamer(defaultSuffixes ...string) Namer { } } +// WithMaxNameLength returns a new Namer with updated max name length. +func (n Namer) WithMaxNameLength(length int) Namer { + n.MaxNameLength = length + return n +} + // WithDefaultSuffixes returns a new Namer with updated default suffixes. func (n Namer) WithDefaultSuffixes(defaultSuffixes ...string) Namer { n.DefaultSuffixes = defaultSuffixes From 2e5ccd103c0642e06806bd604e950f89bea0e15d Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 8 Dec 2025 16:33:49 -0600 Subject: [PATCH 36/90] adjust naming to avoid long names --- pkg/controller/autoops/expected.go | 12 ++++++++---- pkg/controller/autoops/expected_test.go | 6 +++++- pkg/controller/common/name/name.go | 6 ------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 1cf1ea143e1..6f201882619 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "crypto/sha256" "fmt" "hash/fnv" "path" @@ -41,9 +42,8 @@ const ( var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments - // according to the Policy name, and associated Elasticsearch name ensuring - // the name doesn't exceed the max length of 27 characters for deployments. - AutoOpsNamer = common_name.NewNamer("autoops").WithMaxNameLength(27) + // according to the Policy name, and associated Elasticsearch name. + AutoOpsNamer = common_name.NewNamer("autoops") basePodTemplate = corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ @@ -79,8 +79,12 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli commonv1.TypeLabelName: "autoops-agent", autoOpsLabelName: policy.Name, } + // Hash ES namespace and name to create a short unique identifier + // preventing name length issues. + esIdentifier := es.GetNamespace() + es.GetName() + esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), es.GetName(), es.GetNamespace()), + Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), Namespace: policy.GetNamespace(), Labels: labels, } diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 26e35b99de4..eca8a08a10a 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "crypto/sha256" "fmt" "hash/fnv" "testing" @@ -136,9 +137,12 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast configHashAnnotationName: configHashValue, } + // Hash ES namespace and name to match the implementation + esIdentifier := es.GetNamespace() + es.GetName() + esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:8] return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), es.GetName(), es.GetNamespace()), + Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), Namespace: policy.GetNamespace(), Labels: labels, }, diff --git a/pkg/controller/common/name/name.go b/pkg/controller/common/name/name.go index ea7b8b097de..dbaf05dec2d 100644 --- a/pkg/controller/common/name/name.go +++ b/pkg/controller/common/name/name.go @@ -64,12 +64,6 @@ func NewNamer(defaultSuffixes ...string) Namer { } } -// WithMaxNameLength returns a new Namer with updated max name length. -func (n Namer) WithMaxNameLength(length int) Namer { - n.MaxNameLength = length - return n -} - // WithDefaultSuffixes returns a new Namer with updated default suffixes. func (n Namer) WithDefaultSuffixes(defaultSuffixes ...string) Namer { n.DefaultSuffixes = defaultSuffixes From 83f31b58b1d35e33b84c4d3978904aea46da01c7 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 8 Dec 2025 21:41:44 -0600 Subject: [PATCH 37/90] update charts --- deploy/eck-stack/charts/eck-autoops/examples/basic.yaml | 2 +- .../charts/eck-autoops/templates/autoopsagentpolicy.yaml | 2 +- deploy/eck-stack/charts/eck-autoops/values.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml index 3193b5af34d..42cd274906f 100644 --- a/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml +++ b/deploy/eck-stack/charts/eck-autoops/examples/basic.yaml @@ -1,7 +1,7 @@ --- # Version of AutoOps Agent Policy. # -version: 9.2.0 +version: 9.3.0-SNAPSHOT # AutoOps configuration values. # These values are required and will be used to create a Kubernetes Secret. diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml index 0948dc030db..8f4e793ffaf 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -13,7 +13,7 @@ metadata: spec: version: {{ required "An AutoOps Agent Policy version is required" .Values.version }} config: - secretName: {{ include "autoops.secretName" . }} + secretName: {{ required "An AutoOps Agent Policy secretName is required" (include "autoops.secretName" .) }} {{- with .Values.resourceSelector }} resourceSelector: {{- toYaml . | nindent 4 }} diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index f3c20fe11ce..0ff672e0277 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -18,7 +18,7 @@ # Version of AutoOps Agent Policy. # -version: 9.2.0 +version: 9.3.0-SNAPSHOT # Labels that will be applied to AutoOps Agent Policy. # @@ -46,7 +46,7 @@ autoOpsToken: "" cloudConnectedModeAPIURL: "" # Secret name for the AutoOps configuration. -# If not specified, defaults to the fullname of the chart with '-secret' suffix. +# This is not a required field. # # secretName: "" From 4110a014ec2a24a69a05d6a25997774421456da9 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Mon, 8 Dec 2025 21:50:59 -0600 Subject: [PATCH 38/90] review adjustments --- deploy/eck-stack/Chart.yaml | 2 +- pkg/apis/autoops/v1alpha1/webhook.go | 2 +- pkg/controller/autoops/controller.go | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/deploy/eck-stack/Chart.yaml b/deploy/eck-stack/Chart.yaml index fbb89126dc3..d3d6b041d87 100644 --- a/deploy/eck-stack/Chart.yaml +++ b/deploy/eck-stack/Chart.yaml @@ -32,4 +32,4 @@ dependencies: version: "0.18.0-SNAPSHOT" - name: eck-autoops condition: eck-autoops.enabled - version: "0.18.0-SNAPSHOT" \ No newline at end of file + version: "0.18.0-SNAPSHOT" diff --git a/pkg/apis/autoops/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go index 8801814aa77..2651b9c2608 100644 --- a/pkg/apis/autoops/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -86,7 +86,7 @@ func (p *AutoOpsAgentPolicy) GetWarnings() []string { } func validSettings(policy *AutoOpsAgentPolicy) field.ErrorList { - // Validate that ResourceSelector is not empty + // Validate that the ResourceSelector is not empty if policy.Spec.ResourceSelector.MatchLabels == nil && len(policy.Spec.ResourceSelector.MatchExpressions) == 0 { return field.ErrorList{field.Required(field.NewPath("spec").Child("resourceSelector"), "ResourceSelector must be specified with either matchLabels or matchExpressions")} } diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 96154fcbda7..89cbb244ba6 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -42,8 +42,8 @@ const ( // defaultRequeue is the default requeue interval for this controller. var defaultRequeue = 5 * time.Second -// Add creates a new AutoOpsAgentPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. +// Add creates a new AutoOpsAgentPolicy controller and adds it to the manager with default RBAC. The manager will set fields on the controller +// and start it when the manager is started. func Add(mgr manager.Manager, params operator.Parameters) error { r := newReconciler(mgr, params) c, err := common.NewController(mgr, controllerName, r, params) @@ -53,7 +53,6 @@ func Add(mgr manager.Manager, params operator.Parameters) error { return addWatches(mgr, c, r) } -// newReconciler returns a new reconcile.Reconciler of AutoOpsAgentPolicy. func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAutoOpsAgentPolicy { k8sClient := mgr.GetClient() return &ReconcileAutoOpsAgentPolicy{ @@ -90,7 +89,7 @@ type ReconcileAutoOpsAgentPolicy struct { iteration uint64 } -// Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any deployments are created/updated/deleted as needed. +// Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any resources are created/updated/deleted as needed. func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) defer common.LogReconciliationRun(ulog.FromContext(ctx))() @@ -142,13 +141,13 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { - span, vctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) + span, apmctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() if _, err := policy.ValidateCreate(); err != nil { ulog.FromContext(ctx).Error(err, "Validation failed") k8s.MaybeEmitErrorEvent(r.recorder, err, policy, events.EventReasonValidation, err.Error()) - return tracing.CaptureError(vctx, err) + return tracing.CaptureError(apmctx, err) } return nil From 2e48e42e681b9d5415c22a494858392ecded0f5a Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 09:19:56 -0600 Subject: [PATCH 39/90] ensuring secrets are cleaned up when missing es --- pkg/apis/autoops/v1alpha1/webhook.go | 7 ------ pkg/controller/autoops/api_key.go | 13 ++++++---- pkg/controller/autoops/controller.go | 30 ++++++++++++++--------- pkg/controller/autoops/controller_test.go | 2 +- pkg/controller/autoops/expected.go | 2 +- pkg/controller/autoops/expected_test.go | 5 ++-- 6 files changed, 32 insertions(+), 27 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/webhook.go b/pkg/apis/autoops/v1alpha1/webhook.go index 2651b9c2608..78026243ccc 100644 --- a/pkg/apis/autoops/v1alpha1/webhook.go +++ b/pkg/apis/autoops/v1alpha1/webhook.go @@ -78,13 +78,6 @@ func (p *AutoOpsAgentPolicy) validate() (admission.Warnings, error) { return nil, nil } -func (p *AutoOpsAgentPolicy) GetWarnings() []string { - if p == nil { - return nil - } - return nil -} - func validSettings(policy *AutoOpsAgentPolicy) field.ErrorList { // Validate that the ResourceSelector is not empty if policy.Spec.ResourceSelector.MatchLabels == nil && len(policy.Spec.ResourceSelector.MatchExpressions) == 0 { diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index ba6048999ad..bc575cd2de1 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -172,7 +172,7 @@ func maybeUpdateAPIKey( } // The API key is seemingly up to date, so we need to ensure the secret exists with correct value - secretName := apiKeySecretNameFrom(es) + secretName := apiKeySecretNameFor(types.NamespacedName{Namespace: policy.Namespace, Name: es.Name}) var secret corev1.Secret nsn := types.NamespacedName{ Namespace: policy.Namespace, @@ -252,7 +252,7 @@ func storeAPIKeyInSecret( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { - secretName := apiKeySecretNameFrom(es) + secretName := apiKeySecretNameFor(types.NamespacedName{Namespace: policy.Namespace, Name: es.Name}) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} @@ -316,7 +316,7 @@ func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsea } // apiKeySecretNameFrom generates the name for the API key secret from an ES instance. -func apiKeySecretNameFrom(es esv1.Elasticsearch) string { +func apiKeySecretNameFor(es types.NamespacedName) string { return fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESAPIKeySecretNameSuffix) } @@ -379,7 +379,11 @@ func cleanupAutoOpsESAPIKey( } } - secretName := apiKeySecretNameFrom(es) + return deleteESAPIKeySecret(ctx, c, log, policyNamespace, types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) +} + +func deleteESAPIKeySecret(ctx context.Context, c k8s.Client, log logr.Logger, policyNamespace string, es types.NamespacedName) error { + secretName := apiKeySecretNameFor(es) secretKey := types.NamespacedName{ Namespace: policyNamespace, Name: secretName, @@ -400,6 +404,5 @@ func cleanupAutoOpsESAPIKey( } return fmt.Errorf("while deleting API key secret %s: %w", secretName, err) } - return nil } diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 89cbb244ba6..06312311abb 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -29,6 +29,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/tracing" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -75,7 +76,7 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAutoOp return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets)) } -var _ reconcile.Reconciler = &ReconcileAutoOpsAgentPolicy{} +var _ reconcile.Reconciler = (*ReconcileAutoOpsAgentPolicy)(nil) // ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object type ReconcileAutoOpsAgentPolicy struct { @@ -92,7 +93,8 @@ type ReconcileAutoOpsAgentPolicy struct { // Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any resources are created/updated/deleted as needed. func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) - defer common.LogReconciliationRun(ulog.FromContext(ctx))() + log := ulog.FromContext(ctx) + defer common.LogReconciliationRun(log)() defer tracing.EndContextTransaction(ctx) // retrieve the AutoOpsAgentPolicy resource @@ -110,7 +112,7 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec } if common.IsUnmanaged(ctx, &policy) { - ulog.FromContext(ctx).Info("Object is currently not managed by this controller. Skipping reconciliation") + log.Info("Object is currently not managed by this controller. Skipping reconciliation") return reconcile.Result{}, nil } @@ -122,13 +124,7 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec results := r.doReconcile(ctx, policy, state) - if state.status.Phase != autoopsv1alpha1.InvalidPhase && state.status.Phase != autoopsv1alpha1.ErrorPhase { - if isReconciled, _ := results.IsReconciled(); !isReconciled { - state.UpdateWithPhase(autoopsv1alpha1.ApplyingChangesPhase) - } else { - state.UpdateWithPhase(autoopsv1alpha1.ReadyPhase) - } - } + updatePhaseFromResults(results, state) result, err := r.updateStatusFromState(ctx, state) if err != nil { @@ -140,6 +136,15 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec return results.Aggregate() } +// updatePhaseFromResults updates the phase of the AutoOpsAgentPolicy status based on the results of the reconciliation +func updatePhaseFromResults(results *reconciler.Results, state *State) { + if isReconciled, _ := results.IsReconciled(); !isReconciled { + state.UpdateWithPhase(autoopsv1alpha1.ApplyingChangesPhase) + } else { + state.UpdateWithPhase(autoopsv1alpha1.ReadyPhase) + } +} + func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { span, apmctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() @@ -211,7 +216,10 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na var es esv1.Elasticsearch if err := r.Client.Get(ctx, types.NamespacedName{Namespace: esNamespace, Name: esName}, &es); err != nil { if apierrors.IsNotFound(err) { - log.V(1).Info("Elasticsearch cluster not found, skipping cleanup", "es_namespace", esNamespace, "es_name", esName) + // The ES cluster is gone, so we need to delete the API key secret + if err := deleteESAPIKeySecret(ctx, r.Client, log, obj.Namespace, types.NamespacedName{Namespace: esNamespace, Name: esName}); err != nil { + log.Error(err, "Failed to delete API key secret", "es_namespace", esNamespace, "es_name", esName) + } continue } log.Error(err, "Failed to get Elasticsearch cluster", "es_namespace", esNamespace, "es_name", esName) diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index aa273fe3f70..67b1f43766b 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -286,7 +286,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { for _, es := range tt.esClusters { if es.Status.Phase == esv1.ElasticsearchReadyPhase { - expectedSecretName := apiKeySecretNameFrom(es) + expectedSecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) var retrievedSecret corev1.Secret err := k8sClient.Get(ctx, types.NamespacedName{Namespace: tt.policy.Namespace, Name: expectedSecretName}, &retrievedSecret) assert.True(t, apierrors.IsNotFound(err), "Expected secret %s/%s to be deleted", tt.policy.Namespace, expectedSecretName) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 6f201882619..d783bbd42cd 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -231,7 +231,7 @@ func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: apiKeySecretNameFrom(es), + Name: apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), }, Key: "api_key", Optional: ptr.To(false), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index eca8a08a10a..4e6adea3375 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -15,6 +15,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" @@ -139,7 +140,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast // Hash ES namespace and name to match the implementation esIdentifier := es.GetNamespace() + es.GetName() - esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:8] + esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), @@ -242,7 +243,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: apiKeySecretNameFrom(es), + Name: apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), }, Key: "api_key", Optional: ptr.To(false), From 86de6992920100a89bb8a7d453cab5f816526e62 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 09:28:26 -0600 Subject: [PATCH 40/90] fix comments --- pkg/controller/autoops/state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/autoops/state.go b/pkg/controller/autoops/state.go index 6c1fde3382e..2c0f3da91be 100644 --- a/pkg/controller/autoops/state.go +++ b/pkg/controller/autoops/state.go @@ -51,7 +51,7 @@ func (s *State) UpdateWithPhase(phase autoopsv1alpha1.PolicyPhase) *State { return s } -// UpdateAutoOpsInvalidWithEvent is a convenient method to set the phase to InvalidPhase +// UpdateInvalidPhaseWithEvent is a convenient method to set the phase to InvalidPhase // and generate an event at the same time. func (s *State) UpdateInvalidPhaseWithEvent(msg string) { s.status.Phase = autoopsv1alpha1.InvalidPhase From 82cb69567ff96abb0141afbd888aebaf90c7f1cf Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 11:11:17 -0600 Subject: [PATCH 41/90] cleanup deployment code --- config/e2e/rbac.yaml | 1 + .../v1alpha1/autoopsagentpolicy_types.go | 12 +++ pkg/controller/autoops/expected.go | 79 ++++++++----------- pkg/controller/autoops/reconcile.go | 12 +-- 4 files changed, 48 insertions(+), 56 deletions(-) diff --git a/config/e2e/rbac.yaml b/config/e2e/rbac.yaml index 777f36537ad..f1dad094255 100644 --- a/config/e2e/rbac.yaml +++ b/config/e2e/rbac.yaml @@ -390,6 +390,7 @@ rules: - autoops.k8s.elastic.co resources: - autoopsagentpolicies + - autoopsagentpolicies/status verbs: - get - list diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 1e29ce9a42c..4574b353571 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -5,6 +5,7 @@ package v1alpha1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" @@ -66,6 +67,17 @@ type AutoOpsAgentPolicySpec struct { // AutoOpsRef is a reference to an AutoOps instance running in the same Kubernetes cluster. // (TODO) AutoOpsRef is not yet implemented. // AutoOpsRef commonv1.ObjectSelector `json:"autoOpsRef,omitempty"` + + // Image is the AutoOps Agent Docker image to deploy. + Image string `json:"image,omitempty"` + + // PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods + // +kubebuilder:validation:Optional + // +kubebuilder:pruning:PreserveUnknownFields + PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` + + // RevisionHistoryLimit is the number of revisions to retain to allow rollback in the underlying Deployment. + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` } type AutoOpsAgentPolicyStatus struct { diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index d783bbd42cd..17fae8ece6d 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -13,7 +13,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" @@ -23,13 +23,13 @@ import ( esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/defaults" + common_deployment "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/deployment" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/volume" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/services" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" - "github.com/elastic/cloud-on-k8s/v3/pkg/utils/pointer" ) const ( @@ -43,34 +43,22 @@ const ( var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments // according to the Policy name, and associated Elasticsearch name. - AutoOpsNamer = common_name.NewNamer("autoops") - basePodTemplate = corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "autoops-agent", - }, - }, + AutoOpsNamer = common_name.NewNamer("autoops") + // Default resources for the AutoOps Agent deployment. + // These currently mirror the defaults for the Elastic Agent deployment. + defaultResources = corev1.ResourceRequirements{ + Limits: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceMemory: resource.MustParse("400Mi"), + corev1.ResourceCPU: resource.MustParse("200m"), + }, + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceMemory: resource.MustParse("400Mi"), + corev1.ResourceCPU: resource.MustParse("200m"), }, } ) -type ExpectedResources struct { - deployment appsv1.Deployment -} - -func (r *ReconcileAutoOpsAgentPolicy) generateExpectedResources(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (ExpectedResources, error) { - deployment, err := r.deploymentParams(ctx, policy, es) - if err != nil { - return ExpectedResources{}, err - } - return ExpectedResources{ - deployment: deployment, - }, nil -} - func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { - var deployment appsv1.Deployment v, err := version.Parse(policy.Spec.Version) if err != nil { return appsv1.Deployment{}, err @@ -79,23 +67,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli commonv1.TypeLabelName: "autoops-agent", autoOpsLabelName: policy.Name, } - // Hash ES namespace and name to create a short unique identifier - // preventing name length issues. - esIdentifier := es.GetNamespace() + es.GetName() - esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] - deployment.ObjectMeta = metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), - Namespace: policy.GetNamespace(), - Labels: labels, - } - deployment.Spec = appsv1.DeploymentSpec{ - Replicas: pointer.Int32(1), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - autoOpsLabelName: policy.GetName(), - }, - }, - } + // Create ES-specific config map volume configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) configVolume := volume.NewConfigMapVolume(configMapName, configVolumeName, configVolumePath) @@ -123,12 +95,13 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli annotations := map[string]string{configHashAnnotationName: configHash} meta := metadata.Propagate(&policy, metadata.Metadata{Labels: labels, Annotations: annotations}) - podTemplateSpec := defaults.NewPodTemplateBuilder(basePodTemplate, "autoops-agent"). + podTemplateSpec := defaults.NewPodTemplateBuilder(policy.Spec.PodTemplate, "autoops-agent"). WithArgs("--config", path.Join(configVolumePath, autoOpsESConfigFileName)). WithLabels(meta.Labels). WithAnnotations(meta.Annotations). - WithDockerImage(container.ImageRepository(container.AutoOpsAgentImage, v), v.String()). + WithDockerImage(policy.Spec.Image, container.ImageRepository(container.AutoOpsAgentImage, v)). WithEnv(autoopsEnvVars(es)...). + WithResources(defaultResources). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). WithPorts([]corev1.ContainerPort{{Name: "http", ContainerPort: int32(readinessProbePort), Protocol: corev1.ProtocolTCP}}). @@ -154,8 +127,22 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli }). PodTemplate - deployment.Spec.Template = podTemplateSpec - return deployment, nil + // Hash ES namespace and name to create a short unique identifier + // preventing name length issues. + esIdentifier := es.GetNamespace() + es.GetName() + esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] + + return common_deployment.New(common_deployment.Params{ + Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), + Namespace: policy.GetNamespace(), + Selector: map[string]string{ + autoOpsLabelName: policy.GetName(), + }, + Metadata: meta, + PodTemplateSpec: podTemplateSpec, + Replicas: 1, + RevisionHistoryLimit: policy.Spec.RevisionHistoryLimit, + }), nil } // readinessProbe is the readiness probe for the AutoOps Agent container diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 78f1161533d..96a4544facd 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -82,14 +82,6 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } listOpts := client.ListOptions{LabelSelector: selector} - // Restrict the search to the policy namespace if it is different from the operator namespace - // This follows the same behavior as the stackconfigpolicy controller for consistency. - log.V(1).Info("comparing policy namespace with operator namespace", "policy namespace", policy.Namespace, "operator namespace", r.params.OperatorNamespace) - if policy.Namespace != r.params.OperatorNamespace { - log.V(1).Info("Restricting search to policy namespace", "namespace", policy.Namespace) - listOpts.Namespace = policy.Namespace - } - var esList esv1.ElasticsearchList if err := r.Client.List(ctx, &esList, &listOpts); err != nil { state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) @@ -133,14 +125,14 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( continue } - expectedResources, err := r.generateExpectedResources(ctx, policy, es) + deploymentParams, err := r.deploymentParams(ctx, policy, es) if err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue } - reconciledDeployment, err := deployment.Reconcile(ctx, r.Client, expectedResources.deployment, &policy) + reconciledDeployment, err := deployment.Reconcile(ctx, r.Client, deploymentParams, &policy) if err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) From 35da2a6f0b670f65e7efeb4885f0ee8796c832c0 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 11:15:22 -0600 Subject: [PATCH 42/90] update helm charts adding additional options --- .../templates/autoopsagentpolicy.yaml | 10 +++++++++ .../eck-stack/charts/eck-autoops/values.yaml | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml index 8f4e793ffaf..36ff775156f 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -12,6 +12,16 @@ metadata: {{- end }} spec: version: {{ required "An AutoOps Agent Policy version is required" .Values.version }} + {{- with .Values.image }} + image: {{ . }} + {{- end }} + {{- with .Values.revisionHistoryLimit }} + revisionHistoryLimit: {{ . }} + {{- end }} + {{- with .Values.podTemplate }} + podTemplate: + {{- toYaml . | nindent 4 }} + {{- end }} config: secretName: {{ required "An AutoOps Agent Policy secretName is required" (include "autoops.secretName" .) }} {{- with .Values.resourceSelector }} diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index 0ff672e0277..0498ed44bf7 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -50,6 +50,27 @@ cloudConnectedModeAPIURL: "" # # secretName: "" +# Image is the AutoOps Agent Docker image to deploy. +# image: "docker.elastic.co/elastic-agent/elastic-otel-collector-wolfi:9.3.0-SNAPSHOT" + +# RevisionHistoryLimit is the number of revisions to retain to allow rollback in the underlying Deployment. +# revisionHistoryLimit: 2 + +# PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods +# +kubebuilder:validation:Optional +# +kubebuilder:pruning:PreserveUnknownFields +# podTemplate: +# spec: +# containers: +# - name: autoops-agent +# resources: +# limits: +# memory: 400Mi +# cpu: 200m +# requests: +# memory: 400Mi +# cpu: 200m + # ResourceSelector is a label selector for the resources to be configured. # Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. # From 475348d914c5cf68c288d89ae42c822518105a0f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 14:04:33 -0600 Subject: [PATCH 43/90] also watch the autoops ca secret --- pkg/controller/autoops/controller.go | 22 ++++++++++++++++++++ pkg/controller/autoops/expected_test.go | 8 +++++--- pkg/controller/autoops/reconcile.go | 2 +- pkg/controller/autoops/secret.go | 27 +++++++++++++++++++------ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 06312311abb..488a06e1108 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -72,10 +72,32 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAutoOp return err } + // watch for changes to Elasticsearch and reconcile all AutoOpsAgentPolicies + if err := c.Watch(source.Kind[client.Object](mgr.GetCache(), &esv1.Elasticsearch{}, reconcileRequestForAllAutoOpsPolicies(r.Client))); err != nil { + return err + } + // watch dynamically referenced secrets return c.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets)) } +// reconcileRequestForAllAutoOpsPolicies returns the requests to reconcile all AutoOpsAgentPolicy resources. +func reconcileRequestForAllAutoOpsPolicies(clnt k8s.Client) handler.TypedEventHandler[client.Object, reconcile.Request] { + return handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, es client.Object) []reconcile.Request { + var autoOpsAgentPolicyList autoopsv1alpha1.AutoOpsAgentPolicyList + err := clnt.List(context.Background(), &autoOpsAgentPolicyList) + if err != nil { + ulog.Log.Error(err, "Fail to list AutoOpsAgentPolicyList while watching Elasticsearch") + return nil + } + requests := make([]reconcile.Request, 0) + for _, autoOpsAgentPolicy := range autoOpsAgentPolicyList.Items { + requests = append(requests, reconcile.Request{NamespacedName: k8s.ExtractNamespacedName(&autoOpsAgentPolicy)}) + } + return requests + }) +} + var _ reconcile.Reconciler = (*ReconcileAutoOpsAgentPolicy)(nil) // ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 4e6adea3375..f16327f3e87 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -143,9 +143,10 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), - Namespace: policy.GetNamespace(), - Labels: labels, + Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), + Namespace: policy.GetNamespace(), + Labels: labels, + Annotations: annotations, }, Spec: appsv1.DeploymentSpec{ Replicas: pointer.Int32(1), @@ -183,6 +184,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast "--config", "/mnt/config/autoops_es.yml", }, + Resources: defaultResources, Ports: []corev1.ContainerPort{ { Name: "http", diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 96a4544facd..e6fcd378cf2 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -106,7 +106,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } if es.Spec.HTTP.TLS.Enabled() { - if err := reconcileAutoOpsESCASecret(ctx, r.Client, policy, es); err != nil { + if err := r.reconcileAutoOpsESCASecret(ctx, policy, es); err != nil { errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index d94c95188ff..998f23c2c45 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -19,7 +19,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" - "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" ) @@ -31,9 +31,8 @@ const ( // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate // for a specific Elasticsearch cluster, copying it from the ES instance's http-ca-internal secret. -func reconcileAutoOpsESCASecret( +func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESCASecret( ctx context.Context, - c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { @@ -50,7 +49,7 @@ func reconcileAutoOpsESCASecret( Name: certificates.CAInternalSecretName(esv1.ESNamer, es.Name, certificates.HTTPCAType), } var sourceSecret corev1.Secret - if err := c.Get(ctx, sourceSecretKey, &sourceSecret); err != nil { + if err := r.Client.Get(ctx, sourceSecretKey, &sourceSecret); err != nil { if apierrors.IsNotFound(err) { log.V(1).Info("ES http-ca-internal secret not found, skipping", "namespace", es.Namespace, "name", es.Name) return nil @@ -68,10 +67,10 @@ func reconcileAutoOpsESCASecret( expected := buildAutoOpsESCASecret(policy, secretName, caCert) reconciled := &corev1.Secret{} - return reconciler.ReconcileResource( + err := reconciler.ReconcileResource( reconciler.Params{ Context: ctx, - Client: c, + Client: r.Client, Owner: &policy, Expected: &expected, Reconciled: reconciled, @@ -87,6 +86,22 @@ func reconcileAutoOpsESCASecret( }, }, ) + if err != nil { + return err + } + + watcher := types.NamespacedName{ + Name: policy.Name, + Namespace: policy.Namespace, + } + + // Add a watch for the AutoOps CA secret + return watches.WatchUserProvidedSecrets( + watcher, + r.dynamicWatches, + secretName, + []string{secretName}, + ) } // buildAutoOpsESCASecret builds the expected Secret for autoops ES CA certificate. From a6b70ff3042c283d8899d53cfa1851d18dd9a1e0 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 14:09:46 -0600 Subject: [PATCH 44/90] dont check ready status in called func --- pkg/controller/autoops/api_key.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index bc575cd2de1..1eb0a1f51bb 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -69,11 +69,6 @@ func reconcileAutoOpsESAPIKey( ) log.V(1).Info("Reconciling AutoOps ES API key") - if es.Status.Phase != esv1.ElasticsearchReadyPhase { - log.V(1).Info("Skipping ES cluster that is not ready") - return nil - } - esClient, err := esClientProvider(ctx, c, dialer, es) if err != nil { return fmt.Errorf("while creating Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) From e863ad68602f8bcbdc00c8b3ba5719382785cce1 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 14:27:14 -0600 Subject: [PATCH 45/90] adjust helm chart to allow existing secret --- .../eck-autoops/templates/autoopsagentpolicy.yaml | 6 +++++- .../charts/eck-autoops/templates/secret.yaml | 6 +++--- deploy/eck-stack/charts/eck-autoops/values.yaml | 11 ++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml index 36ff775156f..7db8363cbfd 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -23,7 +23,11 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} config: - secretName: {{ required "An AutoOps Agent Policy secretName is required" (include "autoops.secretName" .) }} + {{- if .Values.configRef }} + secretName: {{ required "configRef.secretName is required when configRef is specified" .Values.configRef.secretName }} + {{- else }} + secretName: {{ printf "%s-config" (include "autoops.fullname" .) }} + {{- end }} {{- with .Values.resourceSelector }} resourceSelector: {{- toYaml . | nindent 4 }} diff --git a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml index 2b46b4c3e14..0f1030c78d0 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml @@ -1,9 +1,9 @@ +{{ if not .Values.configRef }} --- apiVersion: v1 kind: Secret metadata: - name: {{ include "autoops.secretName" . }} - labels: + name: {{ printf "%s-config" (include "autoops.fullname" .) }} {{- include "autoops.labels" . | nindent 4 }} annotations: {{- with .Values.annotations }} @@ -17,4 +17,4 @@ stringData: {{ with .Values.cloudConnectedModeAPIURL }} cloud-connected-mode-api-url: {{ . }} {{ end }} - +{{ end }} diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index 0498ed44bf7..13319a72326 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -45,10 +45,15 @@ autoOpsToken: "" # This is not a required field. cloudConnectedModeAPIURL: "" -# Secret name for the AutoOps configuration. -# This is not a required field. +# Reference an existing Kubernetes secret holding the AutoOps configuration. +# The referenced secret must contain the following: +# - `ccmApiKey`: the Cloud Connected Mode API key +# - `autoOpsOTelURL`: the URL of the AutoOps OTel endpoint +# - `autoOpsToken`: the token to authenticate against the AutoOps platform +# - `cloudConnectedModeAPIURL`: the URL of the Cloud Connected Mode API (optional) # -# secretName: "" +# configRef: +# secretName: "" # Image is the AutoOps Agent Docker image to deploy. # image: "docker.elastic.co/elastic-agent/elastic-otel-collector-wolfi:9.3.0-SNAPSHOT" From 67974186dca8d589a25ab77610497c74658169ed Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 14:36:28 -0600 Subject: [PATCH 46/90] also hash secret data --- pkg/controller/autoops/expected.go | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 17fae8ece6d..d9a309faf9c 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -164,10 +164,12 @@ func readinessProbe() corev1.Probe { } } -// buildConfigHash builds a hash of the ConfigMap data to trigger pod restart on config changes +// buildConfigHash builds a hash of the ConfigMap data and secret values +// to trigger pod restart on config changes func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (string, error) { configHash := fnv.New32a() + // Hash ConfigMap data configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) var configMap corev1.ConfigMap configMapKey := types.NamespacedName{Namespace: policy.Namespace, Name: configMapName} @@ -179,6 +181,37 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A _, _ = configHash.Write([]byte(configData)) } + // Hash secret values from autoops-secret + autoopsSecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: "autoops-secret"} + var autoopsSecret corev1.Secret + if err := c.Get(ctx, autoopsSecretKey, &autoopsSecret); err != nil { + return "", fmt.Errorf("failed to get autoops-secret: %w", err) + } + + // Hash secret keys, including optional keys. There's no code here to handle missing keys as + // 1. The optional keys are included here. + // 2. The required keys are already validated in the controller, so they should always be present. + requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} + for _, key := range requiredKeys { + if data, ok := autoopsSecret.Data[key]; ok { + _, _ = configHash.Write(data) + } + } + + // Hash ES API key secret + esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} + var esAPIKeySecret corev1.Secret + if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { + return "", fmt.Errorf("failed to get ES API key secret %s: %w", esAPIKeySecretName, err) + } + + // This data may not exist on initial reconciliation, so we don't return an error if it's missing. + // This should resolve itself on the next reconciliation after the API key is created. + if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { + _, _ = configHash.Write(apiKeyData) + } + return fmt.Sprint(configHash.Sum32()), nil } From 7a0b47f947a200e39e89689b7797d0d7e58474cc Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 14:40:55 -0600 Subject: [PATCH 47/90] fix unit tests --- pkg/controller/autoops/expected_test.go | 36 ++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index f16327f3e87..cb0d731f100 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -103,7 +103,34 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { autoOpsESConfigFileName: configData, }, } - client := k8s.NewFakeClient(configMap) + + // We need the autoops-secret with all required keys to build the config hash + autoopsSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "autoops-secret", + Namespace: tt.args.autoops.Namespace, + }, + Data: map[string][]byte{ + "autoops-token": []byte("test-autoops-token"), + "autoops-otel-url": []byte("https://test-otel-url"), + "cloud-connected-mode-api-key": []byte("test-ccm-api-key"), + "cloud-connected-mode-api-url": []byte("https://test-ccm-api-url"), + }, + } + + // We need the ES API key secret as well to build the config hash + esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: tt.args.es.Namespace, Name: tt.args.es.Name}) + esAPIKeySecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: esAPIKeySecretName, + Namespace: tt.args.autoops.Namespace, + }, + Data: map[string][]byte{ + "api_key": []byte("test-es-api-key"), + }, + } + + client := k8s.NewFakeClient(configMap, autoopsSecret, esAPIKeySecret) r := &ReconcileAutoOpsAgentPolicy{ Client: client, } @@ -117,6 +144,13 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { // Calculate expected config hash to match what buildConfigHash computes expectedConfigHash := fnv.New32a() _, _ = expectedConfigHash.Write([]byte(configData)) + // Hash autoops-secret values + _, _ = expectedConfigHash.Write([]byte("test-autoops-token")) + _, _ = expectedConfigHash.Write([]byte("https://test-otel-url")) + _, _ = expectedConfigHash.Write([]byte("test-ccm-api-key")) + _, _ = expectedConfigHash.Write([]byte("https://test-ccm-api-url")) + // Hash ES API key secret value + _, _ = expectedConfigHash.Write([]byte("test-es-api-key")) expectedHashStr := fmt.Sprint(expectedConfigHash.Sum32()) want := expectedDeployment(tt.args.autoops, tt.args.es, expectedHashStr) if !cmp.Equal(got, want) { From 458cf327bf04bf2fdec6ce9ded1e00fe0733e436 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 15:23:28 -0600 Subject: [PATCH 48/90] fix helm tests for autoops --- deploy/eck-stack/charts/eck-autoops/lint-values.yaml | 3 +++ .../charts/eck-autoops/templates/autoopsagentpolicy.yaml | 3 +++ deploy/eck-stack/charts/eck-autoops/templates/secret.yaml | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 deploy/eck-stack/charts/eck-autoops/lint-values.yaml diff --git a/deploy/eck-stack/charts/eck-autoops/lint-values.yaml b/deploy/eck-stack/charts/eck-autoops/lint-values.yaml new file mode 100644 index 00000000000..262a330a87c --- /dev/null +++ b/deploy/eck-stack/charts/eck-autoops/lint-values.yaml @@ -0,0 +1,3 @@ +ccmApiKey: required +autoOpsOTelURL: required +autoOpsToken: required diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml index 7db8363cbfd..e78f876980b 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "autoops.fullname" . }} labels: {{- include "autoops.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: eck.k8s.elastic.co/license: basic {{- with .Values.annotations }} diff --git a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml index 0f1030c78d0..241fca4b3a4 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml @@ -1,10 +1,14 @@ -{{ if not .Values.configRef }} --- +{{ if not .Values.configRef }} apiVersion: v1 kind: Secret metadata: - name: {{ printf "%s-config" (include "autoops.fullname" .) }} + name: {{ printf "%s-config" (include "autoops.fullname" .) }} + labels: {{- include "autoops.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: {{- with .Values.annotations }} {{- toYaml . | nindent 4 }} From 70ca228224b2755bf5d3972889e9be578a90296c Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Tue, 9 Dec 2025 16:32:03 -0600 Subject: [PATCH 49/90] make generate --- config/crds/v1/all-crds.yaml | 8457 +++++++++++++++++ ...s.k8s.elastic.co_autoopsagentpolicies.yaml | 8457 +++++++++++++++++ .../eck-operator-crds/templates/all-crds.yaml | 8457 +++++++++++++++++ docs/reference/api-reference/main.md | 3 + .../autoops/v1alpha1/zz_generated.deepcopy.go | 6 + 5 files changed, 25380 insertions(+) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 5975229189f..c4d87742f65 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2425,6 +2425,8458 @@ spec: description: SecretName is the name of the secret. type: string type: object + image: + description: Image is the AutoOps Agent Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Agent pods + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and subtracting + "weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: |- + Name is this DNS resolver option's name. + Required. + type: string + value: + description: Value is this DNS resolver option's + value. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + You cannot set this field on ephemeral containers. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. You cannot set this field on + ephemeral containers. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + When using HostNetwork you should specify ports so the scheduler is aware. + When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`, + and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + hostnameOverride: + description: |- + HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. + This field only specifies the pod's hostname and does not affect its DNS records. + When this field is set to a non-empty string: + - It takes precedence over the values set in `hostname` and `subdomain`. + - The Pod's hostname will be set to this value. + - `setHostnameAsFQDN` must be nil or set to false. + - `hostNetwork` must be set to false. + + This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. + Requires the HostnameOverride feature gate to be enabled. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + description: |- + NodeName indicates in which node this pod is scheduled. + If empty, this pod is a candidate for scheduling by the scheduler defined in schedulerName. + Once this field is set, the kubelet for this node becomes responsible for the lifecycle of this pod. + This field should not be used to express a desire for the pod to be scheduled on a specific node. + https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.resources + - spec.securityContext.appArmorProfile + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.securityContext.supplementalGroupsPolicy + - spec.containers[*].securityContext.appArmorProfile + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + description: |- + Resources is the total amount of CPU and Memory resources required by all + containers in the pod. It supports specifying Requests and Limits for + "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. + + This field enables fine-grained control over resource allocation for the + entire pod, allowing resource sharing among containers in a pod. + + This is an alpha field and requires enabling the PodLevelResources feature + gate. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name, + namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + properties: + endpoints: + description: endpoints is the endpoint name that + details Glusterfs topology. + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name, namespace and uid + are supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. Once the signer approves the + request and issues a certificate chain, Kubelet writes the key and + certificate chain to the pod filesystem. The pod does not start until + certificates have been issued for each podCertificate projected volume + source in its spec. + + Kubelet will begin trying to rotate the certificate at the time indicated + by the signer using the PodCertificateRequest.Status.BeginRefreshAt + timestamp. + + Kubelet can write a single file, indicated by the credentialBundlePath + field, or separate files, indicated by the keyPath and + certificateChainPath fields. + + The credential bundle is a single file in PEM format. The first PEM + entry is the private key (in PKCS#8 format), and the remaining PEM + entries are the certificate chain issued by the signer (typically, + signers will return their certificate chain in leaf-to-root order). + + Prefer using the credential bundle format, since your application code + can read it atomically. If you use keyPath and certificateChainPath, + your application must make two separate file reads. If these coincide + with a certificate rotation, it is possible that the private key and leaf + certificate you read may not correspond to each other. Your application + will need to check for this condition, and re-read until they are + consistent. + + The named signer controls chooses the format of the certificate it + issues; consult the signer implementation's documentation to learn how to + use the certificates it issues. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + + The remaining blocks are CERTIFICATE blocks, containing the issued + certificate chain from the signer (leaf and any intermediates). + + Using credentialBundlePath lets your Pod's application code make a single + atomic read that retrieves a consistent key and certificate chain. If you + project them to separate files, your application code will need to + additionally check that the leaf certificate was issued to the key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver + will reject values shorter than 3600 (1 hour). The maximum allowable + value is 7862400 (91 days). + + The signer implementation is then free to issue a certificate with any + lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 + seconds (1 hour). This constraint is enforced by kube-apiserver. + `kubernetes.io` signers will never issue certificates with a lifetime + longer than 24 hours. + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs + will be addressed to this signer. + type: string + required: + - keyType + - signerName + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true resourceSelector: description: |- ResourceSelector is a label selector for the resources to be configured. @@ -2473,6 +10925,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer version: description: Version of the AutoOpsAgentPolicy. type: string diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 647b1635db8..2a4a239782c 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -71,6 +71,8458 @@ spec: description: SecretName is the name of the secret. type: string type: object + image: + description: Image is the AutoOps Agent Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Agent pods + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and subtracting + "weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: |- + Name is this DNS resolver option's name. + Required. + type: string + value: + description: Value is this DNS resolver option's + value. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + You cannot set this field on ephemeral containers. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. You cannot set this field on + ephemeral containers. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + When using HostNetwork you should specify ports so the scheduler is aware. + When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`, + and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + hostnameOverride: + description: |- + HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. + This field only specifies the pod's hostname and does not affect its DNS records. + When this field is set to a non-empty string: + - It takes precedence over the values set in `hostname` and `subdomain`. + - The Pod's hostname will be set to this value. + - `setHostnameAsFQDN` must be nil or set to false. + - `hostNetwork` must be set to false. + + This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. + Requires the HostnameOverride feature gate to be enabled. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + description: |- + NodeName indicates in which node this pod is scheduled. + If empty, this pod is a candidate for scheduling by the scheduler defined in schedulerName. + Once this field is set, the kubelet for this node becomes responsible for the lifecycle of this pod. + This field should not be used to express a desire for the pod to be scheduled on a specific node. + https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.resources + - spec.securityContext.appArmorProfile + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.securityContext.supplementalGroupsPolicy + - spec.containers[*].securityContext.appArmorProfile + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + description: |- + Resources is the total amount of CPU and Memory resources required by all + containers in the pod. It supports specifying Requests and Limits for + "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. + + This field enables fine-grained control over resource allocation for the + entire pod, allowing resource sharing among containers in a pod. + + This is an alpha field and requires enabling the PodLevelResources feature + gate. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name, + namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + properties: + endpoints: + description: endpoints is the endpoint name that + details Glusterfs topology. + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name, namespace and uid + are supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. Once the signer approves the + request and issues a certificate chain, Kubelet writes the key and + certificate chain to the pod filesystem. The pod does not start until + certificates have been issued for each podCertificate projected volume + source in its spec. + + Kubelet will begin trying to rotate the certificate at the time indicated + by the signer using the PodCertificateRequest.Status.BeginRefreshAt + timestamp. + + Kubelet can write a single file, indicated by the credentialBundlePath + field, or separate files, indicated by the keyPath and + certificateChainPath fields. + + The credential bundle is a single file in PEM format. The first PEM + entry is the private key (in PKCS#8 format), and the remaining PEM + entries are the certificate chain issued by the signer (typically, + signers will return their certificate chain in leaf-to-root order). + + Prefer using the credential bundle format, since your application code + can read it atomically. If you use keyPath and certificateChainPath, + your application must make two separate file reads. If these coincide + with a certificate rotation, it is possible that the private key and leaf + certificate you read may not correspond to each other. Your application + will need to check for this condition, and re-read until they are + consistent. + + The named signer controls chooses the format of the certificate it + issues; consult the signer implementation's documentation to learn how to + use the certificates it issues. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + + The remaining blocks are CERTIFICATE blocks, containing the issued + certificate chain from the signer (leaf and any intermediates). + + Using credentialBundlePath lets your Pod's application code make a single + atomic read that retrieves a consistent key and certificate chain. If you + project them to separate files, your application code will need to + additionally check that the leaf certificate was issued to the key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver + will reject values shorter than 3600 (1 hour). The maximum allowable + value is 7862400 (91 days). + + The signer implementation is then free to issue a certificate with any + lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 + seconds (1 hour). This constraint is enforced by kube-apiserver. + `kubernetes.io` signers will never issue certificates with a lifetime + longer than 24 hours. + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs + will be addressed to this signer. + type: string + required: + - keyType + - signerName + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true resourceSelector: description: |- ResourceSelector is a label selector for the resources to be configured. @@ -119,6 +8571,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer version: description: Version of the AutoOpsAgentPolicy. type: string diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 3466e2f282b..d72f788da94 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2446,6 +2446,8458 @@ spec: description: SecretName is the name of the secret. type: string type: object + image: + description: Image is the AutoOps Agent Docker image to deploy. + type: string + podTemplate: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the Agent pods + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and subtracting + "weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: |- + Name is this DNS resolver option's name. + Required. + type: string + value: + description: Value is this DNS resolver option's + value. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + You cannot set this field on ephemeral containers. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. You cannot set this field on + ephemeral containers. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + When using HostNetwork you should specify ports so the scheduler is aware. + When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`, + and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + hostnameOverride: + description: |- + HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. + This field only specifies the pod's hostname and does not affect its DNS records. + When this field is set to a non-empty string: + - It takes precedence over the values set in `hostname` and `subdomain`. + - The Pod's hostname will be set to this value. + - `setHostnameAsFQDN` must be nil or set to false. + - `hostNetwork` must be set to false. + + This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. + Requires the HostnameOverride feature gate to be enabled. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source may consist of any printable ASCII characters except '='. + When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps or Secrets + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents a duration that + the container should sleep. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for backward compatibility. There is no validation of this field and + lifecycle hooks will fail at runtime when it is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + description: |- + StopSignal defines which signal will be sent to a container when it is being stopped. + If not specified, the default is defined by the container runtime in use. + StopSignal can only be set for Pods with a non-empty .spec.os.name + type: string + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Additionally, setting the RestartPolicy as "Always" for the init container will + have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. If no rule matches the container exit condition, + the Container-level restart policy determines the whether the container + is restarted or not. Constraints on the rules: + - At most 20 rules are allowed. + - Rules can have the same action. + - Identical rules are not forbidden in validations. + When rules are specified, container MUST set RestartPolicy explicitly + even it if matches the Pod's RestartPolicy. + items: + description: ContainerRestartRule describes how a + container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check + on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + - NotIn: the requirement is satisfied if the container exit code is + not in the set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies a command to execute + in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + If ReadOnly is false, this field has no meaning and must be unspecified. + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + description: |- + NodeName indicates in which node this pod is scheduled. + If empty, this pod is a candidate for scheduling by the scheduler defined in schedulerName. + Once this field is set, the kubelet for this node becomes responsible for the lifecycle of this pod. + This field should not be used to express a desire for the pod to be scheduled on a specific node. + https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.resources + - spec.securityContext.appArmorProfile + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.securityContext.supplementalGroupsPolicy + - spec.containers[*].securityContext.appArmorProfile + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + description: |- + Resources is the total amount of CPU and Memory resources required by all + containers in the pod. It supports specifying Requests and Limits for + "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. + + This field enables fine-grained control over resource allocation for the + entire pod, allowing resource sharing among containers in a pod. + + This is an alpha field and requires enabling the PodLevelResources feature + gate. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + If this value is nil, the behavior is equivalent to the Honor policy. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + If this value is nil, the behavior is equivalent to the Ignore policy. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree + awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: |- + azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type + are redirected to the disk.csi.azure.com CSI driver. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + default: ext4 + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + default: false + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: |- + azureFile represents an Azure File Service mount on the host and bind mount to the pod. + Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type + are redirected to the file.csi.azure.com CSI driver. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: |- + cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. + Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + Deprecated: Cinder is deprecated. All operations for the in-tree cinder type + are redirected to the cinder.csi.openstack.org CSI driver. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers. + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name, + namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string or nil value indicates that no + VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, + this field can be reset to its previous value (including nil) to cancel the modification. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: |- + flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. + Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree + gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. + properties: + endpoints: + description: endpoints is the endpoint name that + details Glusterfs topology. + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + image: + description: |- + image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + The volume is resolved at pod startup depending on which PullPolicy value is provided: + + - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + + The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. + A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. + The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. + The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. + The volume will be mounted read-only (ro) and non-executable files (noexec). + Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. + The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. + Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. + IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + default: default + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: |- + photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. + Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: |- + portworxVolume represents a portworx volume attached and mounted on kubelets host machine. + Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type + are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate + is on. + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. + items: + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name, namespace and uid + are supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. Once the signer approves the + request and issues a certificate chain, Kubelet writes the key and + certificate chain to the pod filesystem. The pod does not start until + certificates have been issued for each podCertificate projected volume + source in its spec. + + Kubelet will begin trying to rotate the certificate at the time indicated + by the signer using the PodCertificateRequest.Status.BeginRefreshAt + timestamp. + + Kubelet can write a single file, indicated by the credentialBundlePath + field, or separate files, indicated by the keyPath and + certificateChainPath fields. + + The credential bundle is a single file in PEM format. The first PEM + entry is the private key (in PKCS#8 format), and the remaining PEM + entries are the certificate chain issued by the signer (typically, + signers will return their certificate chain in leaf-to-root order). + + Prefer using the credential bundle format, since your application code + can read it atomically. If you use keyPath and certificateChainPath, + your application must make two separate file reads. If these coincide + with a certificate rotation, it is possible that the private key and leaf + certificate you read may not correspond to each other. Your application + will need to check for this condition, and re-read until they are + consistent. + + The named signer controls chooses the format of the certificate it + issues; consult the signer implementation's documentation to learn how to + use the certificates it issues. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + + The remaining blocks are CERTIFICATE blocks, containing the issued + certificate chain from the signer (leaf and any intermediates). + + Using credentialBundlePath lets your Pod's application code make a single + atomic read that retrieves a consistent key and certificate chain. If you + project them to separate files, your application code will need to + additionally check that the leaf certificate was issued to the key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. When using keyPath + and certificateChainPath, your application needs to check that the key + and leaf certificate are consistent, because it is possible to read the + files mid-rotation. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver + will reject values shorter than 3600 (1 hour). The maximum allowable + value is 7862400 (91 days). + + The signer implementation is then free to issue a certificate with any + lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 + seconds (1 hour). This constraint is enforced by kube-apiserver. + `kubernetes.io` signers will never issue certificates with a lifetime + longer than 24 hours. + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs + will be addressed to this signer. + type: string + required: + - keyType + - signerName + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: |- + quobyte represents a Quobyte mount on the host that shares a pod's lifetime. + Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + default: /etc/ceph/keyring + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: |- + scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. + properties: + fsType: + default: xfs + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + default: ThinProvisioned + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: |- + storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: |- + vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. + Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type + are redirected to the csi.vsphere.vmware.com CSI driver. + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + x-kubernetes-preserve-unknown-fields: true resourceSelector: description: |- ResourceSelector is a label selector for the resources to be configured. @@ -2494,6 +10946,11 @@ spec: type: object type: object x-kubernetes-map-type: atomic + revisionHistoryLimit: + description: RevisionHistoryLimit is the number of revisions to retain + to allow rollback in the underlying Deployment. + format: int32 + type: integer version: description: Version of the AutoOpsAgentPolicy. type: string diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 29d4118ae8a..f592e1e4e6b 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -294,6 +294,9 @@ AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes | *`version`* __string__ | Version of the AutoOpsAgentPolicy. | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | | *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`image`* __string__ | Image is the AutoOps Agent Docker image to deploy. | +| *`podTemplate`* __[PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#podtemplatespec-v1-core)__ | PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods | +| *`revisionHistoryLimit`* __integer__ | RevisionHistoryLimit is the number of revisions to retain to allow rollback in the underlying Deployment. | diff --git a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go index dce01fa3383..5ccb76348a9 100644 --- a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go @@ -76,6 +76,12 @@ func (in *AutoOpsAgentPolicySpec) DeepCopyInto(out *AutoOpsAgentPolicySpec) { *out = *in in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) out.Config = in.Config + in.PodTemplate.DeepCopyInto(&out.PodTemplate) + if in.RevisionHistoryLimit != nil { + in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit + *out = new(int32) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoOpsAgentPolicySpec. From c49cdc295ee57e511f0e492de38f75d81c1641bb Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 07:12:32 -0600 Subject: [PATCH 50/90] fix annotation size --- pkg/controller/autoops/expected.go | 37 +++++++++++++------------ pkg/controller/autoops/expected_test.go | 10 +++---- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index d9a309faf9c..0d23a08a7c2 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -188,29 +188,30 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A return "", fmt.Errorf("failed to get autoops-secret: %w", err) } + // Disabling this atm, as I believe it's breaking things... // Hash secret keys, including optional keys. There's no code here to handle missing keys as // 1. The optional keys are included here. // 2. The required keys are already validated in the controller, so they should always be present. - requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} - for _, key := range requiredKeys { - if data, ok := autoopsSecret.Data[key]; ok { - _, _ = configHash.Write(data) - } - } + // requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} + // for _, key := range requiredKeys { + // if data, ok := autoopsSecret.Data[key]; ok { + // _, _ = configHash.Write(data) + // } + // } - // Hash ES API key secret - esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) - esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} - var esAPIKeySecret corev1.Secret - if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { - return "", fmt.Errorf("failed to get ES API key secret %s: %w", esAPIKeySecretName, err) - } + // // Hash ES API key secret + // esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + // esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} + // var esAPIKeySecret corev1.Secret + // if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { + // return "", fmt.Errorf("failed to get ES API key secret %s: %w", esAPIKeySecretName, err) + // } - // This data may not exist on initial reconciliation, so we don't return an error if it's missing. - // This should resolve itself on the next reconciliation after the API key is created. - if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { - _, _ = configHash.Write(apiKeyData) - } + // // This data may not exist on initial reconciliation, so we don't return an error if it's missing. + // // This should resolve itself on the next reconciliation after the API key is created. + // if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { + // _, _ = configHash.Write(apiKeyData) + // } return fmt.Sprint(configHash.Sum32()), nil } diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index cb0d731f100..ed0c78aca8f 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -145,12 +145,12 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { expectedConfigHash := fnv.New32a() _, _ = expectedConfigHash.Write([]byte(configData)) // Hash autoops-secret values - _, _ = expectedConfigHash.Write([]byte("test-autoops-token")) - _, _ = expectedConfigHash.Write([]byte("https://test-otel-url")) - _, _ = expectedConfigHash.Write([]byte("test-ccm-api-key")) - _, _ = expectedConfigHash.Write([]byte("https://test-ccm-api-url")) + // _, _ = expectedConfigHash.Write([]byte("test-autoops-token")) + // _, _ = expectedConfigHash.Write([]byte("https://test-otel-url")) + // _, _ = expectedConfigHash.Write([]byte("test-ccm-api-key")) + // _, _ = expectedConfigHash.Write([]byte("https://test-ccm-api-url")) // Hash ES API key secret value - _, _ = expectedConfigHash.Write([]byte("test-es-api-key")) + // _, _ = expectedConfigHash.Write([]byte("test-es-api-key")) expectedHashStr := fmt.Sprint(expectedConfigHash.Sum32()) want := expectedDeployment(tt.args.autoops, tt.args.es, expectedHashStr) if !cmp.Equal(got, want) { From 55c95cc53a4858868e1b762b302fcf78fc59e176 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 07:32:02 -0600 Subject: [PATCH 51/90] use create, not apply --- test/e2e/cmd/run/run.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/cmd/run/run.go b/test/e2e/cmd/run/run.go index 60044ccb1b6..58805d7f829 100644 --- a/test/e2e/cmd/run/run.go +++ b/test/e2e/cmd/run/run.go @@ -344,8 +344,8 @@ func (h *helper) installOperatorUnderTest() error { return err } - if _, _, err := h.kubectl("apply", "-f", manifestFile); err != nil { - return fmt.Errorf("failed to apply operator manifest: %w", err) + if _, _, err := h.kubectl("create", "-f", manifestFile); err != nil { + return fmt.Errorf("failed to create operator manifest: %w", err) } h.addCleanupFunc(h.deleteResources(manifestFile)) From 153b6c769c9f0e4befe93eff6768cca03fb3d732 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 08:37:21 -0600 Subject: [PATCH 52/90] add patch for crd; revert create vs apply change --- config/crds/v1/all-crds.yaml | 8444 ----------------- .../patches/autoopsagentpolicy-patches.yaml | 8 + config/crds/v1/patches/kustomization.yaml | 9 +- .../eck-operator-crds/templates/all-crds.yaml | 8444 ----------------- test/e2e/cmd/run/run.go | 4 +- 5 files changed, 18 insertions(+), 16891 deletions(-) create mode 100644 config/crds/v1/patches/autoopsagentpolicy-patches.yaml diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index c4d87742f65..e613a2a236d 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2431,8450 +2431,6 @@ spec: podTemplate: description: PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods - properties: - metadata: - description: |- - Standard object's metadata. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - description: |- - Specification of the desired behavior of the pod. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - properties: - activeDeadlineSeconds: - description: |- - Optional duration in seconds the pod may be active on the node relative to - StartTime before the system will actively try to mark it failed and kill associated containers. - Value must be a positive integer. - format: int64 - type: integer - affinity: - description: If specified, the pod's scheduling constraints - properties: - nodeAffinity: - description: Describes node affinity scheduling rules - for the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, etc.), - compute a sum by iterating through the elements of this field and adding - "weight" to the sum if the node matches the corresponding matchExpressions; the - node(s) with the highest sum are the most preferred. - items: - description: |- - An empty preferred scheduling term matches all objects with implicit weight 0 - (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: |- - A null or empty node selector term matches no objects. The requirements of - them are ANDed. - The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-type: atomic - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, etc.), - compute a sum by iterating through the elements of this field and adding - "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: |- - weight associated with matching the corresponding podAffinityTerm, - in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod label update), the - system may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all terms must be satisfied. - items: - description: |- - Defines a set of pods (namely those matching the labelSelector - relative to the given namespace(s)) that this pod should be - co-located (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node whose value of - the label with key matches that of any node on which - a pod of the set of pods is running - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, - etc. as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the anti-affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity expressions, etc.), - compute a sum by iterating through the elements of this field and subtracting - "weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: |- - weight associated with matching the corresponding podAffinityTerm, - in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the anti-affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod label update), the - system may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all terms must be satisfied. - items: - description: |- - Defines a set of pods (namely those matching the labelSelector - relative to the given namespace(s)) that this pod should be - co-located (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node whose value of - the label with key matches that of any node on which - a pod of the set of pods is running - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - type: object - automountServiceAccountToken: - description: AutomountServiceAccountToken indicates whether - a service account token should be automatically mounted. - type: boolean - containers: - description: |- - List of containers belonging to the pod. - Containers cannot currently be added or removed. - There must be at least one container in a Pod. - Cannot be updated. - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This overrides the pod-level restart policy. When this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Additionally, setting the RestartPolicy as "Always" for the init container will - have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. The rules are evaluated in - order. Once a rule matches a container exit condition, the remaining - rules are ignored. If no rule matches the container exit condition, - the Container-level restart policy determines the whether the container - is restarted or not. Constraints on the rules: - - At most 20 rules are allowed. - - Rules can have the same action. - - Identical rules are not forbidden in validations. - When rules are specified, container MUST set RestartPolicy explicitly - even it if matches the Pod's RestartPolicy. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - dnsConfig: - description: |- - Specifies the DNS parameters of a pod. - Parameters specified here will be merged to the generated DNS - configuration based on DNSPolicy. - properties: - nameservers: - description: |- - A list of DNS name server IP addresses. - This will be appended to the base nameservers generated from DNSPolicy. - Duplicated nameservers will be removed. - items: - type: string - type: array - x-kubernetes-list-type: atomic - options: - description: |- - A list of DNS resolver options. - This will be merged with the base options generated from DNSPolicy. - Duplicated entries will be removed. Resolution options given in Options - will override those that appear in the base DNSPolicy. - items: - description: PodDNSConfigOption defines DNS resolver - options of a pod. - properties: - name: - description: |- - Name is this DNS resolver option's name. - Required. - type: string - value: - description: Value is this DNS resolver option's - value. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - searches: - description: |- - A list of DNS search domains for host-name lookup. - This will be appended to the base search paths generated from DNSPolicy. - Duplicated search paths will be removed. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - dnsPolicy: - description: |- - Set DNS policy for the pod. - Defaults to "ClusterFirst". - Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. - DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. - To have DNS options set along with hostNetwork, you have to specify DNS policy - explicitly to 'ClusterFirstWithHostNet'. - type: string - enableServiceLinks: - description: |- - EnableServiceLinks indicates whether information about services should be injected into pod's - environment variables, matching the syntax of Docker links. - Optional: Defaults to true. - type: boolean - ephemeralContainers: - description: |- - List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing - pod to perform user-initiated actions such as debugging. This list cannot be specified when - creating a pod, and it cannot be modified by updating the pod spec. In order to add an - ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - items: - description: |- - An EphemeralContainer is a temporary container that you may add to an existing Pod for - user-initiated activities such as debugging. Ephemeral containers have no resource or - scheduling guarantees, and they will not be restarted when they exit or when a Pod is - removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the - Pod to exceed its resource allocation. - - To add an ephemeral container, use the ephemeralcontainers subresource of an existing - Pod. Ephemeral containers may not be removed or restarted. - properties: - args: - description: |- - Arguments to the entrypoint. - The image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: Lifecycle is not allowed for ephemeral - containers. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the ephemeral container specified as a DNS_LABEL. - This name must be unique among all containers, init containers and ephemeral containers. - type: string - ports: - description: Ports are not allowed for ephemeral containers. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources - already allocated to the pod. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - Restart policy for the container to manage the restart behavior of each - container within a pod. - You cannot set this field on ephemeral containers. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. You cannot set this field on - ephemeral containers. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - Optional: SecurityContext defines the security options the ephemeral container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - targetContainerName: - description: |- - If set, the name of the container from PodSpec that this ephemeral container targets. - The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. - If not set then the ephemeral container uses the namespaces configured in the Pod spec. - - The container runtime must implement support for this feature. If the runtime does not - support namespace targeting then the result of setting this field is undefined. - type: string - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - hostAliases: - description: |- - HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts - file if specified. - items: - description: |- - HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the - pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - description: IP address of the host file entry. - type: string - required: - - ip - type: object - type: array - x-kubernetes-list-map-keys: - - ip - x-kubernetes-list-type: map - hostIPC: - description: |- - Use the host's ipc namespace. - Optional: Default to false. - type: boolean - hostNetwork: - description: |- - Host networking requested for this pod. Use the host's network namespace. - When using HostNetwork you should specify ports so the scheduler is aware. - When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`, - and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`. - Default to false. - type: boolean - hostPID: - description: |- - Use the host's pid namespace. - Optional: Default to false. - type: boolean - hostUsers: - description: |- - Use the host's user namespace. - Optional: Default to true. - If set to true or not present, the pod will be run in the host user namespace, useful - for when the pod needs a feature only available to the host user namespace, such as - loading a kernel module with CAP_SYS_MODULE. - When set to false, a new userns is created for the pod. Setting false is useful for - mitigating container breakout vulnerabilities even allowing users to run their - containers as root without actually having root privileges on the host. - This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. - type: boolean - hostname: - description: |- - Specifies the hostname of the Pod - If not specified, the pod's hostname will be set to a system-defined value. - type: string - hostnameOverride: - description: |- - HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. - This field only specifies the pod's hostname and does not affect its DNS records. - When this field is set to a non-empty string: - - It takes precedence over the values set in `hostname` and `subdomain`. - - The Pod's hostname will be set to this value. - - `setHostnameAsFQDN` must be nil or set to false. - - `hostNetwork` must be set to false. - - This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. - Requires the HostnameOverride feature gate to be enabled. - type: string - imagePullSecrets: - description: |- - ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. - If specified, these secrets will be passed to individual puller implementations for them to use. - More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod - items: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - initContainers: - description: |- - List of initialization containers belonging to the pod. - Init containers are executed in order prior to containers being started. If any - init container fails, the pod is considered to have failed and is handled according - to its restartPolicy. The name for an init container or normal container must be - unique among all containers. - Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. - The resourceRequirements of an init container are taken into account during scheduling - by finding the highest request/limit for each resource type, and then using the max of - that value or the sum of the normal containers. Limits are applied to init containers - in a similar fashion. - Init containers cannot currently be added or removed. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This overrides the pod-level restart policy. When this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Additionally, setting the RestartPolicy as "Always" for the init container will - have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. The rules are evaluated in - order. Once a rule matches a container exit condition, the remaining - rules are ignored. If no rule matches the container exit condition, - the Container-level restart policy determines the whether the container - is restarted or not. Constraints on the rules: - - At most 20 rules are allowed. - - Rules can have the same action. - - Identical rules are not forbidden in validations. - When rules are specified, container MUST set RestartPolicy explicitly - even it if matches the Pod's RestartPolicy. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodeName: - description: |- - NodeName indicates in which node this pod is scheduled. - If empty, this pod is a candidate for scheduling by the scheduler defined in schedulerName. - Once this field is set, the kubelet for this node becomes responsible for the lifecycle of this pod. - This field should not be used to express a desire for the pod to be scheduled on a specific node. - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename - type: string - nodeSelector: - additionalProperties: - type: string - description: |- - NodeSelector is a selector which must be true for the pod to fit on a node. - Selector which must match a node's labels for the pod to be scheduled on that node. - More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - type: object - x-kubernetes-map-type: atomic - os: - description: |- - Specifies the OS of the containers in the pod. - Some pod and container fields are restricted if this is set. - - If the OS field is set to linux, the following fields must be unset: - -securityContext.windowsOptions - - If the OS field is set to windows, following fields must be unset: - - spec.hostPID - - spec.hostIPC - - spec.hostUsers - - spec.resources - - spec.securityContext.appArmorProfile - - spec.securityContext.seLinuxOptions - - spec.securityContext.seccompProfile - - spec.securityContext.fsGroup - - spec.securityContext.fsGroupChangePolicy - - spec.securityContext.sysctls - - spec.shareProcessNamespace - - spec.securityContext.runAsUser - - spec.securityContext.runAsGroup - - spec.securityContext.supplementalGroups - - spec.securityContext.supplementalGroupsPolicy - - spec.containers[*].securityContext.appArmorProfile - - spec.containers[*].securityContext.seLinuxOptions - - spec.containers[*].securityContext.seccompProfile - - spec.containers[*].securityContext.capabilities - - spec.containers[*].securityContext.readOnlyRootFilesystem - - spec.containers[*].securityContext.privileged - - spec.containers[*].securityContext.allowPrivilegeEscalation - - spec.containers[*].securityContext.procMount - - spec.containers[*].securityContext.runAsUser - - spec.containers[*].securityContext.runAsGroup - properties: - name: - description: |- - Name is the name of the operating system. The currently supported values are linux and windows. - Additional value may be defined in future and can be one of: - https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration - Clients should expect to handle additional values and treat unrecognized values in this field as os: null - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. - This field will be autopopulated at admission time by the RuntimeClass admission controller. If - the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. - The RuntimeClass admission controller will reject Pod create requests which have the overhead already - set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value - defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. - More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md - type: object - preemptionPolicy: - description: |- - PreemptionPolicy is the Policy for preempting pods with lower priority. - One of Never, PreemptLowerPriority. - Defaults to PreemptLowerPriority if unset. - type: string - priority: - description: |- - The priority value. Various system components use this field to find the - priority of the pod. When Priority Admission Controller is enabled, it - prevents users from setting this field. The admission controller populates - this field from PriorityClassName. - The higher the value, the higher the priority. - format: int32 - type: integer - priorityClassName: - description: |- - If specified, indicates the pod's priority. "system-node-critical" and - "system-cluster-critical" are two special keywords which indicate the - highest priorities with the former being the highest priority. Any other - name must be defined by creating a PriorityClass object with that name. - If not specified, the pod priority will be default or zero if there is no - default. - type: string - readinessGates: - description: |- - If specified, all readiness gates will be evaluated for pod readiness. - A pod is ready when all its containers are ready AND - all conditions specified in the readiness gates have status equal to "True" - More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates - items: - description: PodReadinessGate contains the reference to - a pod condition - properties: - conditionType: - description: ConditionType refers to a condition in - the pod's condition list with matching type. - type: string - required: - - conditionType - type: object - type: array - x-kubernetes-list-type: atomic - resourceClaims: - description: |- - ResourceClaims defines which ResourceClaims must be allocated - and reserved before the Pod is allowed to start. The resources - will be made available to those containers which consume them - by name. - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - This field is immutable. - items: - description: |- - PodResourceClaim references exactly one ResourceClaim, either directly - or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim - for the pod. - - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. - Containers that need access to the ResourceClaim reference it with this name. - properties: - name: - description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. - type: string - resourceClaimName: - description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. - - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. - type: string - resourceClaimTemplateName: - description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. - - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. - - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. - - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - resources: - description: |- - Resources is the total amount of CPU and Memory resources required by all - containers in the pod. It supports specifying Requests and Limits for - "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. - - This field enables fine-grained control over resource allocation for the - entire pod, allowing resource sharing among containers in a pod. - - This is an alpha field and requires enabling the PodLevelResources feature - gate. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - Restart policy for all containers within the pod. - One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. - Default to Always. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy - type: string - runtimeClassName: - description: |- - RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used - to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. - If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an - empty definition that uses the default runtime handler. - More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class - type: string - schedulerName: - description: |- - If specified, the pod will be dispatched by specified scheduler. - If not specified, the pod will be dispatched by default scheduler. - type: string - schedulingGates: - description: |- - SchedulingGates is an opaque list of values that if specified will block scheduling the pod. - If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the - scheduler will not attempt to schedule the pod. - - SchedulingGates can only be set at pod creation time, and be removed only afterwards. - items: - description: PodSchedulingGate is associated to a Pod to - guard its scheduling. - properties: - name: - description: |- - Name of the scheduling gate. - Each scheduling gate must have a unique name field. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - securityContext: - description: |- - SecurityContext holds pod-level security attributes and common container settings. - Optional: Defaults to empty. See type description for default values of each field. - properties: - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by the containers in this pod. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - fsGroup: - description: |- - A special supplemental group that applies to all containers in a pod. - Some volume types allow the Kubelet to change the ownership of that volume - to be owned by the pod: - - 1. The owning GID will be the FSGroup - 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - 3. The permission bits are OR'd with rw-rw---- - - If unset, the Kubelet will not modify the ownership and permissions of any volume. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - fsGroupChangePolicy: - description: |- - fsGroupChangePolicy defines behavior of changing ownership and permission of the volume - before being exposed inside Pod. This field will only apply to - volume types which support fsGroup based ownership(and permissions). - It will have no effect on ephemeral volume types such as: secret, configmaps - and emptydir. - Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. - Note that this field cannot be set when spec.os.name is windows. - type: string - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence - for that container. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence - for that container. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxChangePolicy: - description: |- - seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. - It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. - Valid values are "MountOption" and "Recursive". - - "Recursive" means relabeling of all files on all Pod volumes by the container runtime. - This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. - - "MountOption" mounts all eligible Pod volumes with `-o context` mount option. - This requires all Pods that share the same volume to use the same SELinux label. - It is not possible to share the same volume among privileged and unprivileged Pods. - Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes - whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their - CSIDriver instance. Other volumes are always re-labelled recursively. - "MountOption" value is allowed only when SELinuxMount feature gate is enabled. - - If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. - If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes - and "Recursive" for all other volumes. - - This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. - - All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. - Note that this field cannot be set when spec.os.name is windows. - type: string - seLinuxOptions: - description: |- - The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in SecurityContext. If set in - both SecurityContext and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by the containers in this pod. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - addition to the container's primary GID and fsGroup (if specified). If - the SupplementalGroupsPolicy feature is enabled, the - supplementalGroupsPolicy field determines whether these are in addition - to or instead of any group memberships defined in the container image. - If unspecified, no additional groups are added, though group memberships - defined in the container image may still be used, depending on the - supplementalGroupsPolicy field. - Note that this field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - x-kubernetes-list-type: atomic - supplementalGroupsPolicy: - description: |- - Defines how supplemental groups of the first container processes are calculated. - Valid values are "Merge" and "Strict". If not specified, "Merge" is used. - (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled - and the container runtime must implement support for this feature. - Note that this field cannot be set when spec.os.name is windows. - type: string - sysctls: - description: |- - Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported - sysctls (by the container runtime) might fail to launch. - Note that this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options within a container's SecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - serviceAccount: - description: |- - DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. - Deprecated: Use serviceAccountName instead. - type: string - serviceAccountName: - description: |- - ServiceAccountName is the name of the ServiceAccount to use to run this pod. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - type: string - setHostnameAsFQDN: - description: |- - If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). - In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). - In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. - If a pod does not have FQDN, this has no effect. - Default to false. - type: boolean - shareProcessNamespace: - description: |- - Share a single process namespace between all of the containers in a pod. - When this is set containers will be able to view and signal processes from other containers - in the same pod, and the first process in each container will not be assigned PID 1. - HostPID and ShareProcessNamespace cannot both be set. - Optional: Default to false. - type: boolean - subdomain: - description: |- - If specified, the fully qualified Pod hostname will be "...svc.". - If not specified, the pod will not have a domainname at all. - type: string - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - If this value is nil, the default grace period will be used instead. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - Defaults to 30 seconds. - format: int64 - type: integer - tolerations: - description: If specified, the pod's tolerations. - items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the triple using the matching operator . - properties: - effect: - description: |- - Effect indicates the taint effect to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: |- - Key is the taint key that the toleration applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; this combination means to match all values and all keys. - type: string - operator: - description: |- - Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod can - tolerate all taints of a particular category. - type: string - tolerationSeconds: - description: |- - TolerationSeconds represents the period of time the toleration (which must be - of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint forever (do not evict). Zero and - negative values will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: |- - Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise just a regular string. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - topologySpreadConstraints: - description: |- - TopologySpreadConstraints describes how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which abides by the constraints. - All topologySpreadConstraints are ANDed. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: |- - LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine the number of pods - in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spreading will be calculated. The keys are used to lookup values from the - incoming pod labels, those key-value labels are ANDed with labelSelector - to select the group of existing pods over which spreading will be calculated - for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector isn't set. - Keys that don't exist in the incoming pod labels will - be ignored. A null or empty list means only match against labelSelector. - - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - description: |- - MaxSkew describes the degree to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference - between the number of matching pods in the target topology and the global minimum. - The global minimum is the minimum number of matching pods in an eligible domain - or zero if the number of eligible domains is less than MinDomains. - For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same - labelSelector spread as 2/2/1: - In this case, the global minimum is 1. - | zone1 | zone2 | zone3 | - | P P | P P | P | - - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) - violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto any zone. - When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence - to topologies that satisfy it. - It's a required field. Default value is 1 and 0 is not allowed. - format: int32 - type: integer - minDomains: - description: |- - MinDomains indicates a minimum number of eligible domains. - When the number of eligible domains with matching topology keys is less than minDomains, - Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. - And when the number of eligible domains with matching topology keys equals or greater than minDomains, - this value has no effect on scheduling. - As a result, when the number of eligible domains is less than minDomains, - scheduler won't schedule more than maxSkew Pods to those domains. - If value is nil, the constraint behaves as if MinDomains is equal to 1. - Valid values are integers greater than 0. - When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same - labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | - | P P | P P | P P | - The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. - In this situation, new pod with the same labelSelector cannot be scheduled, - because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, - it will violate MaxSkew. - format: int32 - type: integer - nodeAffinityPolicy: - description: |- - NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. Options are: - - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - - If this value is nil, the behavior is equivalent to the Honor policy. - type: string - nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - pod topology spread skew. Options are: - - Honor: nodes without taints, along with tainted nodes for which the incoming pod - has a toleration, are included. - - Ignore: node taints are ignored. All nodes are included. - - If this value is nil, the behavior is equivalent to the Ignore policy. - type: string - topologyKey: - description: |- - TopologyKey is the key of node labels. Nodes that have a label with this key - and identical values are considered to be in the same topology. - We consider each as a "bucket", and try to put balanced number - of pods into each bucket. - We define a domain as a particular instance of a topology. - Also, we define an eligible domain as a domain whose nodes meet the requirements of - nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. - And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. - It's a required field. - type: string - whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - the spread constraint. - - DoNotSchedule (default) tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule the pod in any location, - but giving higher precedence to topologies that would help reduce the - skew. - A constraint is considered "Unsatisfiable" for an incoming pod - if and only if every possible node assignment for that pod would violate - "MaxSkew" on some topology. - For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same - labelSelector spread as 3/1/1: - | zone1 | zone2 | zone3 | - | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled - to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler - won't make it *more* imbalanced. - It's a required field. - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - description: |- - List of volumes that can be mounted by containers belonging to the pod. - More info: https://kubernetes.io/docs/concepts/storage/volumes - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: |- - awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree - awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - properties: - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: string - partition: - description: |- - partition is the partition in the volume that you want to mount. - If omitted, the default is to mount by volume name. - Examples: For volume /dev/sda1, you specify the partition as "1". - Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). - format: int32 - type: integer - readOnly: - description: |- - readOnly value true will force the readOnly setting in VolumeMounts. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: boolean - volumeID: - description: |- - volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: string - required: - - volumeID - type: object - azureDisk: - description: |- - azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. - Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type - are redirected to the disk.csi.azure.com CSI driver. - properties: - cachingMode: - description: 'cachingMode is the Host Caching mode: - None, Read Only, Read Write.' - type: string - diskName: - description: diskName is the Name of the data disk - in the blob storage - type: string - diskURI: - description: diskURI is the URI of data disk in - the blob storage - type: string - fsType: - default: ext4 - description: |- - fsType is Filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - kind: - description: 'kind expected values are Shared: multiple - blob disks per storage account Dedicated: single - blob disk per storage account Managed: azure - managed data disk (only in managed availability - set). defaults to shared' - type: string - readOnly: - default: false - description: |- - readOnly Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: |- - azureFile represents an Azure File Service mount on the host and bind mount to the pod. - Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type - are redirected to the file.csi.azure.com CSI driver. - properties: - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: secretName is the name of secret that - contains Azure Storage Account Name and Key - type: string - shareName: - description: shareName is the azure share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: |- - cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. - Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. - properties: - monitors: - description: |- - monitors is Required: Monitors is a collection of Ceph monitors - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - description: 'path is Optional: Used as the mounted - root, rather than the full Ceph tree, default - is /' - type: string - readOnly: - description: |- - readOnly is Optional: Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: boolean - secretFile: - description: |- - secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: string - secretRef: - description: |- - secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: |- - user is optional: User is the rados user name, default is admin - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: string - required: - - monitors - type: object - cinder: - description: |- - cinder represents a cinder volume attached and mounted on kubelets host machine. - Deprecated: Cinder is deprecated. All operations for the in-tree cinder type - are redirected to the cinder.csi.openstack.org CSI driver. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: boolean - secretRef: - description: |- - secretRef is optional: points to a secret object containing parameters used to connect - to OpenStack. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - description: |- - volumeID used to identify the volume in cinder. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: string - required: - - volumeID - type: object - configMap: - description: configMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: |- - defaultMode is optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - description: csi (Container Storage Interface) represents - ephemeral storage that is handled by certain external - CSI drivers. - properties: - driver: - description: |- - driver is the name of the CSI driver that handles this volume. - Consult with your admin for the correct name as registered in the cluster. - type: string - fsType: - description: |- - fsType to mount. Ex. "ext4", "xfs", "ntfs". - If not provided, the empty value is passed to the associated CSI driver - which will determine the default filesystem to apply. - type: string - nodePublishSecretRef: - description: |- - nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to complete the CSI - NodePublishVolume and NodeUnpublishVolume calls. - This field is optional, and may be empty if no secret is required. If the - secret object contains more than one secret, all secret references are passed. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - description: |- - readOnly specifies a read-only configuration for the volume. - Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: |- - volumeAttributes stores driver-specific properties that are passed to the CSI - driver. Consult your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: downwardAPI represents downward API about - the pod that should populate this volume - properties: - defaultMode: - description: |- - Optional: mode bits to use on created files by default. Must be a - Optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing the - pod field - properties: - fieldRef: - description: 'Required: Selects a field of - the pod: only annotations, labels, name, - namespace and uid are supported.' - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: |- - Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' path. - Must be utf-8 encoded. The first item of - the relative path must not start with ''..''' - type: string - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - description: |- - emptyDir represents a temporary directory that shares a pod's lifetime. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - properties: - medium: - description: |- - medium represents what type of storage medium should back this directory. - The default is "" which means to use the node's default medium. - Must be an empty string (default) or Memory. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: |- - sizeLimit is the total amount of local storage required for this EmptyDir volume. - The size limit is also applicable for memory medium. - The maximum usage on memory medium EmptyDir would be the minimum value between - the SizeLimit specified here and the sum of memory limits of all containers in a pod. - The default is nil which means that the limit is undefined. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: |- - ephemeral represents a volume that is handled by a cluster storage driver. - The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, - and deleted when the pod is removed. - - Use this if: - a) the volume is only needed while the pod runs, - b) features of normal volumes like restoring from snapshot or capacity - tracking are needed, - c) the storage driver is specified through a storage class, and - d) the storage driver supports dynamic volume provisioning through - a PersistentVolumeClaim (see EphemeralVolumeSource for more - information on the connection between this volume type - and PersistentVolumeClaim). - - Use PersistentVolumeClaim or one of the vendor-specific - APIs for volumes that persist for longer than the lifecycle - of an individual pod. - - Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to - be used that way - see the documentation of the driver for - more information. - - A pod can use both types of ephemeral volumes and - persistent volumes at the same time. - properties: - volumeClaimTemplate: - description: |- - Will be used to create a stand-alone PVC to provision the volume. - The pod in which this EphemeralVolumeSource is embedded will be the - owner of the PVC, i.e. the PVC will be deleted together with the - pod. The name of the PVC will be `-` where - `` is the name from the `PodSpec.Volumes` array - entry. Pod validation will reject the pod if the concatenated name - is not valid for a PVC (for example, too long). - - An existing PVC with that name that is not owned by the pod - will *not* be used for the pod to avoid using an unrelated - volume by mistake. Starting the pod is then blocked until - the unrelated PVC is removed. If such a pre-created PVC is - meant to be used by the pod, the PVC has to updated with an - owner reference to the pod once the pod exists. Normally - this should not be necessary, but it may be useful when - manually reconstructing a broken cluster. - - This field is read-only and no changes will be made by Kubernetes - to the PVC after it has been created. - - Required, must not be nil. - properties: - metadata: - description: |- - May contain labels and annotations that will be copied into the PVC - when creating it. No other fields are allowed and will be rejected during - validation. - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - description: |- - The specification for the PersistentVolumeClaim. The entire content is - copied unchanged into the PVC that gets created from this - template. The same fields as in a PersistentVolumeClaim - are also valid here. - properties: - accessModes: - description: |- - accessModes contains the desired access modes the volume should have. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - description: |- - dataSource field can be used to specify either: - * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) - If the provisioner or an external controller can support the specified data source, - it will create a new volume based on the contents of the specified data source. - When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, - and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. - If the namespace is specified, then dataSourceRef will not be copied to dataSource. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: |- - dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty API group (non - core object) or a PersistentVolumeClaim object. - When this field is specified, volume binding will only succeed if the type of - the specified object matches some installed volume populator or dynamic - provisioner. - This field will replace the functionality of the dataSource field and as such - if both fields are non-empty, they must have the same value. For backwards - compatibility, when namespace isn't specified in dataSourceRef, - both fields (dataSource and dataSourceRef) will be set to the same - value automatically if one of them is empty and the other is non-empty. - When namespace is specified in dataSourceRef, - dataSource isn't set to the same value and must be empty. - There are three important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping them), dataSourceRef - preserves all values, and generates an error if a disallowed value is - specified. - * While dataSource only allows local objects, dataSourceRef allows objects - in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. - (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - namespace: - description: |- - Namespace is the namespace of resource being referenced - Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. - (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: |- - resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements - that are lower than previous value but must still be higher than capacity recorded in the - status field of the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - selector: - description: selector is a label query over - volumes to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: |- - storageClassName is the name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 - type: string - volumeAttributesClassName: - description: |- - volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. - If specified, the CSI driver will create or update the volume with the attributes defined - in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, - it can be changed after the claim is created. An empty string or nil value indicates that no - VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, - this field can be reset to its previous value (including nil) to cancel the modification. - If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be - set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource - exists. - More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ - type: string - volumeMode: - description: |- - volumeMode defines what type of volume is required by the claim. - Value of Filesystem is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: fc represents a Fibre Channel resource - that is attached to a kubelet's host machine and then - exposed to the pod. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - lun: - description: 'lun is Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: |- - readOnly is Optional: Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - targetWWNs: - description: 'targetWWNs is Optional: FC target - worldwide names (WWNs)' - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - description: |- - wwids Optional: FC volume world wide identifiers (wwids) - Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - description: |- - flexVolume represents a generic volume resource that is - provisioned/attached using an exec based plugin. - Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. - properties: - driver: - description: driver is the name of the driver to - use for this volume. - type: string - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'options is Optional: this field holds - extra command options if any.' - type: object - readOnly: - description: |- - readOnly is Optional: defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugin scripts. This may be - empty if no secret object is specified. If the secret object - contains more than one secret, all secrets are passed to the plugin - scripts. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - description: |- - flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. - Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. - properties: - datasetName: - description: |- - datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as deprecated - type: string - datasetUUID: - description: datasetUUID is the UUID of the dataset. - This is unique identifier of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: |- - gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree - gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - properties: - fsType: - description: |- - fsType is filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: string - partition: - description: |- - partition is the partition in the volume that you want to mount. - If omitted, the default is to mount by volume name. - Examples: For volume /dev/sda1, you specify the partition as "1". - Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - format: int32 - type: integer - pdName: - description: |- - pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: string - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: boolean - required: - - pdName - type: object - gitRepo: - description: |- - gitRepo represents a git repository at a particular revision. - Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an - EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir - into the Pod's container. - properties: - directory: - description: |- - directory is the target directory name. - Must not contain or start with '..'. If '.' is supplied, the volume directory will be the - git repository. Otherwise, if specified, the volume will contain the git repository in - the subdirectory with the given name. - type: string - repository: - description: repository is the URL - type: string - revision: - description: revision is the commit hash for the - specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - properties: - endpoints: - description: endpoints is the endpoint name that - details Glusterfs topology. - type: string - path: - description: |- - path is the Glusterfs volume path. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - type: string - readOnly: - description: |- - readOnly here will force the Glusterfs volume to be mounted with read-only permissions. - Defaults to false. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: |- - hostPath represents a pre-existing file or directory on the host - machine that is directly exposed to the container. This is generally - used for system agents or other privileged things that are allowed - to see the host machine. Most containers will NOT need this. - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - properties: - path: - description: |- - path of the directory on the host. - If the path is a symlink, it will follow the link to the real path. - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - type: string - type: - description: |- - type for HostPath Volume - Defaults to "" - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - type: string - required: - - path - type: object - image: - description: |- - image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. - The volume is resolved at pod startup depending on which PullPolicy value is provided: - - - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. - - The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. - A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. - The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. - The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - The volume will be mounted read-only (ro) and non-executable files (noexec). - Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. - The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. - properties: - pullPolicy: - description: |- - Policy for pulling OCI objects. Possible values are: - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - type: string - reference: - description: |- - Required: Image or artifact reference to be used. - Behaves in the same way as pod.spec.containers[*].image. - Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - type: object - iscsi: - description: |- - iscsi represents an ISCSI Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi - properties: - chapAuthDiscovery: - description: chapAuthDiscovery defines whether support - iSCSI Discovery CHAP authentication - type: boolean - chapAuthSession: - description: chapAuthSession defines whether support - iSCSI Session CHAP authentication - type: boolean - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - type: string - initiatorName: - description: |- - initiatorName is the custom iSCSI Initiator Name. - If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface - : will be created for the connection. - type: string - iqn: - description: iqn is the target iSCSI Qualified Name. - type: string - iscsiInterface: - default: default - description: |- - iscsiInterface is the interface Name that uses an iSCSI transport. - Defaults to 'default' (tcp). - type: string - lun: - description: lun represents iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: |- - portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port - is other than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - type: boolean - secretRef: - description: secretRef is the CHAP Secret for iSCSI - target and initiator authentication - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - description: |- - targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port - is other than default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: |- - name of the volume. - Must be a DNS_LABEL and unique within the pod. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - nfs: - description: |- - nfs represents an NFS mount on the host that shares a pod's lifetime - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - properties: - path: - description: |- - path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: string - readOnly: - description: |- - readOnly here will force the NFS export to be mounted with read-only permissions. - Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: boolean - server: - description: |- - server is the hostname or IP address of the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: |- - persistentVolumeClaimVolumeSource represents a reference to a - PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - properties: - claimName: - description: |- - claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - type: string - readOnly: - description: |- - readOnly Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: |- - photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. - Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - pdID: - description: pdID is the ID that identifies Photon - Controller persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: |- - portworxVolume represents a portworx volume attached and mounted on kubelets host machine. - Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - is on. - properties: - fsType: - description: |- - fSType represents the filesystem type to mount - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: volumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: projected items for all in one resources - secrets, configmaps, and downward API - properties: - defaultMode: - description: |- - defaultMode are the mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - sources: - description: |- - sources is the list of volume projections. Each entry in this list - handles one source. - items: - description: |- - Projection that may be projected along with other supported volume types. - Exactly one of these fields must be set. - properties: - clusterTrustBundle: - description: |- - ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field - of ClusterTrustBundle objects in an auto-updating file. - - Alpha, gated by the ClusterTrustBundleProjection feature gate. - - ClusterTrustBundle objects can either be selected by name, or by the - combination of signer name and a label selector. - - Kubelet performs aggressive normalization of the PEM contents written - into the pod filesystem. Esoteric PEM features such as inter-block - comments and block headers are stripped. Certificates are deduplicated. - The ordering of certificates within the file is arbitrary, and Kubelet - may change the order over time. - properties: - labelSelector: - description: |- - Select all ClusterTrustBundles that match this label selector. Only has - effect if signerName is set. Mutually-exclusive with name. If unset, - interpreted as "match nothing". If set but empty, interpreted as "match - everything". - properties: - matchExpressions: - description: matchExpressions is a - list of label selector requirements. - The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - name: - description: |- - Select a single ClusterTrustBundle by object name. Mutually-exclusive - with signerName and labelSelector. - type: string - optional: - description: |- - If true, don't block pod startup if the referenced ClusterTrustBundle(s) - aren't available. If using name, then the named ClusterTrustBundle is - allowed not to exist. If using signerName, then the combination of - signerName and labelSelector is allowed to match zero - ClusterTrustBundles. - type: boolean - path: - description: Relative path from the volume - root to write the bundle. - type: string - signerName: - description: |- - Select all ClusterTrustBundles that match this signer name. - Mutually-exclusive with name. The contents of all selected - ClusterTrustBundles will be unified and deduplicated. - type: string - required: - - path - type: object - configMap: - description: configMap information about the - configMap data to project - properties: - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a - path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional specify whether - the ConfigMap or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - description: downwardAPI information about - the downwardAPI data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects - a field of the pod: only annotations, - labels, name, namespace and uid - are supported.' - properties: - apiVersion: - description: Version of the - schema the FieldPath is written - in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field - to select in the specified - API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: |- - Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file - to be created. Must not be absolute - or contain the ''..'' path. Must - be utf-8 encoded. The first item - of the relative path must not - start with ''..''' - type: string - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. - properties: - containerName: - description: 'Container name: - required for volumes, optional - for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output - format of the exposed resources, - defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podCertificate: - description: |- - Projects an auto-rotating credential bundle (private key and certificate - chain) that the pod can use either as a TLS client or server. - - Kubelet generates a private key and uses it to send a - PodCertificateRequest to the named signer. Once the signer approves the - request and issues a certificate chain, Kubelet writes the key and - certificate chain to the pod filesystem. The pod does not start until - certificates have been issued for each podCertificate projected volume - source in its spec. - - Kubelet will begin trying to rotate the certificate at the time indicated - by the signer using the PodCertificateRequest.Status.BeginRefreshAt - timestamp. - - Kubelet can write a single file, indicated by the credentialBundlePath - field, or separate files, indicated by the keyPath and - certificateChainPath fields. - - The credential bundle is a single file in PEM format. The first PEM - entry is the private key (in PKCS#8 format), and the remaining PEM - entries are the certificate chain issued by the signer (typically, - signers will return their certificate chain in leaf-to-root order). - - Prefer using the credential bundle format, since your application code - can read it atomically. If you use keyPath and certificateChainPath, - your application must make two separate file reads. If these coincide - with a certificate rotation, it is possible that the private key and leaf - certificate you read may not correspond to each other. Your application - will need to check for this condition, and re-read until they are - consistent. - - The named signer controls chooses the format of the certificate it - issues; consult the signer implementation's documentation to learn how to - use the certificates it issues. - properties: - certificateChainPath: - description: |- - Write the certificate chain at this path in the projected volume. - - Most applications should use credentialBundlePath. When using keyPath - and certificateChainPath, your application needs to check that the key - and leaf certificate are consistent, because it is possible to read the - files mid-rotation. - type: string - credentialBundlePath: - description: |- - Write the credential bundle at this path in the projected volume. - - The credential bundle is a single file that contains multiple PEM blocks. - The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private - key. - - The remaining blocks are CERTIFICATE blocks, containing the issued - certificate chain from the signer (leaf and any intermediates). - - Using credentialBundlePath lets your Pod's application code make a single - atomic read that retrieves a consistent key and certificate chain. If you - project them to separate files, your application code will need to - additionally check that the leaf certificate was issued to the key. - type: string - keyPath: - description: |- - Write the key at this path in the projected volume. - - Most applications should use credentialBundlePath. When using keyPath - and certificateChainPath, your application needs to check that the key - and leaf certificate are consistent, because it is possible to read the - files mid-rotation. - type: string - keyType: - description: |- - The type of keypair Kubelet will generate for the pod. - - Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", - "ECDSAP521", and "ED25519". - type: string - maxExpirationSeconds: - description: |- - maxExpirationSeconds is the maximum lifetime permitted for the - certificate. - - Kubelet copies this value verbatim into the PodCertificateRequests it - generates for this projection. - - If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver - will reject values shorter than 3600 (1 hour). The maximum allowable - value is 7862400 (91 days). - - The signer implementation is then free to issue a certificate with any - lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 - seconds (1 hour). This constraint is enforced by kube-apiserver. - `kubernetes.io` signers will never issue certificates with a lifetime - longer than 24 hours. - format: int32 - type: integer - signerName: - description: Kubelet's generated CSRs - will be addressed to this signer. - type: string - required: - - keyType - - signerName - type: object - secret: - description: secret information about the - secret data to project - properties: - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the Secret, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a - path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional field specify whether - the Secret or its key must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - description: serviceAccountToken is information - about the serviceAccountToken data to project - properties: - audience: - description: |- - audience is the intended audience of the token. A recipient of a token - must identify itself with an identifier specified in the audience of the - token, and otherwise should reject the token. The audience defaults to the - identifier of the apiserver. - type: string - expirationSeconds: - description: |- - expirationSeconds is the requested duration of validity of the service - account token. As the token approaches expiration, the kubelet volume - plugin will proactively rotate the service account token. The kubelet will - start trying to rotate the token if the token is older than 80 percent of - its time to live or if the token is older than 24 hours.Defaults to 1 hour - and must be at least 10 minutes. - format: int64 - type: integer - path: - description: |- - path is the path relative to the mount point of the file to project the - token into. - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - description: |- - quobyte represents a Quobyte mount on the host that shares a pod's lifetime. - Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. - properties: - group: - description: |- - group to map volume access to - Default is no group - type: string - readOnly: - description: |- - readOnly here will force the Quobyte volume to be mounted with read-only permissions. - Defaults to false. - type: boolean - registry: - description: |- - registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple entries are separated with commas) - which acts as the central registry for volumes - type: string - tenant: - description: |- - tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by the plugin - type: string - user: - description: |- - user to map volume access to - Defaults to serivceaccount user - type: string - volume: - description: volume is a string that references - an already created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - type: string - image: - description: |- - image is the rados image name. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - keyring: - default: /etc/ceph/keyring - description: |- - keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - monitors: - description: |- - monitors is a collection of Ceph monitors. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - description: |- - pool is the rados pool name. - Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: boolean - secretRef: - description: |- - secretRef is name of the authentication secret for RBDUser. If provided - overrides keyring. - Default is nil. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - description: |- - user is the rados user name. - Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - required: - - image - - monitors - type: object - scaleIO: - description: |- - scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. - Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. - properties: - fsType: - default: xfs - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". - Default is "xfs". - type: string - gateway: - description: gateway is the host address of the - ScaleIO API Gateway. - type: string - protectionDomain: - description: protectionDomain is the name of the - ScaleIO Protection Domain for the configured storage. - type: string - readOnly: - description: |- - readOnly Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef references to the secret for ScaleIO user and other - sensitive information. If this is not provided, Login operation will fail. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - description: sslEnabled Flag enable/disable SSL - communication with Gateway, default false - type: boolean - storageMode: - default: ThinProvisioned - description: |- - storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. - Default is ThinProvisioned. - type: string - storagePool: - description: storagePool is the ScaleIO Storage - Pool associated with the protection domain. - type: string - system: - description: system is the name of the storage system - as configured in ScaleIO. - type: string - volumeName: - description: |- - volumeName is the name of a volume already created in the ScaleIO system - that is associated with this volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: |- - secret represents a secret that should populate this volume. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret - properties: - defaultMode: - description: |- - defaultMode is Optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values - for mode bits. Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: |- - items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the Secret, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - description: optional field specify whether the - Secret or its keys must be defined - type: boolean - secretName: - description: |- - secretName is the name of the secret in the pod's namespace to use. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret - type: string - type: object - storageos: - description: |- - storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. - Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef specifies the secret to use for obtaining the StorageOS API - credentials. If not specified, default values will be attempted. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - description: |- - volumeName is the human-readable name of the StorageOS volume. Volume - names are only unique within a namespace. - type: string - volumeNamespace: - description: |- - volumeNamespace specifies the scope of the volume within StorageOS. If no - namespace is specified then the Pod's namespace will be used. This allows the - Kubernetes name scoping to be mirrored within StorageOS for tighter integration. - Set VolumeName to any name to override the default behaviour. - Set to "default" if you are not using namespaces within StorageOS. - Namespaces that do not pre-exist within StorageOS will be created. - type: string - type: object - vsphereVolume: - description: |- - vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. - Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type - are redirected to the csi.vsphere.vmware.com CSI driver. - properties: - fsType: - description: |- - fsType is filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - storagePolicyID: - description: storagePolicyID is the storage Policy - Based Management (SPBM) profile ID associated - with the StoragePolicyName. - type: string - storagePolicyName: - description: storagePolicyName is the storage Policy - Based Management (SPBM) profile name. - type: string - volumePath: - description: volumePath is the path that identifies - vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - required: - - containers - type: object type: object x-kubernetes-preserve-unknown-fields: true resourceSelector: diff --git a/config/crds/v1/patches/autoopsagentpolicy-patches.yaml b/config/crds/v1/patches/autoopsagentpolicy-patches.yaml new file mode 100644 index 00000000000..488ced77ee7 --- /dev/null +++ b/config/crds/v1/patches/autoopsagentpolicy-patches.yaml @@ -0,0 +1,8 @@ +# Using `kubectl apply` stores the complete CRD file as an annotation, +# which may be too big for the annotations size limit. +# One way to mitigate this problem is to remove the (huge) podTemplate properties from the CRD. +# It also avoids the problem of having any k8s-version specific field in the Pod schema, +# that would maybe not match the user's k8s version. +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplate/properties + diff --git a/config/crds/v1/patches/kustomization.yaml b/config/crds/v1/patches/kustomization.yaml index ebb3d95a6b9..c7a376e34a5 100644 --- a/config/crds/v1/patches/kustomization.yaml +++ b/config/crds/v1/patches/kustomization.yaml @@ -70,12 +70,19 @@ patches: kind: CustomResourceDefinition name: elasticmapsservers.maps.k8s.elastic.co path: maps-patches.yaml - # custom patches for Logstash + # custom patches for Logstash - target: group: apiextensions.k8s.io version: v1 kind: CustomResourceDefinition name: logstashes.logstash.k8s.elastic.co path: logstash-patches.yaml + # custom patches for AutoOpsAgentPolicy + - target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: autoopsagentpolicies.autoops.k8s.elastic.co + path: autoopsagentpolicy-patches.yaml diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index d72f788da94..ae5d35bc8ff 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2452,8450 +2452,6 @@ spec: podTemplate: description: PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods - properties: - metadata: - description: |- - Standard object's metadata. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - description: |- - Specification of the desired behavior of the pod. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - properties: - activeDeadlineSeconds: - description: |- - Optional duration in seconds the pod may be active on the node relative to - StartTime before the system will actively try to mark it failed and kill associated containers. - Value must be a positive integer. - format: int64 - type: integer - affinity: - description: If specified, the pod's scheduling constraints - properties: - nodeAffinity: - description: Describes node affinity scheduling rules - for the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, etc.), - compute a sum by iterating through the elements of this field and adding - "weight" to the sum if the node matches the corresponding matchExpressions; the - node(s) with the highest sum are the most preferred. - items: - description: |- - An empty preferred scheduling term matches all objects with implicit weight 0 - (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: |- - A null or empty node selector term matches no objects. The requirements of - them are ANDed. - The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: |- - A node selector requirement is a selector that contains values, a key, and an operator - that relates the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: |- - Represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: |- - An array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. If the operator is Gt or Lt, the values - array must have a single element, which will be interpreted as an integer. - This array is replaced during a strategic merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-type: atomic - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, etc.), - compute a sum by iterating through the elements of this field and adding - "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: |- - weight associated with matching the corresponding podAffinityTerm, - in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod label update), the - system may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all terms must be satisfied. - items: - description: |- - Defines a set of pods (namely those matching the labelSelector - relative to the given namespace(s)) that this pod should be - co-located (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node whose value of - the label with key matches that of any node on which - a pod of the set of pods is running - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, - etc. as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: |- - The scheduler will prefer to schedule pods to nodes that satisfy - the anti-affinity expressions specified by this field, but it may choose - a node that violates one or more of the expressions. The node that is - most preferred is the one with the greatest sum of weights, i.e. - for each node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity expressions, etc.), - compute a sum by iterating through the elements of this field and subtracting - "weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: |- - weight associated with matching the corresponding podAffinityTerm, - in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - description: |- - If the anti-affinity requirements specified by this field are not met at - scheduling time, the pod will not be scheduled onto the node. - If the anti-affinity requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod label update), the - system may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all terms must be satisfied. - items: - description: |- - Defines a set of pods (namely those matching the labelSelector - relative to the given namespace(s)) that this pod should be - co-located (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node whose value of - the label with key matches that of any node on which - a pod of the set of pods is running - properties: - labelSelector: - description: |- - A label query over a set of resources, in this case pods. - If it's null, this PodAffinityTerm matches with no Pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both matchLabelKeys and labelSelector. - Also, matchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - description: |- - MismatchLabelKeys is a set of pod label keys to select which pods will - be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` - to select the group of existing pods which pods will be taken into consideration - for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming - pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. - Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field - and the ones listed in the namespaces field. - null selector and null or empty namespaces list means "this pod's namespace". - An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: |- - namespaces specifies a static list of namespace names that the term applies to. - The term is applied to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. - null or empty namespaces list and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - description: |- - This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where co-located is defined as running on a node - whose value of the label with key topologyKey matches that of any node on which any of the - selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - type: object - automountServiceAccountToken: - description: AutomountServiceAccountToken indicates whether - a service account token should be automatically mounted. - type: boolean - containers: - description: |- - List of containers belonging to the pod. - Containers cannot currently be added or removed. - There must be at least one container in a Pod. - Cannot be updated. - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This overrides the pod-level restart policy. When this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Additionally, setting the RestartPolicy as "Always" for the init container will - have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. The rules are evaluated in - order. Once a rule matches a container exit condition, the remaining - rules are ignored. If no rule matches the container exit condition, - the Container-level restart policy determines the whether the container - is restarted or not. Constraints on the rules: - - At most 20 rules are allowed. - - Rules can have the same action. - - Identical rules are not forbidden in validations. - When rules are specified, container MUST set RestartPolicy explicitly - even it if matches the Pod's RestartPolicy. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - dnsConfig: - description: |- - Specifies the DNS parameters of a pod. - Parameters specified here will be merged to the generated DNS - configuration based on DNSPolicy. - properties: - nameservers: - description: |- - A list of DNS name server IP addresses. - This will be appended to the base nameservers generated from DNSPolicy. - Duplicated nameservers will be removed. - items: - type: string - type: array - x-kubernetes-list-type: atomic - options: - description: |- - A list of DNS resolver options. - This will be merged with the base options generated from DNSPolicy. - Duplicated entries will be removed. Resolution options given in Options - will override those that appear in the base DNSPolicy. - items: - description: PodDNSConfigOption defines DNS resolver - options of a pod. - properties: - name: - description: |- - Name is this DNS resolver option's name. - Required. - type: string - value: - description: Value is this DNS resolver option's - value. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - searches: - description: |- - A list of DNS search domains for host-name lookup. - This will be appended to the base search paths generated from DNSPolicy. - Duplicated search paths will be removed. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - dnsPolicy: - description: |- - Set DNS policy for the pod. - Defaults to "ClusterFirst". - Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. - DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. - To have DNS options set along with hostNetwork, you have to specify DNS policy - explicitly to 'ClusterFirstWithHostNet'. - type: string - enableServiceLinks: - description: |- - EnableServiceLinks indicates whether information about services should be injected into pod's - environment variables, matching the syntax of Docker links. - Optional: Defaults to true. - type: boolean - ephemeralContainers: - description: |- - List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing - pod to perform user-initiated actions such as debugging. This list cannot be specified when - creating a pod, and it cannot be modified by updating the pod spec. In order to add an - ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - items: - description: |- - An EphemeralContainer is a temporary container that you may add to an existing Pod for - user-initiated activities such as debugging. Ephemeral containers have no resource or - scheduling guarantees, and they will not be restarted when they exit or when a Pod is - removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the - Pod to exceed its resource allocation. - - To add an ephemeral container, use the ephemeralcontainers subresource of an existing - Pod. Ephemeral containers may not be removed or restarted. - properties: - args: - description: |- - Arguments to the entrypoint. - The image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: Lifecycle is not allowed for ephemeral - containers. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the ephemeral container specified as a DNS_LABEL. - This name must be unique among all containers, init containers and ephemeral containers. - type: string - ports: - description: Ports are not allowed for ephemeral containers. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources - already allocated to the pod. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - Restart policy for the container to manage the restart behavior of each - container within a pod. - You cannot set this field on ephemeral containers. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. You cannot set this field on - ephemeral containers. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - Optional: SecurityContext defines the security options the ephemeral container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - targetContainerName: - description: |- - If set, the name of the container from PodSpec that this ephemeral container targets. - The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. - If not set then the ephemeral container uses the namespaces configured in the Pod spec. - - The container runtime must implement support for this feature. If the runtime does not - support namespace targeting then the result of setting this field is undefined. - type: string - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - hostAliases: - description: |- - HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts - file if specified. - items: - description: |- - HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the - pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - description: IP address of the host file entry. - type: string - required: - - ip - type: object - type: array - x-kubernetes-list-map-keys: - - ip - x-kubernetes-list-type: map - hostIPC: - description: |- - Use the host's ipc namespace. - Optional: Default to false. - type: boolean - hostNetwork: - description: |- - Host networking requested for this pod. Use the host's network namespace. - When using HostNetwork you should specify ports so the scheduler is aware. - When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`, - and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`. - Default to false. - type: boolean - hostPID: - description: |- - Use the host's pid namespace. - Optional: Default to false. - type: boolean - hostUsers: - description: |- - Use the host's user namespace. - Optional: Default to true. - If set to true or not present, the pod will be run in the host user namespace, useful - for when the pod needs a feature only available to the host user namespace, such as - loading a kernel module with CAP_SYS_MODULE. - When set to false, a new userns is created for the pod. Setting false is useful for - mitigating container breakout vulnerabilities even allowing users to run their - containers as root without actually having root privileges on the host. - This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. - type: boolean - hostname: - description: |- - Specifies the hostname of the Pod - If not specified, the pod's hostname will be set to a system-defined value. - type: string - hostnameOverride: - description: |- - HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. - This field only specifies the pod's hostname and does not affect its DNS records. - When this field is set to a non-empty string: - - It takes precedence over the values set in `hostname` and `subdomain`. - - The Pod's hostname will be set to this value. - - `setHostnameAsFQDN` must be nil or set to false. - - `hostNetwork` must be set to false. - - This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. - Requires the HostnameOverride feature gate to be enabled. - type: string - imagePullSecrets: - description: |- - ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. - If specified, these secrets will be passed to individual puller implementations for them to use. - More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod - items: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - initContainers: - description: |- - List of initialization containers belonging to the pod. - Init containers are executed in order prior to containers being started. If any - init container fails, the pod is considered to have failed and is handled according - to its restartPolicy. The name for an init container or normal container must be - unique among all containers. - Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. - The resourceRequirements of an init container are taken into account during scheduling - by finding the highest request/limit for each resource type, and then using the max of - that value or the sum of the normal containers. Limits are applied to init containers - in a similar fashion. - Init containers cannot currently be added or removed. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: |- - Name of the environment variable. - May consist of any printable ASCII characters except '='. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - description: |- - FileKeyRef selects a key of the env file. - Requires the EnvFiles feature gate to be enabled. - properties: - key: - description: |- - The key within the env file. An invalid key will prevent the pod from starting. - The keys defined within a source may consist of any printable ASCII characters except '='. - During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. - type: string - optional: - default: false - description: |- - Specify whether the file or its key must be defined. If the file or key - does not exist, then the env var is not published. - If optional is set to true and the specified key does not exist, - the environment variable will not be set in the Pod's containers. - - If optional is set to false and the specified key does not exist, - an error will be returned during Pod creation. - type: boolean - path: - description: |- - The path within the volume from which to select the file. - Must be relative and may not contain the '..' path or start with '..'. - type: string - volumeName: - description: The name of the volume mount - containing the env file. - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in - the pod's namespace - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source may consist of any printable ASCII characters except '='. - When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps or Secrets - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: |- - Optional text to prepend to the name of each environment variable. - May consist of any printable ASCII characters except '='. - type: string - secretRef: - description: The Secret to select from - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP - server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents a duration that - the container should sleep. - properties: - seconds: - description: Seconds is the number of seconds - to sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for backward compatibility. There is no validation of this field and - lifecycle hooks will fail at runtime when it is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - description: |- - StopSignal defines which signal will be sent to a container when it is being stopped. - If not specified, the default is defined by the container runtime in use. - StopSignal can only be set for Pods with a non-empty .spec.os.name - type: string - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external - port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource - resize policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This overrides the pod-level restart policy. When this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Additionally, setting the RestartPolicy as "Always" for the init container will - have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - restartPolicyRules: - description: |- - Represents a list of rules to be checked to determine if the - container should be restarted on exit. The rules are evaluated in - order. Once a rule matches a container exit condition, the remaining - rules are ignored. If no rule matches the container exit condition, - the Container-level restart policy determines the whether the container - is restarted or not. Constraints on the rules: - - At most 20 rules are allowed. - - Rules can have the same action. - - Identical rules are not forbidden in validations. - When rules are specified, container MUST set RestartPolicy explicitly - even it if matches the Pod's RestartPolicy. - items: - description: ContainerRestartRule describes how a - container exit is handled. - properties: - action: - description: |- - Specifies the action taken on a container exit if the requirements - are satisfied. The only possible value is "Restart" to restart the - container. - type: string - exitCodes: - description: Represents the exit codes to check - on container exits. - properties: - operator: - description: |- - Represents the relationship between the container exit code(s) and the - specified values. Possible values are: - - In: the requirement is satisfied if the container exit code is in the - set of specified values. - - NotIn: the requirement is satisfied if the container exit code is - not in the set of specified values. - type: string - values: - description: |- - Specifies the set of values to check for container exit codes. - At most 255 elements are allowed. - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by this container. If set, this profile - overrides the pod's appArmorProfile. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default value is Default which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies a command to execute - in the container. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies a GRPC HealthCheckRequest. - properties: - port: - description: Port number of the gRPC service. - Number must be in the range 1 to 65535. - format: int32 - type: integer - service: - default: "" - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies an HTTP GET request - to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies a connection to - a TCP port. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a - raw block device within a container. - properties: - devicePath: - description: devicePath is the path inside of - the container that the device will be mapped - to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a - Volume within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified - (which defaults to None). - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - recursiveReadOnly: - description: |- - RecursiveReadOnly specifies whether read-only mounts should be handled - recursively. - - If ReadOnly is false, this field has no meaning and must be unspecified. - - If ReadOnly is true, and this field is set to Disabled, the mount is not made - recursively read-only. If this field is set to IfPossible, the mount is made - recursively read-only, if it is supported by the container runtime. If this - field is set to Enabled, the mount is made recursively read-only if it is - supported by the container runtime, otherwise the pod will not be started and - an error will be generated to indicate the reason. - - If this field is set to IfPossible or Enabled, MountPropagation must be set to - None (or be unspecified, which defaults to None). - - If this field is not specified, it is treated as an equivalent of Disabled. - type: string - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodeName: - description: |- - NodeName indicates in which node this pod is scheduled. - If empty, this pod is a candidate for scheduling by the scheduler defined in schedulerName. - Once this field is set, the kubelet for this node becomes responsible for the lifecycle of this pod. - This field should not be used to express a desire for the pod to be scheduled on a specific node. - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename - type: string - nodeSelector: - additionalProperties: - type: string - description: |- - NodeSelector is a selector which must be true for the pod to fit on a node. - Selector which must match a node's labels for the pod to be scheduled on that node. - More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - type: object - x-kubernetes-map-type: atomic - os: - description: |- - Specifies the OS of the containers in the pod. - Some pod and container fields are restricted if this is set. - - If the OS field is set to linux, the following fields must be unset: - -securityContext.windowsOptions - - If the OS field is set to windows, following fields must be unset: - - spec.hostPID - - spec.hostIPC - - spec.hostUsers - - spec.resources - - spec.securityContext.appArmorProfile - - spec.securityContext.seLinuxOptions - - spec.securityContext.seccompProfile - - spec.securityContext.fsGroup - - spec.securityContext.fsGroupChangePolicy - - spec.securityContext.sysctls - - spec.shareProcessNamespace - - spec.securityContext.runAsUser - - spec.securityContext.runAsGroup - - spec.securityContext.supplementalGroups - - spec.securityContext.supplementalGroupsPolicy - - spec.containers[*].securityContext.appArmorProfile - - spec.containers[*].securityContext.seLinuxOptions - - spec.containers[*].securityContext.seccompProfile - - spec.containers[*].securityContext.capabilities - - spec.containers[*].securityContext.readOnlyRootFilesystem - - spec.containers[*].securityContext.privileged - - spec.containers[*].securityContext.allowPrivilegeEscalation - - spec.containers[*].securityContext.procMount - - spec.containers[*].securityContext.runAsUser - - spec.containers[*].securityContext.runAsGroup - properties: - name: - description: |- - Name is the name of the operating system. The currently supported values are linux and windows. - Additional value may be defined in future and can be one of: - https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration - Clients should expect to handle additional values and treat unrecognized values in this field as os: null - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. - This field will be autopopulated at admission time by the RuntimeClass admission controller. If - the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. - The RuntimeClass admission controller will reject Pod create requests which have the overhead already - set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value - defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. - More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md - type: object - preemptionPolicy: - description: |- - PreemptionPolicy is the Policy for preempting pods with lower priority. - One of Never, PreemptLowerPriority. - Defaults to PreemptLowerPriority if unset. - type: string - priority: - description: |- - The priority value. Various system components use this field to find the - priority of the pod. When Priority Admission Controller is enabled, it - prevents users from setting this field. The admission controller populates - this field from PriorityClassName. - The higher the value, the higher the priority. - format: int32 - type: integer - priorityClassName: - description: |- - If specified, indicates the pod's priority. "system-node-critical" and - "system-cluster-critical" are two special keywords which indicate the - highest priorities with the former being the highest priority. Any other - name must be defined by creating a PriorityClass object with that name. - If not specified, the pod priority will be default or zero if there is no - default. - type: string - readinessGates: - description: |- - If specified, all readiness gates will be evaluated for pod readiness. - A pod is ready when all its containers are ready AND - all conditions specified in the readiness gates have status equal to "True" - More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates - items: - description: PodReadinessGate contains the reference to - a pod condition - properties: - conditionType: - description: ConditionType refers to a condition in - the pod's condition list with matching type. - type: string - required: - - conditionType - type: object - type: array - x-kubernetes-list-type: atomic - resourceClaims: - description: |- - ResourceClaims defines which ResourceClaims must be allocated - and reserved before the Pod is allowed to start. The resources - will be made available to those containers which consume them - by name. - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - This field is immutable. - items: - description: |- - PodResourceClaim references exactly one ResourceClaim, either directly - or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim - for the pod. - - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. - Containers that need access to the ResourceClaim reference it with this name. - properties: - name: - description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. - type: string - resourceClaimName: - description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. - - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. - type: string - resourceClaimTemplateName: - description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. - - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. - - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. - - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - resources: - description: |- - Resources is the total amount of CPU and Memory resources required by all - containers in the pod. It supports specifying Requests and Limits for - "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. - - This field enables fine-grained control over resource allocation for the - entire pod, allowing resource sharing among containers in a pod. - - This is an alpha field and requires enabling the PodLevelResources feature - gate. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - This field depends on the - DynamicResourceAllocation feature gate. - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - request: - description: |- - Request is the name chosen for a request in the referenced claim. - If empty, everything from the claim is made available, otherwise - only the result of this request. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - Restart policy for all containers within the pod. - One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. - Default to Always. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy - type: string - runtimeClassName: - description: |- - RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used - to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. - If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an - empty definition that uses the default runtime handler. - More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class - type: string - schedulerName: - description: |- - If specified, the pod will be dispatched by specified scheduler. - If not specified, the pod will be dispatched by default scheduler. - type: string - schedulingGates: - description: |- - SchedulingGates is an opaque list of values that if specified will block scheduling the pod. - If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the - scheduler will not attempt to schedule the pod. - - SchedulingGates can only be set at pod creation time, and be removed only afterwards. - items: - description: PodSchedulingGate is associated to a Pod to - guard its scheduling. - properties: - name: - description: |- - Name of the scheduling gate. - Each scheduling gate must have a unique name field. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - securityContext: - description: |- - SecurityContext holds pod-level security attributes and common container settings. - Optional: Defaults to empty. See type description for default values of each field. - properties: - appArmorProfile: - description: |- - appArmorProfile is the AppArmor options to use by the containers in this pod. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile loaded on the node that should be used. - The profile must be preconfigured on the node to work. - Must match the loaded name of the profile. - Must be set if and only if type is "Localhost". - type: string - type: - description: |- - type indicates which kind of AppArmor profile will be applied. - Valid options are: - Localhost - a profile pre-loaded on the node. - RuntimeDefault - the container runtime's default profile. - Unconfined - no AppArmor enforcement. - type: string - required: - - type - type: object - fsGroup: - description: |- - A special supplemental group that applies to all containers in a pod. - Some volume types allow the Kubelet to change the ownership of that volume - to be owned by the pod: - - 1. The owning GID will be the FSGroup - 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - 3. The permission bits are OR'd with rw-rw---- - - If unset, the Kubelet will not modify the ownership and permissions of any volume. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - fsGroupChangePolicy: - description: |- - fsGroupChangePolicy defines behavior of changing ownership and permission of the volume - before being exposed inside Pod. This field will only apply to - volume types which support fsGroup based ownership(and permissions). - It will have no effect on ephemeral volume types such as: secret, configmaps - and emptydir. - Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. - Note that this field cannot be set when spec.os.name is windows. - type: string - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence - for that container. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence - for that container. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxChangePolicy: - description: |- - seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. - It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. - Valid values are "MountOption" and "Recursive". - - "Recursive" means relabeling of all files on all Pod volumes by the container runtime. - This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. - - "MountOption" mounts all eligible Pod volumes with `-o context` mount option. - This requires all Pods that share the same volume to use the same SELinux label. - It is not possible to share the same volume among privileged and unprivileged Pods. - Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes - whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their - CSIDriver instance. Other volumes are always re-labelled recursively. - "MountOption" value is allowed only when SELinuxMount feature gate is enabled. - - If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. - If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes - and "Recursive" for all other volumes. - - This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. - - All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. - Note that this field cannot be set when spec.os.name is windows. - type: string - seLinuxOptions: - description: |- - The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in SecurityContext. If set in - both SecurityContext and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by the containers in this pod. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - supplementalGroups: - description: |- - A list of groups applied to the first process run in each container, in - addition to the container's primary GID and fsGroup (if specified). If - the SupplementalGroupsPolicy feature is enabled, the - supplementalGroupsPolicy field determines whether these are in addition - to or instead of any group memberships defined in the container image. - If unspecified, no additional groups are added, though group memberships - defined in the container image may still be used, depending on the - supplementalGroupsPolicy field. - Note that this field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - x-kubernetes-list-type: atomic - supplementalGroupsPolicy: - description: |- - Defines how supplemental groups of the first container processes are calculated. - Valid values are "Merge" and "Strict". If not specified, "Merge" is used. - (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled - and the container runtime must implement support for this feature. - Note that this field cannot be set when spec.os.name is windows. - type: string - sysctls: - description: |- - Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported - sysctls (by the container runtime) might fail to launch. - Note that this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options within a container's SecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - serviceAccount: - description: |- - DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. - Deprecated: Use serviceAccountName instead. - type: string - serviceAccountName: - description: |- - ServiceAccountName is the name of the ServiceAccount to use to run this pod. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - type: string - setHostnameAsFQDN: - description: |- - If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). - In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). - In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. - If a pod does not have FQDN, this has no effect. - Default to false. - type: boolean - shareProcessNamespace: - description: |- - Share a single process namespace between all of the containers in a pod. - When this is set containers will be able to view and signal processes from other containers - in the same pod, and the first process in each container will not be assigned PID 1. - HostPID and ShareProcessNamespace cannot both be set. - Optional: Default to false. - type: boolean - subdomain: - description: |- - If specified, the fully qualified Pod hostname will be "...svc.". - If not specified, the pod will not have a domainname at all. - type: string - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - If this value is nil, the default grace period will be used instead. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - Defaults to 30 seconds. - format: int64 - type: integer - tolerations: - description: If specified, the pod's tolerations. - items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the triple using the matching operator . - properties: - effect: - description: |- - Effect indicates the taint effect to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: |- - Key is the taint key that the toleration applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; this combination means to match all values and all keys. - type: string - operator: - description: |- - Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod can - tolerate all taints of a particular category. - type: string - tolerationSeconds: - description: |- - TolerationSeconds represents the period of time the toleration (which must be - of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint forever (do not evict). Zero and - negative values will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: |- - Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise just a regular string. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - topologySpreadConstraints: - description: |- - TopologySpreadConstraints describes how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which abides by the constraints. - All topologySpreadConstraints are ANDed. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: |- - LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine the number of pods - in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: |- - MatchLabelKeys is a set of pod label keys to select the pods over which - spreading will be calculated. The keys are used to lookup values from the - incoming pod labels, those key-value labels are ANDed with labelSelector - to select the group of existing pods over which spreading will be calculated - for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector isn't set. - Keys that don't exist in the incoming pod labels will - be ignored. A null or empty list means only match against labelSelector. - - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - description: |- - MaxSkew describes the degree to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference - between the number of matching pods in the target topology and the global minimum. - The global minimum is the minimum number of matching pods in an eligible domain - or zero if the number of eligible domains is less than MinDomains. - For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same - labelSelector spread as 2/2/1: - In this case, the global minimum is 1. - | zone1 | zone2 | zone3 | - | P P | P P | P | - - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) - violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto any zone. - When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence - to topologies that satisfy it. - It's a required field. Default value is 1 and 0 is not allowed. - format: int32 - type: integer - minDomains: - description: |- - MinDomains indicates a minimum number of eligible domains. - When the number of eligible domains with matching topology keys is less than minDomains, - Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. - And when the number of eligible domains with matching topology keys equals or greater than minDomains, - this value has no effect on scheduling. - As a result, when the number of eligible domains is less than minDomains, - scheduler won't schedule more than maxSkew Pods to those domains. - If value is nil, the constraint behaves as if MinDomains is equal to 1. - Valid values are integers greater than 0. - When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same - labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | - | P P | P P | P P | - The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. - In this situation, new pod with the same labelSelector cannot be scheduled, - because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, - it will violate MaxSkew. - format: int32 - type: integer - nodeAffinityPolicy: - description: |- - NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. Options are: - - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - - If this value is nil, the behavior is equivalent to the Honor policy. - type: string - nodeTaintsPolicy: - description: |- - NodeTaintsPolicy indicates how we will treat node taints when calculating - pod topology spread skew. Options are: - - Honor: nodes without taints, along with tainted nodes for which the incoming pod - has a toleration, are included. - - Ignore: node taints are ignored. All nodes are included. - - If this value is nil, the behavior is equivalent to the Ignore policy. - type: string - topologyKey: - description: |- - TopologyKey is the key of node labels. Nodes that have a label with this key - and identical values are considered to be in the same topology. - We consider each as a "bucket", and try to put balanced number - of pods into each bucket. - We define a domain as a particular instance of a topology. - Also, we define an eligible domain as a domain whose nodes meet the requirements of - nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. - And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. - It's a required field. - type: string - whenUnsatisfiable: - description: |- - WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy - the spread constraint. - - DoNotSchedule (default) tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule the pod in any location, - but giving higher precedence to topologies that would help reduce the - skew. - A constraint is considered "Unsatisfiable" for an incoming pod - if and only if every possible node assignment for that pod would violate - "MaxSkew" on some topology. - For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same - labelSelector spread as 3/1/1: - | zone1 | zone2 | zone3 | - | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled - to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler - won't make it *more* imbalanced. - It's a required field. - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - description: |- - List of volumes that can be mounted by containers belonging to the pod. - More info: https://kubernetes.io/docs/concepts/storage/volumes - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: |- - awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree - awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - properties: - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: string - partition: - description: |- - partition is the partition in the volume that you want to mount. - If omitted, the default is to mount by volume name. - Examples: For volume /dev/sda1, you specify the partition as "1". - Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). - format: int32 - type: integer - readOnly: - description: |- - readOnly value true will force the readOnly setting in VolumeMounts. - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: boolean - volumeID: - description: |- - volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). - More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - type: string - required: - - volumeID - type: object - azureDisk: - description: |- - azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. - Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type - are redirected to the disk.csi.azure.com CSI driver. - properties: - cachingMode: - description: 'cachingMode is the Host Caching mode: - None, Read Only, Read Write.' - type: string - diskName: - description: diskName is the Name of the data disk - in the blob storage - type: string - diskURI: - description: diskURI is the URI of data disk in - the blob storage - type: string - fsType: - default: ext4 - description: |- - fsType is Filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - kind: - description: 'kind expected values are Shared: multiple - blob disks per storage account Dedicated: single - blob disk per storage account Managed: azure - managed data disk (only in managed availability - set). defaults to shared' - type: string - readOnly: - default: false - description: |- - readOnly Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: |- - azureFile represents an Azure File Service mount on the host and bind mount to the pod. - Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type - are redirected to the file.csi.azure.com CSI driver. - properties: - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: secretName is the name of secret that - contains Azure Storage Account Name and Key - type: string - shareName: - description: shareName is the azure share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: |- - cephFS represents a Ceph FS mount on the host that shares a pod's lifetime. - Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported. - properties: - monitors: - description: |- - monitors is Required: Monitors is a collection of Ceph monitors - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - description: 'path is Optional: Used as the mounted - root, rather than the full Ceph tree, default - is /' - type: string - readOnly: - description: |- - readOnly is Optional: Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: boolean - secretFile: - description: |- - secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: string - secretRef: - description: |- - secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: |- - user is optional: User is the rados user name, default is admin - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it - type: string - required: - - monitors - type: object - cinder: - description: |- - cinder represents a cinder volume attached and mounted on kubelets host machine. - Deprecated: Cinder is deprecated. All operations for the in-tree cinder type - are redirected to the cinder.csi.openstack.org CSI driver. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: boolean - secretRef: - description: |- - secretRef is optional: points to a secret object containing parameters used to connect - to OpenStack. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - description: |- - volumeID used to identify the volume in cinder. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md - type: string - required: - - volumeID - type: object - configMap: - description: configMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: |- - defaultMode is optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - description: csi (Container Storage Interface) represents - ephemeral storage that is handled by certain external - CSI drivers. - properties: - driver: - description: |- - driver is the name of the CSI driver that handles this volume. - Consult with your admin for the correct name as registered in the cluster. - type: string - fsType: - description: |- - fsType to mount. Ex. "ext4", "xfs", "ntfs". - If not provided, the empty value is passed to the associated CSI driver - which will determine the default filesystem to apply. - type: string - nodePublishSecretRef: - description: |- - nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to complete the CSI - NodePublishVolume and NodeUnpublishVolume calls. - This field is optional, and may be empty if no secret is required. If the - secret object contains more than one secret, all secret references are passed. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - description: |- - readOnly specifies a read-only configuration for the volume. - Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: |- - volumeAttributes stores driver-specific properties that are passed to the CSI - driver. Consult your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: downwardAPI represents downward API about - the pod that should populate this volume - properties: - defaultMode: - description: |- - Optional: mode bits to use on created files by default. Must be a - Optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing the - pod field - properties: - fieldRef: - description: 'Required: Selects a field of - the pod: only annotations, labels, name, - namespace and uid are supported.' - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: |- - Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' path. - Must be utf-8 encoded. The first item of - the relative path must not start with ''..''' - type: string - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - description: |- - emptyDir represents a temporary directory that shares a pod's lifetime. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - properties: - medium: - description: |- - medium represents what type of storage medium should back this directory. - The default is "" which means to use the node's default medium. - Must be an empty string (default) or Memory. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: |- - sizeLimit is the total amount of local storage required for this EmptyDir volume. - The size limit is also applicable for memory medium. - The maximum usage on memory medium EmptyDir would be the minimum value between - the SizeLimit specified here and the sum of memory limits of all containers in a pod. - The default is nil which means that the limit is undefined. - More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: |- - ephemeral represents a volume that is handled by a cluster storage driver. - The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, - and deleted when the pod is removed. - - Use this if: - a) the volume is only needed while the pod runs, - b) features of normal volumes like restoring from snapshot or capacity - tracking are needed, - c) the storage driver is specified through a storage class, and - d) the storage driver supports dynamic volume provisioning through - a PersistentVolumeClaim (see EphemeralVolumeSource for more - information on the connection between this volume type - and PersistentVolumeClaim). - - Use PersistentVolumeClaim or one of the vendor-specific - APIs for volumes that persist for longer than the lifecycle - of an individual pod. - - Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to - be used that way - see the documentation of the driver for - more information. - - A pod can use both types of ephemeral volumes and - persistent volumes at the same time. - properties: - volumeClaimTemplate: - description: |- - Will be used to create a stand-alone PVC to provision the volume. - The pod in which this EphemeralVolumeSource is embedded will be the - owner of the PVC, i.e. the PVC will be deleted together with the - pod. The name of the PVC will be `-` where - `` is the name from the `PodSpec.Volumes` array - entry. Pod validation will reject the pod if the concatenated name - is not valid for a PVC (for example, too long). - - An existing PVC with that name that is not owned by the pod - will *not* be used for the pod to avoid using an unrelated - volume by mistake. Starting the pod is then blocked until - the unrelated PVC is removed. If such a pre-created PVC is - meant to be used by the pod, the PVC has to updated with an - owner reference to the pod once the pod exists. Normally - this should not be necessary, but it may be useful when - manually reconstructing a broken cluster. - - This field is read-only and no changes will be made by Kubernetes - to the PVC after it has been created. - - Required, must not be nil. - properties: - metadata: - description: |- - May contain labels and annotations that will be copied into the PVC - when creating it. No other fields are allowed and will be rejected during - validation. - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - description: |- - The specification for the PersistentVolumeClaim. The entire content is - copied unchanged into the PVC that gets created from this - template. The same fields as in a PersistentVolumeClaim - are also valid here. - properties: - accessModes: - description: |- - accessModes contains the desired access modes the volume should have. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - description: |- - dataSource field can be used to specify either: - * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) - If the provisioner or an external controller can support the specified data source, - it will create a new volume based on the contents of the specified data source. - When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, - and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. - If the namespace is specified, then dataSourceRef will not be copied to dataSource. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: |- - dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty API group (non - core object) or a PersistentVolumeClaim object. - When this field is specified, volume binding will only succeed if the type of - the specified object matches some installed volume populator or dynamic - provisioner. - This field will replace the functionality of the dataSource field and as such - if both fields are non-empty, they must have the same value. For backwards - compatibility, when namespace isn't specified in dataSourceRef, - both fields (dataSource and dataSourceRef) will be set to the same - value automatically if one of them is empty and the other is non-empty. - When namespace is specified in dataSourceRef, - dataSource isn't set to the same value and must be empty. - There are three important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping them), dataSourceRef - preserves all values, and generates an error if a disallowed value is - specified. - * While dataSource only allows local objects, dataSourceRef allows objects - in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. - (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - properties: - apiGroup: - description: |- - APIGroup is the group for the resource being referenced. - If APIGroup is not specified, the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - namespace: - description: |- - Namespace is the namespace of resource being referenced - Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. - (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: |- - resources represents the minimum resources the volume should have. - If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements - that are lower than previous value but must still be higher than capacity recorded in the - status field of the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - selector: - description: selector is a label query over - volumes to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: |- - storageClassName is the name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 - type: string - volumeAttributesClassName: - description: |- - volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. - If specified, the CSI driver will create or update the volume with the attributes defined - in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, - it can be changed after the claim is created. An empty string or nil value indicates that no - VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state, - this field can be reset to its previous value (including nil) to cancel the modification. - If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be - set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource - exists. - More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ - type: string - volumeMode: - description: |- - volumeMode defines what type of volume is required by the claim. - Value of Filesystem is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: fc represents a Fibre Channel resource - that is attached to a kubelet's host machine and then - exposed to the pod. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - lun: - description: 'lun is Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: |- - readOnly is Optional: Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - targetWWNs: - description: 'targetWWNs is Optional: FC target - worldwide names (WWNs)' - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - description: |- - wwids Optional: FC volume world wide identifiers (wwids) - Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - description: |- - flexVolume represents a generic volume resource that is - provisioned/attached using an exec based plugin. - Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead. - properties: - driver: - description: driver is the name of the driver to - use for this volume. - type: string - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'options is Optional: this field holds - extra command options if any.' - type: object - readOnly: - description: |- - readOnly is Optional: defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugin scripts. This may be - empty if no secret object is specified. If the secret object - contains more than one secret, all secrets are passed to the plugin - scripts. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - description: |- - flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running. - Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported. - properties: - datasetName: - description: |- - datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as deprecated - type: string - datasetUUID: - description: datasetUUID is the UUID of the dataset. - This is unique identifier of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: |- - gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree - gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - properties: - fsType: - description: |- - fsType is filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: string - partition: - description: |- - partition is the partition in the volume that you want to mount. - If omitted, the default is to mount by volume name. - Examples: For volume /dev/sda1, you specify the partition as "1". - Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - format: int32 - type: integer - pdName: - description: |- - pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: string - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - type: boolean - required: - - pdName - type: object - gitRepo: - description: |- - gitRepo represents a git repository at a particular revision. - Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an - EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir - into the Pod's container. - properties: - directory: - description: |- - directory is the target directory name. - Must not contain or start with '..'. If '.' is supplied, the volume directory will be the - git repository. Otherwise, if specified, the volume will contain the git repository in - the subdirectory with the given name. - type: string - repository: - description: repository is the URL - type: string - revision: - description: revision is the commit hash for the - specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - properties: - endpoints: - description: endpoints is the endpoint name that - details Glusterfs topology. - type: string - path: - description: |- - path is the Glusterfs volume path. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - type: string - readOnly: - description: |- - readOnly here will force the Glusterfs volume to be mounted with read-only permissions. - Defaults to false. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: |- - hostPath represents a pre-existing file or directory on the host - machine that is directly exposed to the container. This is generally - used for system agents or other privileged things that are allowed - to see the host machine. Most containers will NOT need this. - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - properties: - path: - description: |- - path of the directory on the host. - If the path is a symlink, it will follow the link to the real path. - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - type: string - type: - description: |- - type for HostPath Volume - Defaults to "" - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - type: string - required: - - path - type: object - image: - description: |- - image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. - The volume is resolved at pod startup depending on which PullPolicy value is provided: - - - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. - - The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. - A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. - The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. - The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - The volume will be mounted read-only (ro) and non-executable files (noexec). - Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. - The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. - properties: - pullPolicy: - description: |- - Policy for pulling OCI objects. Possible values are: - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - type: string - reference: - description: |- - Required: Image or artifact reference to be used. - Behaves in the same way as pod.spec.containers[*].image. - Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - type: object - iscsi: - description: |- - iscsi represents an ISCSI Disk resource that is attached to a - kubelet's host machine and then exposed to the pod. - More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi - properties: - chapAuthDiscovery: - description: chapAuthDiscovery defines whether support - iSCSI Discovery CHAP authentication - type: boolean - chapAuthSession: - description: chapAuthSession defines whether support - iSCSI Session CHAP authentication - type: boolean - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - type: string - initiatorName: - description: |- - initiatorName is the custom iSCSI Initiator Name. - If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface - : will be created for the connection. - type: string - iqn: - description: iqn is the target iSCSI Qualified Name. - type: string - iscsiInterface: - default: default - description: |- - iscsiInterface is the interface Name that uses an iSCSI transport. - Defaults to 'default' (tcp). - type: string - lun: - description: lun represents iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: |- - portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port - is other than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - type: boolean - secretRef: - description: secretRef is the CHAP Secret for iSCSI - target and initiator authentication - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - description: |- - targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port - is other than default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: |- - name of the volume. - Must be a DNS_LABEL and unique within the pod. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - nfs: - description: |- - nfs represents an NFS mount on the host that shares a pod's lifetime - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - properties: - path: - description: |- - path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: string - readOnly: - description: |- - readOnly here will force the NFS export to be mounted with read-only permissions. - Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: boolean - server: - description: |- - server is the hostname or IP address of the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: |- - persistentVolumeClaimVolumeSource represents a reference to a - PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - properties: - claimName: - description: |- - claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - type: string - readOnly: - description: |- - readOnly Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: |- - photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. - Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - pdID: - description: pdID is the ID that identifies Photon - Controller persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: |- - portworxVolume represents a portworx volume attached and mounted on kubelets host machine. - Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - is on. - properties: - fsType: - description: |- - fSType represents the filesystem type to mount - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: volumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: projected items for all in one resources - secrets, configmaps, and downward API - properties: - defaultMode: - description: |- - defaultMode are the mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - sources: - description: |- - sources is the list of volume projections. Each entry in this list - handles one source. - items: - description: |- - Projection that may be projected along with other supported volume types. - Exactly one of these fields must be set. - properties: - clusterTrustBundle: - description: |- - ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field - of ClusterTrustBundle objects in an auto-updating file. - - Alpha, gated by the ClusterTrustBundleProjection feature gate. - - ClusterTrustBundle objects can either be selected by name, or by the - combination of signer name and a label selector. - - Kubelet performs aggressive normalization of the PEM contents written - into the pod filesystem. Esoteric PEM features such as inter-block - comments and block headers are stripped. Certificates are deduplicated. - The ordering of certificates within the file is arbitrary, and Kubelet - may change the order over time. - properties: - labelSelector: - description: |- - Select all ClusterTrustBundles that match this label selector. Only has - effect if signerName is set. Mutually-exclusive with name. If unset, - interpreted as "match nothing". If set but empty, interpreted as "match - everything". - properties: - matchExpressions: - description: matchExpressions is a - list of label selector requirements. - The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - name: - description: |- - Select a single ClusterTrustBundle by object name. Mutually-exclusive - with signerName and labelSelector. - type: string - optional: - description: |- - If true, don't block pod startup if the referenced ClusterTrustBundle(s) - aren't available. If using name, then the named ClusterTrustBundle is - allowed not to exist. If using signerName, then the combination of - signerName and labelSelector is allowed to match zero - ClusterTrustBundles. - type: boolean - path: - description: Relative path from the volume - root to write the bundle. - type: string - signerName: - description: |- - Select all ClusterTrustBundles that match this signer name. - Mutually-exclusive with name. The contents of all selected - ClusterTrustBundles will be unified and deduplicated. - type: string - required: - - path - type: object - configMap: - description: configMap information about the - configMap data to project - properties: - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a - path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional specify whether - the ConfigMap or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - description: downwardAPI information about - the downwardAPI data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects - a field of the pod: only annotations, - labels, name, namespace and uid - are supported.' - properties: - apiVersion: - description: Version of the - schema the FieldPath is written - in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field - to select in the specified - API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: |- - Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file - to be created. Must not be absolute - or contain the ''..'' path. Must - be utf-8 encoded. The first item - of the relative path must not - start with ''..''' - type: string - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. - properties: - containerName: - description: 'Container name: - required for volumes, optional - for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output - format of the exposed resources, - defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podCertificate: - description: |- - Projects an auto-rotating credential bundle (private key and certificate - chain) that the pod can use either as a TLS client or server. - - Kubelet generates a private key and uses it to send a - PodCertificateRequest to the named signer. Once the signer approves the - request and issues a certificate chain, Kubelet writes the key and - certificate chain to the pod filesystem. The pod does not start until - certificates have been issued for each podCertificate projected volume - source in its spec. - - Kubelet will begin trying to rotate the certificate at the time indicated - by the signer using the PodCertificateRequest.Status.BeginRefreshAt - timestamp. - - Kubelet can write a single file, indicated by the credentialBundlePath - field, or separate files, indicated by the keyPath and - certificateChainPath fields. - - The credential bundle is a single file in PEM format. The first PEM - entry is the private key (in PKCS#8 format), and the remaining PEM - entries are the certificate chain issued by the signer (typically, - signers will return their certificate chain in leaf-to-root order). - - Prefer using the credential bundle format, since your application code - can read it atomically. If you use keyPath and certificateChainPath, - your application must make two separate file reads. If these coincide - with a certificate rotation, it is possible that the private key and leaf - certificate you read may not correspond to each other. Your application - will need to check for this condition, and re-read until they are - consistent. - - The named signer controls chooses the format of the certificate it - issues; consult the signer implementation's documentation to learn how to - use the certificates it issues. - properties: - certificateChainPath: - description: |- - Write the certificate chain at this path in the projected volume. - - Most applications should use credentialBundlePath. When using keyPath - and certificateChainPath, your application needs to check that the key - and leaf certificate are consistent, because it is possible to read the - files mid-rotation. - type: string - credentialBundlePath: - description: |- - Write the credential bundle at this path in the projected volume. - - The credential bundle is a single file that contains multiple PEM blocks. - The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private - key. - - The remaining blocks are CERTIFICATE blocks, containing the issued - certificate chain from the signer (leaf and any intermediates). - - Using credentialBundlePath lets your Pod's application code make a single - atomic read that retrieves a consistent key and certificate chain. If you - project them to separate files, your application code will need to - additionally check that the leaf certificate was issued to the key. - type: string - keyPath: - description: |- - Write the key at this path in the projected volume. - - Most applications should use credentialBundlePath. When using keyPath - and certificateChainPath, your application needs to check that the key - and leaf certificate are consistent, because it is possible to read the - files mid-rotation. - type: string - keyType: - description: |- - The type of keypair Kubelet will generate for the pod. - - Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", - "ECDSAP521", and "ED25519". - type: string - maxExpirationSeconds: - description: |- - maxExpirationSeconds is the maximum lifetime permitted for the - certificate. - - Kubelet copies this value verbatim into the PodCertificateRequests it - generates for this projection. - - If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver - will reject values shorter than 3600 (1 hour). The maximum allowable - value is 7862400 (91 days). - - The signer implementation is then free to issue a certificate with any - lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 - seconds (1 hour). This constraint is enforced by kube-apiserver. - `kubernetes.io` signers will never issue certificates with a lifetime - longer than 24 hours. - format: int32 - type: integer - signerName: - description: Kubelet's generated CSRs - will be addressed to this signer. - type: string - required: - - keyType - - signerName - type: object - secret: - description: secret information about the - secret data to project - properties: - items: - description: |- - items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the Secret, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a - path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: optional field specify whether - the Secret or its key must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - description: serviceAccountToken is information - about the serviceAccountToken data to project - properties: - audience: - description: |- - audience is the intended audience of the token. A recipient of a token - must identify itself with an identifier specified in the audience of the - token, and otherwise should reject the token. The audience defaults to the - identifier of the apiserver. - type: string - expirationSeconds: - description: |- - expirationSeconds is the requested duration of validity of the service - account token. As the token approaches expiration, the kubelet volume - plugin will proactively rotate the service account token. The kubelet will - start trying to rotate the token if the token is older than 80 percent of - its time to live or if the token is older than 24 hours.Defaults to 1 hour - and must be at least 10 minutes. - format: int64 - type: integer - path: - description: |- - path is the path relative to the mount point of the file to project the - token into. - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - description: |- - quobyte represents a Quobyte mount on the host that shares a pod's lifetime. - Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported. - properties: - group: - description: |- - group to map volume access to - Default is no group - type: string - readOnly: - description: |- - readOnly here will force the Quobyte volume to be mounted with read-only permissions. - Defaults to false. - type: boolean - registry: - description: |- - registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple entries are separated with commas) - which acts as the central registry for volumes - type: string - tenant: - description: |- - tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by the plugin - type: string - user: - description: |- - user to map volume access to - Defaults to serivceaccount user - type: string - volume: - description: volume is a string that references - an already created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type of the volume that you want to mount. - Tip: Ensure that the filesystem type is supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - type: string - image: - description: |- - image is the rados image name. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - keyring: - default: /etc/ceph/keyring - description: |- - keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - monitors: - description: |- - monitors is a collection of Ceph monitors. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - description: |- - pool is the rados pool name. - Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - readOnly: - description: |- - readOnly here will force the ReadOnly setting in VolumeMounts. - Defaults to false. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: boolean - secretRef: - description: |- - secretRef is name of the authentication secret for RBDUser. If provided - overrides keyring. - Default is nil. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - description: |- - user is the rados user name. - Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it - type: string - required: - - image - - monitors - type: object - scaleIO: - description: |- - scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. - Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. - properties: - fsType: - default: xfs - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". - Default is "xfs". - type: string - gateway: - description: gateway is the host address of the - ScaleIO API Gateway. - type: string - protectionDomain: - description: protectionDomain is the name of the - ScaleIO Protection Domain for the configured storage. - type: string - readOnly: - description: |- - readOnly Defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef references to the secret for ScaleIO user and other - sensitive information. If this is not provided, Login operation will fail. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - description: sslEnabled Flag enable/disable SSL - communication with Gateway, default false - type: boolean - storageMode: - default: ThinProvisioned - description: |- - storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. - Default is ThinProvisioned. - type: string - storagePool: - description: storagePool is the ScaleIO Storage - Pool associated with the protection domain. - type: string - system: - description: system is the name of the storage system - as configured in ScaleIO. - type: string - volumeName: - description: |- - volumeName is the name of a volume already created in the ScaleIO system - that is associated with this volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: |- - secret represents a secret that should populate this volume. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret - properties: - defaultMode: - description: |- - defaultMode is Optional: mode bits used to set permissions on created files by default. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values - for mode bits. Defaults to 0644. - Directories within the path are not affected by this setting. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - items: - description: |- - items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume as a file whose name is the - key and content is the value. If specified, the listed keys will be - projected into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in the Secret, - the volume setup will error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: |- - mode is Optional: mode bits used to set permissions on this file. - Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. - If not specified, the volume defaultMode will be used. - This might be in conflict with other options that affect the file - mode, like fsGroup, and the result can be other mode bits set. - format: int32 - type: integer - path: - description: |- - path is the relative path of the file to map the key to. - May not be an absolute path. - May not contain the path element '..'. - May not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - description: optional field specify whether the - Secret or its keys must be defined - type: boolean - secretName: - description: |- - secretName is the name of the secret in the pod's namespace to use. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret - type: string - type: object - storageos: - description: |- - storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. - Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. - properties: - fsType: - description: |- - fsType is the filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - readOnly: - description: |- - readOnly defaults to false (read/write). ReadOnly here will force - the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: |- - secretRef specifies the secret to use for obtaining the StorageOS API - credentials. If not specified, default values will be attempted. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - description: |- - volumeName is the human-readable name of the StorageOS volume. Volume - names are only unique within a namespace. - type: string - volumeNamespace: - description: |- - volumeNamespace specifies the scope of the volume within StorageOS. If no - namespace is specified then the Pod's namespace will be used. This allows the - Kubernetes name scoping to be mirrored within StorageOS for tighter integration. - Set VolumeName to any name to override the default behaviour. - Set to "default" if you are not using namespaces within StorageOS. - Namespaces that do not pre-exist within StorageOS will be created. - type: string - type: object - vsphereVolume: - description: |- - vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine. - Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type - are redirected to the csi.vsphere.vmware.com CSI driver. - properties: - fsType: - description: |- - fsType is filesystem type to mount. - Must be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - type: string - storagePolicyID: - description: storagePolicyID is the storage Policy - Based Management (SPBM) profile ID associated - with the StoragePolicyName. - type: string - storagePolicyName: - description: storagePolicyName is the storage Policy - Based Management (SPBM) profile name. - type: string - volumePath: - description: volumePath is the path that identifies - vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - required: - - containers - type: object type: object x-kubernetes-preserve-unknown-fields: true resourceSelector: diff --git a/test/e2e/cmd/run/run.go b/test/e2e/cmd/run/run.go index 58805d7f829..60044ccb1b6 100644 --- a/test/e2e/cmd/run/run.go +++ b/test/e2e/cmd/run/run.go @@ -344,8 +344,8 @@ func (h *helper) installOperatorUnderTest() error { return err } - if _, _, err := h.kubectl("create", "-f", manifestFile); err != nil { - return fmt.Errorf("failed to create operator manifest: %w", err) + if _, _, err := h.kubectl("apply", "-f", manifestFile); err != nil { + return fmt.Errorf("failed to apply operator manifest: %w", err) } h.addCleanupFunc(h.deleteResources(manifestFile)) From 8331edb6a95b59d7f8358563993dd542afee1f82 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 08:42:38 -0600 Subject: [PATCH 53/90] adding back additional hashing --- pkg/controller/autoops/expected.go | 31 ++++++++++++------------- pkg/controller/autoops/expected_test.go | 10 ++++---- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 0d23a08a7c2..b6be402b78b 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -188,30 +188,29 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A return "", fmt.Errorf("failed to get autoops-secret: %w", err) } - // Disabling this atm, as I believe it's breaking things... // Hash secret keys, including optional keys. There's no code here to handle missing keys as // 1. The optional keys are included here. // 2. The required keys are already validated in the controller, so they should always be present. - // requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} - // for _, key := range requiredKeys { - // if data, ok := autoopsSecret.Data[key]; ok { - // _, _ = configHash.Write(data) - // } - // } + requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} + for _, key := range requiredKeys { + if data, ok := autoopsSecret.Data[key]; ok { + _, _ = configHash.Write(data) + } + } // // Hash ES API key secret - // esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) - // esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} - // var esAPIKeySecret corev1.Secret - // if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { - // return "", fmt.Errorf("failed to get ES API key secret %s: %w", esAPIKeySecretName, err) - // } + esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} + var esAPIKeySecret corev1.Secret + if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { + return "", fmt.Errorf("failed to get ES API key secret %s: %w", esAPIKeySecretName, err) + } // // This data may not exist on initial reconciliation, so we don't return an error if it's missing. // // This should resolve itself on the next reconciliation after the API key is created. - // if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { - // _, _ = configHash.Write(apiKeyData) - // } + if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { + _, _ = configHash.Write(apiKeyData) + } return fmt.Sprint(configHash.Sum32()), nil } diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index ed0c78aca8f..cb0d731f100 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -145,12 +145,12 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { expectedConfigHash := fnv.New32a() _, _ = expectedConfigHash.Write([]byte(configData)) // Hash autoops-secret values - // _, _ = expectedConfigHash.Write([]byte("test-autoops-token")) - // _, _ = expectedConfigHash.Write([]byte("https://test-otel-url")) - // _, _ = expectedConfigHash.Write([]byte("test-ccm-api-key")) - // _, _ = expectedConfigHash.Write([]byte("https://test-ccm-api-url")) + _, _ = expectedConfigHash.Write([]byte("test-autoops-token")) + _, _ = expectedConfigHash.Write([]byte("https://test-otel-url")) + _, _ = expectedConfigHash.Write([]byte("test-ccm-api-key")) + _, _ = expectedConfigHash.Write([]byte("https://test-ccm-api-url")) // Hash ES API key secret value - // _, _ = expectedConfigHash.Write([]byte("test-es-api-key")) + _, _ = expectedConfigHash.Write([]byte("test-es-api-key")) expectedHashStr := fmt.Sprint(expectedConfigHash.Sum32()) want := expectedDeployment(tt.args.autoops, tt.args.es, expectedHashStr) if !cmp.Equal(got, want) { From 16d1e7a54a3a7c26528e71f93588328242b0c245 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 09:55:14 -0600 Subject: [PATCH 54/90] using namers for all --- pkg/controller/autoops/api_key.go | 4 +++- pkg/controller/autoops/expected.go | 18 +++++++++--------- pkg/controller/autoops/expected_test.go | 5 +++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 1eb0a1f51bb..03f9dbf93b4 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "crypto/sha256" "fmt" "reflect" @@ -247,7 +248,8 @@ func storeAPIKeyInSecret( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { - secretName := apiKeySecretNameFor(types.NamespacedName{Namespace: policy.Namespace, Name: es.Name}) + namingHash := fmt.Sprintf("%x", sha256.Sum256([]byte(es.GetNamespace()+es.GetName())))[0:6] + secretName := AutoOpsAPIKeySecretNamer.Suffix(policy.GetName(), namingHash) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index b6be402b78b..1d3f24a8f6b 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -43,7 +43,10 @@ const ( var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments // according to the Policy name, and associated Elasticsearch name. - AutoOpsNamer = common_name.NewNamer("autoops") + AutoOpsNamer = common_name.NewNamer("autoops") + AutoOpsConfigNamer = common_name.NewNamer("autoops-config") + AutoOpsCASecretNamer = common_name.NewNamer("autoops-ca-secret") + AutoOpsAPIKeySecretNamer = common_name.NewNamer("autoops-api-key-secret") // Default resources for the AutoOps Agent deployment. // These currently mirror the defaults for the Elastic Agent deployment. defaultResources = corev1.ResourceRequirements{ @@ -63,13 +66,15 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli if err != nil { return appsv1.Deployment{}, err } + + namingHash := fmt.Sprintf("%x", sha256.Sum256([]byte(es.GetNamespace()+es.GetName())))[0:6] labels := map[string]string{ commonv1.TypeLabelName: "autoops-agent", autoOpsLabelName: policy.Name, } // Create ES-specific config map volume - configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + configMapName := AutoOpsConfigNamer.Suffix(policy.GetName(), namingHash) configVolume := volume.NewConfigMapVolume(configMapName, configVolumeName, configVolumePath) volumes := []corev1.Volume{configVolume.Volume()} @@ -77,7 +82,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli // Add CA certificate volume for this ES instance only if TLS is enabled if es.Spec.HTTP.TLS.Enabled() { - caSecretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretSuffix) + caSecretName := AutoOpsCASecretNamer.Suffix(policy.GetName(), namingHash) caVolume := volume.NewSecretVolumeWithMountPath( caSecretName, fmt.Sprintf("es-ca-%s-%s", es.Name, es.Namespace), @@ -127,13 +132,8 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli }). PodTemplate - // Hash ES namespace and name to create a short unique identifier - // preventing name length issues. - esIdentifier := es.GetNamespace() + es.GetName() - esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] - return common_deployment.New(common_deployment.Params{ - Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), + Name: AutoOpsNamer.Suffix(policy.GetName(), namingHash), Namespace: policy.GetNamespace(), Selector: map[string]string{ autoOpsLabelName: policy.GetName(), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index cb0d731f100..abfbd3898d9 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -175,9 +175,10 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast // Hash ES namespace and name to match the implementation esIdentifier := es.GetNamespace() + es.GetName() esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] + name := AutoOpsNamer.Suffix(policy.GetName(), esHash) return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: AutoOpsNamer.Suffix(policy.GetName(), esHash), + Name: name, Namespace: policy.GetNamespace(), Labels: labels, Annotations: annotations, @@ -201,7 +202,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, policy.GetNamespace(), es.GetName()), + Name: AutoOpsConfigNamer.Suffix(policy.GetName(), esHash), }, DefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode), Optional: ptr.To(false), From c71af79606d5c802de68f3956caa7fa73d564c64 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 10:17:51 -0600 Subject: [PATCH 55/90] reduce size of namer file name --- pkg/controller/autoops/expected.go | 10 +++++----- pkg/controller/autoops/expected_test.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 1d3f24a8f6b..1c595d3099e 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -43,10 +43,10 @@ const ( var ( // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments // according to the Policy name, and associated Elasticsearch name. - AutoOpsNamer = common_name.NewNamer("autoops") - AutoOpsConfigNamer = common_name.NewNamer("autoops-config") - AutoOpsCASecretNamer = common_name.NewNamer("autoops-ca-secret") - AutoOpsAPIKeySecretNamer = common_name.NewNamer("autoops-api-key-secret") + AutoOpsDeploymentNamer = common_name.NewNamer("deploy") + AutoOpsConfigNamer = common_name.NewNamer("config") + AutoOpsCASecretNamer = common_name.NewNamer("ca-secret") + AutoOpsAPIKeySecretNamer = common_name.NewNamer("api-key-secret") // Default resources for the AutoOps Agent deployment. // These currently mirror the defaults for the Elastic Agent deployment. defaultResources = corev1.ResourceRequirements{ @@ -133,7 +133,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli PodTemplate return common_deployment.New(common_deployment.Params{ - Name: AutoOpsNamer.Suffix(policy.GetName(), namingHash), + Name: AutoOpsDeploymentNamer.Suffix(policy.GetName(), namingHash), Namespace: policy.GetNamespace(), Selector: map[string]string{ autoOpsLabelName: policy.GetName(), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index abfbd3898d9..72f7a6a74fa 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -175,7 +175,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast // Hash ES namespace and name to match the implementation esIdentifier := es.GetNamespace() + es.GetName() esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] - name := AutoOpsNamer.Suffix(policy.GetName(), esHash) + name := AutoOpsDeploymentNamer.Suffix(policy.GetName(), esHash) return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: name, From e196050a50e0cc1e487ca8d6b0d5dd7d659f3983 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 10:55:33 -0600 Subject: [PATCH 56/90] centralize autoops naming --- pkg/apis/autoops/v1alpha1/name.go | 47 +++++++++++++++++++++++++ pkg/controller/autoops/api_key.go | 4 +-- pkg/controller/autoops/expected.go | 15 ++------ pkg/controller/autoops/expected_test.go | 8 ++--- 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 pkg/apis/autoops/v1alpha1/name.go diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go new file mode 100644 index 00000000000..05f7f0ceb21 --- /dev/null +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -0,0 +1,47 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/hash" + common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" +) + +var ( + // AutoOpsNamer is a Namer that is configured with the defaults for resources related to an AutoOps agent.a + AutoOpsNamer = common_name.NewNamer("autoops") +) + +const ( + deploymentSuffix = "deploy" + configSuffix = "config" + caSecretSuffix = "ca-secret" //nolint:gosec + apiKeySecretSuffix = "api-key-secret" //nolint:gosec +) + +// Deployment returns the name of the deployment for the given policy and ES instance. +func Deployment(policyName string, es esv1.Elasticsearch) string { + hash := hash.HashObject(es.GetNamespace() + es.GetName()) + return AutoOpsNamer.Suffix(policyName, deploymentSuffix, hash) +} + +// Config returns the name of the ConfigMap which holds the AutoOps Agent configuration for the given policy and ES instance. +func Config(policyName string, es esv1.Elasticsearch) string { + hash := hash.HashObject(es.GetNamespace() + es.GetName()) + return AutoOpsNamer.Suffix(policyName, configSuffix, hash) +} + +// CASecret returns the name of the Secret which holds the Elasticsearch CA certificate for the given policy and ES instance. +func CASecret(policyName string, es esv1.Elasticsearch) string { + hash := hash.HashObject(es.GetNamespace() + es.GetName()) + return AutoOpsNamer.Suffix(policyName, caSecretSuffix, hash) +} + +// APIKeySecret returns the name of the Secret which holds the Elasticsearch API key for the given policy and ES instance. +func APIKeySecret(policyName string, es esv1.Elasticsearch) string { + hash := hash.HashObject(es.GetNamespace() + es.GetName()) + return AutoOpsNamer.Suffix(policyName, apiKeySecretSuffix, hash) +} diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 03f9dbf93b4..92bb35dd3dd 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "crypto/sha256" "fmt" "reflect" @@ -248,8 +247,7 @@ func storeAPIKeyInSecret( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { - namingHash := fmt.Sprintf("%x", sha256.Sum256([]byte(es.GetNamespace()+es.GetName())))[0:6] - secretName := AutoOpsAPIKeySecretNamer.Suffix(policy.GetName(), namingHash) + secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), es) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 1c595d3099e..f57c2e32b30 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "crypto/sha256" "fmt" "hash/fnv" "path" @@ -25,7 +24,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/defaults" common_deployment "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/deployment" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" - common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/version" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/volume" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/services" @@ -41,12 +39,6 @@ const ( ) var ( - // ESNAutoOpsNamer is a Namer that generates names for AutoOps deployments - // according to the Policy name, and associated Elasticsearch name. - AutoOpsDeploymentNamer = common_name.NewNamer("deploy") - AutoOpsConfigNamer = common_name.NewNamer("config") - AutoOpsCASecretNamer = common_name.NewNamer("ca-secret") - AutoOpsAPIKeySecretNamer = common_name.NewNamer("api-key-secret") // Default resources for the AutoOps Agent deployment. // These currently mirror the defaults for the Elastic Agent deployment. defaultResources = corev1.ResourceRequirements{ @@ -67,14 +59,13 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli return appsv1.Deployment{}, err } - namingHash := fmt.Sprintf("%x", sha256.Sum256([]byte(es.GetNamespace()+es.GetName())))[0:6] labels := map[string]string{ commonv1.TypeLabelName: "autoops-agent", autoOpsLabelName: policy.Name, } // Create ES-specific config map volume - configMapName := AutoOpsConfigNamer.Suffix(policy.GetName(), namingHash) + configMapName := autoopsv1alpha1.Config(policy.GetName(), es) configVolume := volume.NewConfigMapVolume(configMapName, configVolumeName, configVolumePath) volumes := []corev1.Volume{configVolume.Volume()} @@ -82,7 +73,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli // Add CA certificate volume for this ES instance only if TLS is enabled if es.Spec.HTTP.TLS.Enabled() { - caSecretName := AutoOpsCASecretNamer.Suffix(policy.GetName(), namingHash) + caSecretName := autoopsv1alpha1.CASecret(policy.GetName(), es) caVolume := volume.NewSecretVolumeWithMountPath( caSecretName, fmt.Sprintf("es-ca-%s-%s", es.Name, es.Namespace), @@ -133,7 +124,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli PodTemplate return common_deployment.New(common_deployment.Params{ - Name: AutoOpsDeploymentNamer.Suffix(policy.GetName(), namingHash), + Name: autoopsv1alpha1.Deployment(policy.GetName(), es), Namespace: policy.GetNamespace(), Selector: map[string]string{ autoOpsLabelName: policy.GetName(), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 72f7a6a74fa..b2db1eb03bf 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -6,7 +6,6 @@ package autoops import ( "context" - "crypto/sha256" "fmt" "hash/fnv" "testing" @@ -172,10 +171,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast configHashAnnotationName: configHashValue, } - // Hash ES namespace and name to match the implementation - esIdentifier := es.GetNamespace() + es.GetName() - esHash := fmt.Sprintf("%x", sha256.Sum256([]byte(esIdentifier)))[0:6] - name := AutoOpsDeploymentNamer.Suffix(policy.GetName(), esHash) + name := autoopsv1alpha1.Deployment(policy.GetName(), es) return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -202,7 +198,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: AutoOpsConfigNamer.Suffix(policy.GetName(), esHash), + Name: autoopsv1alpha1.Config(policy.GetName(), es), }, DefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode), Optional: ptr.To(false), From a08eda64b9ee7c89084b0abd1e6d824904a48de8 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 11:04:23 -0600 Subject: [PATCH 57/90] fix linting --- pkg/apis/autoops/v1alpha1/name.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go index 05f7f0ceb21..873631fa0bf 100644 --- a/pkg/apis/autoops/v1alpha1/name.go +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -18,8 +18,8 @@ var ( const ( deploymentSuffix = "deploy" configSuffix = "config" - caSecretSuffix = "ca-secret" //nolint:gosec - apiKeySecretSuffix = "api-key-secret" //nolint:gosec + caSecretSuffix = "ca-secret" + apiKeySecretSuffix = "api-key-secret" ) // Deployment returns the name of the deployment for the given policy and ES instance. From f6209d593d3a78675bf3d9bbe4d228bbbaa35923 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 13:40:37 -0600 Subject: [PATCH 58/90] better control namer length --- pkg/apis/autoops/v1alpha1/name.go | 4 +- pkg/apis/autoops/v1alpha1/name_test.go | 82 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 pkg/apis/autoops/v1alpha1/name_test.go diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go index 873631fa0bf..f4212e85fea 100644 --- a/pkg/apis/autoops/v1alpha1/name.go +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -18,8 +18,8 @@ var ( const ( deploymentSuffix = "deploy" configSuffix = "config" - caSecretSuffix = "ca-secret" - apiKeySecretSuffix = "api-key-secret" + caSecretSuffix = "ca" + apiKeySecretSuffix = "apikey" ) // Deployment returns the name of the deployment for the given policy and ES instance. diff --git a/pkg/apis/autoops/v1alpha1/name_test.go b/pkg/apis/autoops/v1alpha1/name_test.go new file mode 100644 index 00000000000..5c88e9eea36 --- /dev/null +++ b/pkg/apis/autoops/v1alpha1/name_test.go @@ -0,0 +1,82 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package v1alpha1 + +import ( + "strings" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" +) + +func TestCASecret(t *testing.T) { + maxLength := 27 + tests := []struct { + name string + policyName string + es esv1.Elasticsearch + want string + }{ + { + name: "test-cas-secret-too-long", + policyName: "eck-autoops-config-policy", + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testing", + Namespace: "elastic", + }, + }, + want: "eck-autoops-config-policy-autoops-ca-4269947480", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := CASecret(tt.policyName, tt.es) + if got != tt.want { + t.Errorf("CASecret() = %v, want %v", got, tt.want) + } + suffix, _ := strings.CutPrefix(got, tt.policyName) + if len(suffix) > maxLength { + t.Errorf("CASecret(): suffix %s: length %d, want length %d", suffix, len(suffix), maxLength) + } + }) + } +} + +func TestAPIKeySecret(t *testing.T) { + maxLength := 27 + tests := []struct { + name string + policyName string + es esv1.Elasticsearch + want string + }{ + { + name: "test-api-key-secret-too-long", + policyName: "eck-autoops-config-policy", + es: esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testing", + Namespace: "elastic", + }, + }, + want: "eck-autoops-config-policy-autoops-pkg/apis/autoops/v1alpha1/name_test.go-4269947480", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := APIKeySecret(tt.policyName, tt.es) + if got != tt.want { + t.Errorf("APIKeySecret() = %v, want %v", got, tt.want) + } + suffix, _ := strings.CutPrefix(got, tt.policyName) + if len(suffix) > maxLength { + t.Errorf("CASecret(): suffix %s: length %d, want length %d", suffix, len(suffix), maxLength) + } + }) + } +} From 7dc93ad00421b03a5370e44cb27295cadfbc224c Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 14:36:07 -0600 Subject: [PATCH 59/90] fix updatewithphase transitions --- pkg/apis/autoops/v1alpha1/name.go | 2 +- pkg/apis/autoops/v1alpha1/name_test.go | 2 +- pkg/controller/autoops/state.go | 15 ++- pkg/controller/autoops/state_test.go | 162 +++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 pkg/controller/autoops/state_test.go diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go index f4212e85fea..c2a55dd8c6c 100644 --- a/pkg/apis/autoops/v1alpha1/name.go +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -11,7 +11,7 @@ import ( ) var ( - // AutoOpsNamer is a Namer that is configured with the defaults for resources related to an AutoOps agent.a + // AutoOpsNamer is a Namer that is configured with the defaults for resources related to an AutoOps agent AutoOpsNamer = common_name.NewNamer("autoops") ) diff --git a/pkg/apis/autoops/v1alpha1/name_test.go b/pkg/apis/autoops/v1alpha1/name_test.go index 5c88e9eea36..f070565289d 100644 --- a/pkg/apis/autoops/v1alpha1/name_test.go +++ b/pkg/apis/autoops/v1alpha1/name_test.go @@ -64,7 +64,7 @@ func TestAPIKeySecret(t *testing.T) { Namespace: "elastic", }, }, - want: "eck-autoops-config-policy-autoops-pkg/apis/autoops/v1alpha1/name_test.go-4269947480", + want: "eck-autoops-config-policy-autoops-apikey-4269947480", }, } for _, tt := range tests { diff --git a/pkg/controller/autoops/state.go b/pkg/controller/autoops/state.go index 2c0f3da91be..e64fd533b65 100644 --- a/pkg/controller/autoops/state.go +++ b/pkg/controller/autoops/state.go @@ -11,6 +11,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/events" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/set" ) // State holds the accumulated state during the reconcile loop including the response and a copy of the @@ -37,14 +38,22 @@ func NewState(policy autoopsv1alpha1.AutoOpsAgentPolicy) *State { // UpdateWithPhase updates the phase of the AutoOpsAgentPolicy status. // It respects phase stickiness - InvalidPhase will not be overwritten, and ApplyingChangesPhase -// will not overwrite other non-ready phases. +// and ReadyPhase will not overwrite other non-ready phases. func (s *State) UpdateWithPhase(phase autoopsv1alpha1.PolicyPhase) *State { + nonReadyPhases := set.Make( + string(autoopsv1alpha1.ErrorPhase), + string(autoopsv1alpha1.NoResourcesPhase), + string(autoopsv1alpha1.UnknownPhase), + ) switch { // do not overwrite the Invalid phase case s.status.Phase == autoopsv1alpha1.InvalidPhase: return s - // do not overwrite non-ready phases like ErrorPhase or NoResourcesPhase - case s.status.Phase != "" && phase == autoopsv1alpha1.ApplyingChangesPhase: + // do not overwrite non-ready phases with ApplyingChangesPhase + case phase == autoopsv1alpha1.ApplyingChangesPhase && nonReadyPhases.Has(string(s.status.Phase)): + return s + // do not overwrite non-ready phases with ReadyPhase + case phase == autoopsv1alpha1.ReadyPhase && nonReadyPhases.Has(string(s.status.Phase)): return s } s.status.Phase = phase diff --git a/pkg/controller/autoops/state_test.go b/pkg/controller/autoops/state_test.go new file mode 100644 index 00000000000..8908d9dc0ed --- /dev/null +++ b/pkg/controller/autoops/state_test.go @@ -0,0 +1,162 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" +) + +func TestState_UpdateWithPhase(t *testing.T) { + tests := []struct { + name string + initialPhase autoopsv1alpha1.PolicyPhase + updatePhase autoopsv1alpha1.PolicyPhase + expectedPhase autoopsv1alpha1.PolicyPhase + shouldUpdate bool + }{ + { + name: "empty phase can transition to ReadyPhase", + initialPhase: "", + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.ReadyPhase, + shouldUpdate: true, + }, + { + name: "empty phase can transition to ErrorPhase", + initialPhase: "", + updatePhase: autoopsv1alpha1.ErrorPhase, + expectedPhase: autoopsv1alpha1.ErrorPhase, + shouldUpdate: true, + }, + { + name: "empty phase can transition to ApplyingChangesPhase", + initialPhase: "", + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.ApplyingChangesPhase, + shouldUpdate: true, + }, + { + name: "empty phase can transition to InvalidPhase", + initialPhase: "", + updatePhase: autoopsv1alpha1.InvalidPhase, + expectedPhase: autoopsv1alpha1.InvalidPhase, + shouldUpdate: true, + }, + { + name: "empty phase can transition to NoResourcesPhase", + initialPhase: "", + updatePhase: autoopsv1alpha1.NoResourcesPhase, + expectedPhase: autoopsv1alpha1.NoResourcesPhase, + shouldUpdate: true, + }, + { + name: "InvalidPhase should not be overwritten by ReadyPhase", + initialPhase: autoopsv1alpha1.InvalidPhase, + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.InvalidPhase, + shouldUpdate: false, + }, + { + name: "InvalidPhase should not be overwritten by ErrorPhase", + initialPhase: autoopsv1alpha1.InvalidPhase, + updatePhase: autoopsv1alpha1.ErrorPhase, + expectedPhase: autoopsv1alpha1.InvalidPhase, + shouldUpdate: false, + }, + { + name: "InvalidPhase should not be overwritten by ApplyingChangesPhase", + initialPhase: autoopsv1alpha1.InvalidPhase, + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.InvalidPhase, + shouldUpdate: false, + }, + { + name: "InvalidPhase should not be overwritten by NoResourcesPhase", + initialPhase: autoopsv1alpha1.InvalidPhase, + updatePhase: autoopsv1alpha1.NoResourcesPhase, + expectedPhase: autoopsv1alpha1.InvalidPhase, + shouldUpdate: false, + }, + { + name: "ErrorPhase should not be overwritten by ApplyingChangesPhase", + initialPhase: autoopsv1alpha1.ErrorPhase, + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.ErrorPhase, + shouldUpdate: false, + }, + { + name: "NoResourcesPhase should not be overwritten by ApplyingChangesPhase", + initialPhase: autoopsv1alpha1.NoResourcesPhase, + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.NoResourcesPhase, + shouldUpdate: false, + }, + { + name: "UnknownPhase should not be overwritten by ApplyingChangesPhase", + initialPhase: autoopsv1alpha1.UnknownPhase, + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.UnknownPhase, + shouldUpdate: false, + }, + { + name: "ReadyPhase can be overwritten by ApplyingChangesPhase", + initialPhase: autoopsv1alpha1.ReadyPhase, + updatePhase: autoopsv1alpha1.ApplyingChangesPhase, + expectedPhase: autoopsv1alpha1.ApplyingChangesPhase, + shouldUpdate: true, + }, + { + name: "ErrorPhase should not be overwritten by ReadyPhase", + initialPhase: autoopsv1alpha1.ErrorPhase, + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.ErrorPhase, + shouldUpdate: false, + }, + { + name: "NoResourcesPhase should not be overwritten by ReadyPhase", + initialPhase: autoopsv1alpha1.NoResourcesPhase, + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.NoResourcesPhase, + shouldUpdate: false, + }, + { + name: "UnknownPhase should not be overwritten by ReadyPhase", + initialPhase: autoopsv1alpha1.UnknownPhase, + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.UnknownPhase, + shouldUpdate: false, + }, + { + name: "ApplyingChangesPhase can transition to ReadyPhase", + initialPhase: autoopsv1alpha1.ApplyingChangesPhase, + updatePhase: autoopsv1alpha1.ReadyPhase, + expectedPhase: autoopsv1alpha1.ReadyPhase, + shouldUpdate: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + policy := autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-policy", + Namespace: "default", + }, + Status: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Phase: tt.initialPhase, + }, + } + state := NewState(policy) + state.status.Phase = tt.initialPhase + state.UpdateWithPhase(tt.updatePhase) + assert.Equal(t, tt.expectedPhase, state.status.Phase) + }) + } +} From f5d35fe4ab234d72e9fce577e4db8ff905e4ea77 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 15:00:06 -0600 Subject: [PATCH 60/90] making the naming consistent for secrets --- pkg/apis/autoops/v1alpha1/name.go | 5 +++-- pkg/apis/autoops/v1alpha1/name_test.go | 12 ++++-------- pkg/controller/autoops/api_key.go | 19 ++++++++----------- pkg/controller/autoops/controller.go | 4 +++- pkg/controller/autoops/controller_test.go | 3 ++- pkg/controller/autoops/expected.go | 8 ++++---- pkg/controller/autoops/expected_test.go | 8 ++++---- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go index c2a55dd8c6c..5f529d7417c 100644 --- a/pkg/apis/autoops/v1alpha1/name.go +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -8,6 +8,7 @@ import ( esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/hash" common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" + "k8s.io/apimachinery/pkg/types" ) var ( @@ -41,7 +42,7 @@ func CASecret(policyName string, es esv1.Elasticsearch) string { } // APIKeySecret returns the name of the Secret which holds the Elasticsearch API key for the given policy and ES instance. -func APIKeySecret(policyName string, es esv1.Elasticsearch) string { - hash := hash.HashObject(es.GetNamespace() + es.GetName()) +func APIKeySecret(policyName string, es types.NamespacedName) string { + hash := hash.HashObject(es.Namespace + es.Name) return AutoOpsNamer.Suffix(policyName, apiKeySecretSuffix, hash) } diff --git a/pkg/apis/autoops/v1alpha1/name_test.go b/pkg/apis/autoops/v1alpha1/name_test.go index f070565289d..4721017adc4 100644 --- a/pkg/apis/autoops/v1alpha1/name_test.go +++ b/pkg/apis/autoops/v1alpha1/name_test.go @@ -9,6 +9,7 @@ import ( "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" ) @@ -52,19 +53,14 @@ func TestAPIKeySecret(t *testing.T) { tests := []struct { name string policyName string - es esv1.Elasticsearch + es types.NamespacedName want string }{ { name: "test-api-key-secret-too-long", policyName: "eck-autoops-config-policy", - es: esv1.Elasticsearch{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testing", - Namespace: "elastic", - }, - }, - want: "eck-autoops-config-policy-autoops-apikey-4269947480", + es: types.NamespacedName{Namespace: "elastic", Name: "testing"}, + want: "eck-autoops-config-policy-autoops-apikey-4269947480", }, } for _, tt := range tests { diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 92bb35dd3dd..ab63ad0771b 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -167,7 +167,7 @@ func maybeUpdateAPIKey( } // The API key is seemingly up to date, so we need to ensure the secret exists with correct value - secretName := apiKeySecretNameFor(types.NamespacedName{Namespace: policy.Namespace, Name: es.Name}) + secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) var secret corev1.Secret nsn := types.NamespacedName{ Namespace: policy.Namespace, @@ -247,7 +247,7 @@ func storeAPIKeyInSecret( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { - secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), es) + secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} @@ -310,11 +310,6 @@ func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsea return fmt.Sprintf("autoops-%s-%s-%s-%s", policy.Namespace, policy.Name, es.Namespace, es.Name) } -// apiKeySecretNameFrom generates the name for the API key secret from an ES instance. -func apiKeySecretNameFor(es types.NamespacedName) string { - return fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESAPIKeySecretNameSuffix) -} - // newMetadataFor returns the metadata to be set in the Elasticsearch API key. func newMetadataFor(policy *autoopsv1alpha1.AutoOpsAgentPolicy, es *esv1.Elasticsearch, expectedHash string) map[string]string { return map[string]string{ @@ -374,13 +369,15 @@ func cleanupAutoOpsESAPIKey( } } - return deleteESAPIKeySecret(ctx, c, log, policyNamespace, types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + return deleteESAPIKeySecret(ctx, c, log, + types.NamespacedName{Namespace: policyNamespace, Name: policyName}, + types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) } -func deleteESAPIKeySecret(ctx context.Context, c k8s.Client, log logr.Logger, policyNamespace string, es types.NamespacedName) error { - secretName := apiKeySecretNameFor(es) +func deleteESAPIKeySecret(ctx context.Context, c k8s.Client, log logr.Logger, policy types.NamespacedName, es types.NamespacedName) error { + secretName := autoopsv1alpha1.APIKeySecret(policy.Name, es) secretKey := types.NamespacedName{ - Namespace: policyNamespace, + Namespace: policy.Namespace, Name: secretName, } var secret corev1.Secret diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 488a06e1108..02cb1c511c1 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -239,7 +239,9 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na if err := r.Client.Get(ctx, types.NamespacedName{Namespace: esNamespace, Name: esName}, &es); err != nil { if apierrors.IsNotFound(err) { // The ES cluster is gone, so we need to delete the API key secret - if err := deleteESAPIKeySecret(ctx, r.Client, log, obj.Namespace, types.NamespacedName{Namespace: esNamespace, Name: esName}); err != nil { + if err := deleteESAPIKeySecret(ctx, r.Client, log, + types.NamespacedName{Namespace: obj.Namespace, Name: obj.Name}, + types.NamespacedName{Namespace: esNamespace, Name: esName}); err != nil { log.Error(err, "Failed to delete API key secret", "es_namespace", esNamespace, "es_name", esName) } continue diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index 67b1f43766b..4a6849483b0 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -17,6 +17,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" @@ -286,7 +287,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { for _, es := range tt.esClusters { if es.Status.Phase == esv1.ElasticsearchReadyPhase { - expectedSecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + expectedSecretName := autoopsv1alpha1.APIKeySecret(tt.policy.Name, types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) var retrievedSecret corev1.Secret err := k8sClient.Get(ctx, types.NamespacedName{Namespace: tt.policy.Namespace, Name: expectedSecretName}, &retrievedSecret) assert.True(t, apierrors.IsNotFound(err), "Expected secret %s/%s to be deleted", tt.policy.Namespace, expectedSecretName) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index f57c2e32b30..f0a83404d90 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -96,7 +96,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli WithLabels(meta.Labels). WithAnnotations(meta.Annotations). WithDockerImage(policy.Spec.Image, container.ImageRepository(container.AutoOpsAgentImage, v)). - WithEnv(autoopsEnvVars(es)...). + WithEnv(autoopsEnvVars(policy, es)...). WithResources(defaultResources). WithVolumes(volumes...). WithVolumeMounts(volumeMounts...). @@ -190,7 +190,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A } // // Hash ES API key secret - esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} var esAPIKeySecret corev1.Secret if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { @@ -208,7 +208,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A // autoopsEnvVars returns the environment variables for the AutoOps deployment // that reference values from the autoops-secret and the ES elastic user secret. -func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { +func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) []corev1.EnvVar { esService := services.InternalServiceURL(es) return []corev1.EnvVar{ { @@ -242,7 +242,7 @@ func autoopsEnvVars(es esv1.Elasticsearch) []corev1.EnvVar { ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), + Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), }, Key: "api_key", Optional: ptr.To(false), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index b2db1eb03bf..6e8f2a478f2 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -118,7 +118,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { } // We need the ES API key secret as well to build the config hash - esAPIKeySecretName := apiKeySecretNameFor(types.NamespacedName{Namespace: tt.args.es.Namespace, Name: tt.args.es.Name}) + esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(tt.args.autoops.Name, types.NamespacedName{Namespace: tt.args.es.Namespace, Name: tt.args.es.Name}) esAPIKeySecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: esAPIKeySecretName, @@ -276,7 +276,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: apiKeySecretNameFor(types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), + Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), }, Key: "api_key", Optional: ptr.To(false), @@ -412,7 +412,7 @@ func Test_autoopsEnvVars(t *testing.T) { ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "es-1-ns-1-autoops-es-api-key", + Name: "policy-1-autoops-apikey-2334712842", }, Key: "api_key", Optional: ptr.To(false), @@ -447,7 +447,7 @@ func Test_autoopsEnvVars(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := autoopsEnvVars(tt.es) + got := autoopsEnvVars(tt.policy, tt.es) if !cmp.Equal(got, tt.want) { t.Errorf("autoopsEnvVars() diff = %v", cmp.Diff(got, tt.want)) } From f8e6e25fb2adf70561df39dcf84430dc8af66b2b Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 15:14:58 -0600 Subject: [PATCH 61/90] again; consistent naming --- pkg/controller/autoops/configmap.go | 2 +- pkg/controller/autoops/secret.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 2dcaafd1551..89e255cb387 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -175,7 +175,7 @@ func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1. } // Use ES-specific ConfigMap name to allow per-ES configuration - configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + configMapName := autoopsv1alpha1.Config(policy.GetName(), es) return corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 998f23c2c45..488d642dfd7 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -63,7 +63,7 @@ func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESCASecret( return nil } - secretName := fmt.Sprintf("%s-%s-%s", es.Name, es.Namespace, autoOpsESCASecretSuffix) + secretName := autoopsv1alpha1.CASecret(policy.GetName(), es) expected := buildAutoOpsESCASecret(policy, secretName, caCert) reconciled := &corev1.Secret{} From d2a34e59a82ddd68d08d03d4aa6c5c926c0f3c2d Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 17:31:22 -0600 Subject: [PATCH 62/90] adding better error handling --- pkg/controller/autoops/reconcile.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index e6fcd378cf2..6afef338954 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -101,12 +101,14 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( for _, es := range esList.Items { if es.Status.Phase != esv1.ElasticsearchReadyPhase { + log.V(1).Info("Skipping ES cluster that is not ready", "namespace", es.Namespace, "name", es.Name) results = results.WithRequeue(defaultRequeue) continue } if es.Spec.HTTP.TLS.Enabled() { if err := r.reconcileAutoOpsESCASecret(ctx, policy, es); err != nil { + log.Error(err, "Error reconciling AutoOps ES CA secret", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue @@ -114,12 +116,14 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { + log.Error(err, "Error reconciling AutoOps ES API key", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue } if err := ReconcileAutoOpsESConfigMap(ctx, r.Client, policy, es); err != nil { + log.Error(err, "Error reconciling AutoOps ES config map", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue @@ -127,6 +131,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( deploymentParams, err := r.deploymentParams(ctx, policy, es) if err != nil { + log.Error(err, "Error getting deployment params", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue @@ -134,6 +139,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( reconciledDeployment, err := deployment.Reconcile(ctx, r.Client, deploymentParams, &policy) if err != nil { + log.Error(err, "Error reconciling deployment", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) continue From 46eca6d450279d484c5e09523cdc51f241a76d44 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 17:37:27 -0600 Subject: [PATCH 63/90] add event when not reconciled --- pkg/controller/autoops/controller.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 02cb1c511c1..9f5c551d5a6 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -160,8 +160,9 @@ func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request rec // updatePhaseFromResults updates the phase of the AutoOpsAgentPolicy status based on the results of the reconciliation func updatePhaseFromResults(results *reconciler.Results, state *State) { - if isReconciled, _ := results.IsReconciled(); !isReconciled { + if isReconciled, message := results.IsReconciled(); !isReconciled { state.UpdateWithPhase(autoopsv1alpha1.ApplyingChangesPhase) + state.AddEvent(corev1.EventTypeWarning, events.EventReasonDelayed, message) } else { state.UpdateWithPhase(autoopsv1alpha1.ReadyPhase) } From e982d40f19aecfc418b5a3264134e48b8bd6e090 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 17:39:31 -0600 Subject: [PATCH 64/90] use correct configmap name --- pkg/controller/autoops/expected.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index f0a83404d90..89ece035169 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -161,7 +161,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A configHash := fnv.New32a() // Hash ConfigMap data - configMapName := fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, es.Namespace, es.Name) + configMapName := autoopsv1alpha1.Config(policy.GetName(), es) var configMap corev1.ConfigMap configMapKey := types.NamespacedName{Namespace: policy.Namespace, Name: configMapName} if err := c.Get(ctx, configMapKey, &configMap); err != nil { From c4913a2072f0f5dbd24c02bb6c8f816c59b1e750 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 18:01:04 -0600 Subject: [PATCH 65/90] cleanup logger; pass back errors via result --- pkg/controller/autoops/api_key.go | 4 ---- pkg/controller/autoops/controller.go | 7 +++++-- pkg/controller/autoops/reconcile.go | 5 +++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index ab63ad0771b..47b290333f3 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -64,8 +64,6 @@ func reconcileAutoOpsESAPIKey( log := ulog.FromContext(ctx).WithValues( "es_namespace", es.Namespace, "es_name", es.Name, - "policy_namespace", policy.Namespace, - "policy_name", policy.Name, ) log.V(1).Info("Reconciling AutoOps ES API key") @@ -334,8 +332,6 @@ func cleanupAutoOpsESAPIKey( log := ulog.FromContext(ctx).WithValues( "es_namespace", es.Namespace, "es_name", es.Name, - "policy_namespace", policyNamespace, - "policy_name", policyName, ) log.V(1).Info("Cleaning up AutoOps ES API key") diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 9f5c551d5a6..e42a8cdfecd 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -115,7 +115,10 @@ type ReconcileAutoOpsAgentPolicy struct { // Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any resources are created/updated/deleted as needed. func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) - log := ulog.FromContext(ctx) + log := ulog.FromContext(ctx).WithValues( + "policy_namespace", request.Namespace, + "policy_name", request.Name, + ) defer common.LogReconciliationRun(log)() defer tracing.EndContextTransaction(ctx) @@ -210,7 +213,7 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() - log := ulog.FromContext(ctx).WithValues("policy_namespace", obj.Namespace, "policy_name", obj.Name) + log := ulog.FromContext(ctx) log.Info("Cleaning up AutoOpsAgentPolicy resources") // Remove dynamic watches on secrets diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 6afef338954..82c5cf94dd5 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -111,6 +111,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log.Error(err, "Error reconciling AutoOps ES CA secret", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + results.WithError(err) continue } } @@ -119,6 +120,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log.Error(err, "Error reconciling AutoOps ES API key", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + results.WithError(err) continue } @@ -126,6 +128,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log.Error(err, "Error reconciling AutoOps ES config map", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + results.WithError(err) continue } @@ -134,6 +137,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log.Error(err, "Error getting deployment params", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + results.WithError(err) continue } @@ -142,6 +146,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log.Error(err, "Error reconciling deployment", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) + results.WithError(err) continue } From 63b79dfd7d8c5fab8c54846016eb94d4bd084d79 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 18:08:41 -0600 Subject: [PATCH 66/90] make configref.secret required in helm chart --- .../templates/autoopsagentpolicy.yaml | 10 ++------ .../eck-stack/charts/eck-autoops/values.yaml | 25 ++++++------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml index e78f876980b..956a645659a 100644 --- a/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml +++ b/deploy/eck-stack/charts/eck-autoops/templates/autoopsagentpolicy.yaml @@ -26,13 +26,7 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} config: - {{- if .Values.configRef }} - secretName: {{ required "configRef.secretName is required when configRef is specified" .Values.configRef.secretName }} - {{- else }} - secretName: {{ printf "%s-config" (include "autoops.fullname" .) }} - {{- end }} - {{- with .Values.resourceSelector }} + secretName: {{ required "configRef.secretName is required to reference the AutoOps configuration secret" .Values.configRef.secretName }} resourceSelector: - {{- toYaml . | nindent 4 }} - {{- end }} + {{- required "resourceSelector is required" .Values.resourceSelector | toYaml | nindent 4 }} diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index 13319a72326..33067026433 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -28,28 +28,17 @@ labels: {} # annotations: {} -# AutoOps configuration values. -# These values are required and will be used to create a Kubernetes Secret. +# Reference an existing Kubernetes secret holding the AutoOps configuration. # -# All of these can be obtained the Elastic Cloud Console (https://cloud.elastic.co/connect-cluster-services-portal) +# All of the following items can be obtained the Elastic Cloud Console (https://cloud.elastic.co/connect-cluster-services-portal) # by selecting the ECK connect wizard and following the instructions. # -# This is the Cloud Connected Mode API key and is required. This is used to register the Agent with Elastic Cloud AutoOps. -ccmApiKey: "" -# This is the URL of the AutoOps OTel endpoint and is required. This is used to send Agent data to the AutoOps platform and is region specific. -# Example: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" -autoOpsOTelURL: "" -# This token is required and is how AutoOps knows how to connect Agent data to the relevant Elastic Cloud organization -autoOpsToken: "" -# URL of the Cloud Connected Mode API. -# This is not a required field. -cloudConnectedModeAPIURL: "" - -# Reference an existing Kubernetes secret holding the AutoOps configuration. # The referenced secret must contain the following: -# - `ccmApiKey`: the Cloud Connected Mode API key -# - `autoOpsOTelURL`: the URL of the AutoOps OTel endpoint -# - `autoOpsToken`: the token to authenticate against the AutoOps platform +# - `ccmApiKey`: the Cloud Connected Mode API key. This is used to register the Agent with Elastic Cloud AutoOps. +# - `autoOpsOTelURL`: the URL of the AutoOps OTel endpoint. This is used to send Agent data to the AutoOps platform and is region specific. +# Example: "https://otel-auto-ops.us-east-2.aws.svc.elastic.cloud" +# - `autoOpsToken`: the token to authenticate against the AutoOps platform and is how AutoOps knows how to connect Agent data to the +# relevant Elastic Cloud organization # - `cloudConnectedModeAPIURL`: the URL of the Cloud Connected Mode API (optional) # # configRef: From e8b10f6aa1418cbac897d44fada97401c57491fb Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 18:14:04 -0600 Subject: [PATCH 67/90] add config sample for autoops --- config/samples/autoops/autoops.yaml | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 config/samples/autoops/autoops.yaml diff --git a/config/samples/autoops/autoops.yaml b/config/samples/autoops/autoops.yaml new file mode 100644 index 00000000000..07de2b8097f --- /dev/null +++ b/config/samples/autoops/autoops.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: elasticsearch.k8s.elastic.co/v1 +kind: Elasticsearch +metadata: + name: elasticsearch-sample + labels: + autoops: enabled +spec: + version: 9.2.0 + nodeSets: + - name: default + count: 3 + config: + # most Elasticsearch configuration parameters are possible to set, e.g: node.attr.attr_name: attr_value + node.roles: ["master", "data", "ingest", "ml"] + # this allows ES to run on nodes even if their vm.max_map_count has not been increased, at a performance cost + node.store.allow_mmap: false +--- +apiVersion: autoops.k8s.elastic.co/v1alpha1 +kind: AutoOpsAgentPolicy +metadata: + name: autoops-sample +spec: + version: 9.2.0 + config: + # This secret contains the AutoOps configuration. + # It must contain the following: + # - ccmApiKey: the Cloud Connected Mode API key. This is used to register the Agent with Elastic Cloud AutoOps. + # - autoOpsOTelURL: the URL of the AutoOps OTel endpoint. This is used to send Agent data to the AutoOps platform and is region specific. + # - autoOpsToken: the token to authenticate against the AutoOps platform and is how AutoOps knows how to connect Agent data to the + # relevant Elastic Cloud organization + secretName: autoops-sample-secret + resourceSelector: + matchLabels: + # This label is used to select the Elasticsearch instance for AutoOps integration. + autoops: enabled From cbfdc0e5515bd7ab679aaa4a2e428511463cdd09 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 19:55:16 -0600 Subject: [PATCH 68/90] use extract nsn func --- pkg/controller/autoops/api_key.go | 6 +++--- pkg/controller/autoops/controller.go | 5 +---- pkg/controller/autoops/controller_test.go | 2 +- pkg/controller/autoops/expected.go | 4 ++-- pkg/controller/autoops/expected_test.go | 9 ++++----- pkg/controller/autoops/secret.go | 6 ++---- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 47b290333f3..34ac5ff438c 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -165,7 +165,7 @@ func maybeUpdateAPIKey( } // The API key is seemingly up to date, so we need to ensure the secret exists with correct value - secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)) var secret corev1.Secret nsn := types.NamespacedName{ Namespace: policy.Namespace, @@ -245,7 +245,7 @@ func storeAPIKeyInSecret( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { - secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} @@ -367,7 +367,7 @@ func cleanupAutoOpsESAPIKey( return deleteESAPIKeySecret(ctx, c, log, types.NamespacedName{Namespace: policyNamespace, Name: policyName}, - types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + k8s.ExtractNamespacedName(&es)) } func deleteESAPIKeySecret(ctx context.Context, c k8s.Client, log logr.Logger, policy types.NamespacedName, es types.NamespacedName) error { diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index e42a8cdfecd..6790f217c50 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -266,10 +266,7 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na // reconcileWatches sets up dynamic watches for secrets referenced in the AutoOpsAgentPolicy spec. func (r *ReconcileAutoOpsAgentPolicy) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { - watcher := types.NamespacedName{ - Name: policy.Name, - Namespace: policy.Namespace, - } + watcher := k8s.ExtractNamespacedName(&policy) secretNames := []string{policy.Spec.Config.SecretRef.SecretName} diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index 4a6849483b0..889cc886f1c 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -287,7 +287,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { for _, es := range tt.esClusters { if es.Status.Phase == esv1.ElasticsearchReadyPhase { - expectedSecretName := autoopsv1alpha1.APIKeySecret(tt.policy.Name, types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + expectedSecretName := autoopsv1alpha1.APIKeySecret(tt.policy.Name, k8s.ExtractNamespacedName(&es)) var retrievedSecret corev1.Secret err := k8sClient.Get(ctx, types.NamespacedName{Namespace: tt.policy.Namespace, Name: expectedSecretName}, &retrievedSecret) assert.True(t, apierrors.IsNotFound(err), "Expected secret %s/%s to be deleted", tt.policy.Namespace, expectedSecretName) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 89ece035169..e65df8304fc 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -190,7 +190,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A } // // Hash ES API key secret - esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}) + esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)) esAPIKeySecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: esAPIKeySecretName} var esAPIKeySecret corev1.Secret if err := c.Get(ctx, esAPIKeySecretKey, &esAPIKeySecret); err != nil { @@ -242,7 +242,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), + Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), }, Key: "api_key", Optional: ptr.To(false), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 6e8f2a478f2..d7798274e78 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -14,7 +14,6 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" @@ -118,7 +117,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { } // We need the ES API key secret as well to build the config hash - esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(tt.args.autoops.Name, types.NamespacedName{Namespace: tt.args.es.Namespace, Name: tt.args.es.Name}) + esAPIKeySecretName := autoopsv1alpha1.APIKeySecret(tt.args.autoops.Name, k8s.ExtractNamespacedName(&tt.args.es)) esAPIKeySecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: esAPIKeySecretName, @@ -274,9 +273,9 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast { Name: "AUTOOPS_ES_API_KEY", ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), types.NamespacedName{Namespace: es.Namespace, Name: es.Name}), + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), }, Key: "api_key", Optional: ptr.To(false), diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 488d642dfd7..ce4fd6430a0 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -20,6 +20,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" ) @@ -90,10 +91,7 @@ func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESCASecret( return err } - watcher := types.NamespacedName{ - Name: policy.Name, - Namespace: policy.Namespace, - } + watcher := k8s.ExtractNamespacedName(&policy) // Add a watch for the AutoOps CA secret return watches.WatchUserProvidedSecrets( From 9f0729f1d0d1e672e94889be68590aa2aaec1ec4 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:17:20 -0600 Subject: [PATCH 69/90] fix linter, unit tests --- pkg/controller/autoops/api_key.go | 2 -- pkg/controller/autoops/expected_test.go | 8 ++++---- pkg/controller/autoops/secret.go | 5 ----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 34ac5ff438c..250cb932936 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -30,8 +30,6 @@ import ( ) const ( - // autoOpsESAPIKeySecretNameSuffix is the suffix for API key secrets created for each ES instance - autoOpsESAPIKeySecretNameSuffix = "autoops-es-api-key" //nolint:gosec // managedByMetadataKey is the metadata key indicating the API key is managed by ECK. // This is used when storing the API key in Elasticsearch to clearly identify it as managed by ECK. // This is not included in the labels of the secret. diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index d7798274e78..d30590f2966 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -94,7 +94,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { configData := "test-config-data" configMap := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-%s-%s", autoOpsESConfigMapName, tt.args.es.Namespace, tt.args.es.Name), + Name: autoopsv1alpha1.Config(tt.args.autoops.Name, tt.args.es), Namespace: tt.args.autoops.Namespace, }, Data: map[string]string{ @@ -273,9 +273,9 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast { Name: "AUTOOPS_ES_API_KEY", ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), }, Key: "api_key", Optional: ptr.To(false), diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index ce4fd6430a0..7345d8b6a8d 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -25,11 +25,6 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" ) -const ( - // autoOpsESCASecretSuffix is the suffix for CA secrets created for each ES instance - autoOpsESCASecretSuffix = "autoops-es-ca" //nolint:gosec -) - // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate // for a specific Elasticsearch cluster, copying it from the ES instance's http-ca-internal secret. func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESCASecret( From 4e41ee8cca086b39eaa048de2f15a82551f440f6 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:22:50 -0600 Subject: [PATCH 70/90] try linter values file. Signed-off-by: Michael Montgomery --- deploy/eck-stack/charts/eck-autoops/values.yaml | 4 ++-- deploy/eck-stack/lint-values.yaml | 6 ++++++ hack/operatorhub/config.yaml | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 deploy/eck-stack/lint-values.yaml diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index 33067026433..996156f5d5a 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -41,8 +41,8 @@ annotations: {} # relevant Elastic Cloud organization # - `cloudConnectedModeAPIURL`: the URL of the Cloud Connected Mode API (optional) # -# configRef: -# secretName: "" +configRef: {} + # secretName: "" # Image is the AutoOps Agent Docker image to deploy. # image: "docker.elastic.co/elastic-agent/elastic-otel-collector-wolfi:9.3.0-SNAPSHOT" diff --git a/deploy/eck-stack/lint-values.yaml b/deploy/eck-stack/lint-values.yaml new file mode 100644 index 00000000000..45d35086416 --- /dev/null +++ b/deploy/eck-stack/lint-values.yaml @@ -0,0 +1,6 @@ +eck-autoops: + ccmApiKey: "required" + autoOpsOTelURL: "required" + autoOpsToken: "required" + configRef + secretName: "test-secret" diff --git a/hack/operatorhub/config.yaml b/hack/operatorhub/config.yaml index 7091242e82e..2e82bcaa669 100644 --- a/hack/operatorhub/config.yaml +++ b/hack/operatorhub/config.yaml @@ -1,5 +1,5 @@ -newVersion: 3.3.0-SNAPSHOT -prevVersion: 3.2.0 +newVersion: 3.3.0-rc6 +prevVersion: 3.3.0-rc5 stackVersion: 9.3.0-SNAPSHOT crds: - name: elasticsearches.elasticsearch.k8s.elastic.co From ece73b5cf3402eed8b06fd7458f6322c1861e52a Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:29:17 -0600 Subject: [PATCH 71/90] Fix lint values Signed-off-by: Michael Montgomery --- deploy/eck-stack/lint-values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/eck-stack/lint-values.yaml b/deploy/eck-stack/lint-values.yaml index 45d35086416..8c91cf57b99 100644 --- a/deploy/eck-stack/lint-values.yaml +++ b/deploy/eck-stack/lint-values.yaml @@ -2,5 +2,5 @@ eck-autoops: ccmApiKey: "required" autoOpsOTelURL: "required" autoOpsToken: "required" - configRef + configRef: secretName: "test-secret" From 5e51bbb79e4331767116b5e3ff00d6abd2e6c7b6 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:30:12 -0600 Subject: [PATCH 72/90] Revert config changes Signed-off-by: Michael Montgomery --- hack/operatorhub/config.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hack/operatorhub/config.yaml b/hack/operatorhub/config.yaml index 2e82bcaa669..26774786008 100644 --- a/hack/operatorhub/config.yaml +++ b/hack/operatorhub/config.yaml @@ -1,5 +1,5 @@ -newVersion: 3.3.0-rc6 -prevVersion: 3.3.0-rc5 +newVersion: 3.3.0-SNAPSHOT +prevVersion: 3.2.0 stackVersion: 9.3.0-SNAPSHOT crds: - name: elasticsearches.elasticsearch.k8s.elastic.co @@ -32,9 +32,6 @@ crds: - name: logstashes.logstash.k8s.elastic.co displayName: Logstash description: Logstash instance - - name: autoopsagentpolicies.autoops.k8s.elastic.co - displayName: AutoOps Agent Policy - description: AutoOps Agent Policy instance packages: - outputPath: community-operators packageName: elastic-cloud-eck From 067dab30699a5db5cee7baa04db1e2638e198e5a Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:30:56 -0600 Subject: [PATCH 73/90] Add back autoops policy Signed-off-by: Michael Montgomery --- hack/operatorhub/config.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hack/operatorhub/config.yaml b/hack/operatorhub/config.yaml index 26774786008..7091242e82e 100644 --- a/hack/operatorhub/config.yaml +++ b/hack/operatorhub/config.yaml @@ -32,6 +32,9 @@ crds: - name: logstashes.logstash.k8s.elastic.co displayName: Logstash description: Logstash instance + - name: autoopsagentpolicies.autoops.k8s.elastic.co + displayName: AutoOps Agent Policy + description: AutoOps Agent Policy instance packages: - outputPath: community-operators packageName: elastic-cloud-eck From 5738efe9f1e1c71378eee3506e75cc8896a33f7d Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:37:39 -0600 Subject: [PATCH 74/90] Remove unneeded file Signed-off-by: Michael Montgomery --- .../charts/eck-autoops/templates/secret.yaml | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 deploy/eck-stack/charts/eck-autoops/templates/secret.yaml diff --git a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml b/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml deleted file mode 100644 index 241fca4b3a4..00000000000 --- a/deploy/eck-stack/charts/eck-autoops/templates/secret.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -{{ if not .Values.configRef }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ printf "%s-config" (include "autoops.fullname" .) }} - labels: - {{- include "autoops.labels" . | nindent 4 }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: - {{- with .Values.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -type: Opaque -stringData: - cloud-connected-mode-api-key: {{ required "ccmApiKey is required" .Values.ccmApiKey }} - autoops-otel-url: {{ required "autoOpsOTelURL is required" .Values.autoOpsOTelURL }} - autoops-token: {{ required "autoOpsToken is required" .Values.autoOpsToken }} - {{ with .Values.cloudConnectedModeAPIURL }} - cloud-connected-mode-api-url: {{ . }} - {{ end }} -{{ end }} From ffa255a8f04a5862af8ae1370c7436ba8a66ae6d Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:41:01 -0600 Subject: [PATCH 75/90] remove unneeded helm values Signed-off-by: Michael Montgomery --- deploy/eck-stack/charts/eck-autoops/lint-values.yaml | 3 --- deploy/eck-stack/lint-values.yaml | 3 --- 2 files changed, 6 deletions(-) delete mode 100644 deploy/eck-stack/charts/eck-autoops/lint-values.yaml diff --git a/deploy/eck-stack/charts/eck-autoops/lint-values.yaml b/deploy/eck-stack/charts/eck-autoops/lint-values.yaml deleted file mode 100644 index 262a330a87c..00000000000 --- a/deploy/eck-stack/charts/eck-autoops/lint-values.yaml +++ /dev/null @@ -1,3 +0,0 @@ -ccmApiKey: required -autoOpsOTelURL: required -autoOpsToken: required diff --git a/deploy/eck-stack/lint-values.yaml b/deploy/eck-stack/lint-values.yaml index 8c91cf57b99..a8e6118bb24 100644 --- a/deploy/eck-stack/lint-values.yaml +++ b/deploy/eck-stack/lint-values.yaml @@ -1,6 +1,3 @@ eck-autoops: - ccmApiKey: "required" - autoOpsOTelURL: "required" - autoOpsToken: "required" configRef: secretName: "test-secret" From f7105773df7e251e3bf3741118f1b2c1a47b19fa Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:44:24 -0600 Subject: [PATCH 76/90] remove unused var Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configmap.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 89e255cb387..4a1016c4d15 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -25,8 +25,6 @@ import ( ) const ( - // autoOpsESConfigMapName is the static name for the autoops-es-config ConfigMap - autoOpsESConfigMapName = "autoops-es-config" // autoOpsESConfigFileName is the key name for the config file in the ConfigMap autoOpsESConfigFileName = "autoops_es.yml" ) From 4219c514d3d90099d9cabb6096e0fc8f9a0fe5d0 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:48:51 -0600 Subject: [PATCH 77/90] Fix comment Signed-off-by: Michael Montgomery --- pkg/controller/autoops/expected.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index e65df8304fc..23852ea4e98 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -64,7 +64,7 @@ func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, poli autoOpsLabelName: policy.Name, } - // Create ES-specific config map volume + // Create ES-specific ConfigMap volume configMapName := autoopsv1alpha1.Config(policy.GetName(), es) configVolume := volume.NewConfigMapVolume(configMapName, configVolumeName, configVolumePath) From 5b058aafba8b122797172890d81c07ab237955d7 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Wed, 10 Dec 2025 21:58:54 -0600 Subject: [PATCH 78/90] Fix linting issue Signed-off-by: Michael Montgomery --- pkg/apis/autoops/v1alpha1/name.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/apis/autoops/v1alpha1/name.go b/pkg/apis/autoops/v1alpha1/name.go index 5f529d7417c..5a910762684 100644 --- a/pkg/apis/autoops/v1alpha1/name.go +++ b/pkg/apis/autoops/v1alpha1/name.go @@ -5,10 +5,11 @@ package v1alpha1 import ( + "k8s.io/apimachinery/pkg/types" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/hash" common_name "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/name" - "k8s.io/apimachinery/pkg/types" ) var ( From 3bf46072e5922be1b6bac038df8d7bc1615c3825 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Thu, 11 Dec 2025 09:43:29 -0600 Subject: [PATCH 79/90] Temp disable enterprise check Signed-off-by: Michael Montgomery --- pkg/controller/autoops/reconcile.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 82c5cf94dd5..1f2111ed853 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -32,6 +32,8 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au if err != nil { return results.WithError(err) } + // temporary to see what happens in non-enterprise + enabled = true if !enabled { msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" log.Info(msg) @@ -58,7 +60,8 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, - state *State) *reconciler.Results { + state *State, +) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") From c28db0495f09eadf8cdda518389af10637bae31f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 09:20:30 -0600 Subject: [PATCH 80/90] Review changes. Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 99 +++++++++++----------- pkg/controller/autoops/api_key_test.go | 47 +++++----- pkg/controller/autoops/configuration.go | 1 + pkg/controller/autoops/controller.go | 6 +- pkg/controller/autoops/expected.go | 21 ++--- pkg/controller/autoops/reconcile.go | 2 +- pkg/controller/common/apikey/metadata.go | 36 ++++++++ pkg/controller/common/version/version.go | 2 +- pkg/controller/elasticsearch/user/roles.go | 16 ++++ 9 files changed, 145 insertions(+), 85 deletions(-) create mode 100644 pkg/controller/common/apikey/metadata.go diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index 250cb932936..f8f07d024ae 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -17,10 +17,12 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + commonapikey "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/apikey" commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/hash" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" esuser "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/user" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" @@ -30,14 +32,6 @@ import ( ) const ( - // managedByMetadataKey is the metadata key indicating the API key is managed by ECK. - // This is used when storing the API key in Elasticsearch to clearly identify it as managed by ECK. - // This is not included in the labels of the secret. - managedByMetadataKey = "elasticsearch.k8s.elastic.co/managed-by" - // managedByValue is the value for the managed-by metadata - managedByValue = "eck" - // configHashMetadataKey is the metadata key storing the hash API key - configHashMetadataKey = "elasticsearch.k8s.elastic.co/config-hash" // PolicyNameLabelKey is the label key for the AutoOpsAgentPolicy name. // This is exported as its used in the remotecluster controller to identify API keys managed by the autoops controller. PolicyNameLabelKey = "autoops.k8s.elastic.co/policy-name" @@ -51,11 +45,8 @@ type apiKeySpec struct { } // reconcileAutoOpsESAPIKey reconciles the API key and secret for a specific Elasticsearch cluster. -func reconcileAutoOpsESAPIKey( +func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESAPIKey( ctx context.Context, - c k8s.Client, - esClientProvider commonesclient.Provider, - dialer net.Dialer, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { @@ -65,20 +56,20 @@ func reconcileAutoOpsESAPIKey( ) log.V(1).Info("Reconciling AutoOps ES API key") - esClient, err := esClientProvider(ctx, c, dialer, es) + esClient, err := r.esClientProvider(ctx, r.Client, r.params.Dialer, es) if err != nil { return fmt.Errorf("while creating Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) } defer esClient.Close() - stackMonitoringUserRole, ok := esuser.PredefinedRoles[esuser.StackMonitoringUserRole].(esclient.Role) + autoOpsUserRole, ok := esuser.PredefinedRoles[esuser.AutoOpsUserRole].(esclient.Role) if !ok { - return fmt.Errorf("stackMonitoringUserRole could not be converted to esclient.Role") + return fmt.Errorf("autoOpsUserRole could not be converted to esclient.Role") } apiKeySpec := apiKeySpec{ roleDescriptors: map[string]esclient.Role{ - "eck_autoops_role": stackMonitoringUserRole, + "eck_autoops_role": autoOpsUserRole, }, } @@ -102,17 +93,16 @@ func reconcileAutoOpsESAPIKey( } if activeAPIKey == nil { - return createAPIKey(ctx, log, c, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.createAPIKey(ctx, log, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) } - return maybeUpdateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.maybeUpdateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } // createAPIKey creates a new API key in Elasticsearch and stores it in a secret. -func createAPIKey( +func (r *ReconcileAutoOpsAgentPolicy) createAPIKey( ctx context.Context, log logr.Logger, - c k8s.Client, esClient esclient.Client, apiKeyName string, apiKeySpec apiKeySpec, @@ -141,15 +131,13 @@ func createAPIKey( return fmt.Errorf("while creating API key %s: %w", apiKeyName, err) } - return storeAPIKeyInSecret(ctx, c, apiKeyResp.Encoded, expectedHash, policy, es) + return r.storeAPIKeyInSecret(ctx, policy, es, apiKeyResp.Encoded, expectedHash) } // maybeUpdateAPIKey checks if the API key needs to be updated and handles it. -func maybeUpdateAPIKey( +func (r *ReconcileAutoOpsAgentPolicy) maybeUpdateAPIKey( ctx context.Context, log logr.Logger, - c k8s.Client, - esClient esclient.Client, activeAPIKey *esclient.APIKey, apiKeyName string, apiKeySpec apiKeySpec, @@ -159,7 +147,7 @@ func maybeUpdateAPIKey( ) error { // If the key isn't managed by ECK or it's hash is incorrect, invalidate and recreate the api key. if apiKeyNeedsRecreation(activeAPIKey, expectedHash) { - return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.invalidateAndCreateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } // The API key is seemingly up to date, so we need to ensure the secret exists with correct value @@ -169,11 +157,11 @@ func maybeUpdateAPIKey( Namespace: policy.Namespace, Name: secretName, } - if err := c.Get(ctx, nsn, &secret); err != nil { + if err := r.Client.Get(ctx, nsn, &secret); err != nil { if apierrors.IsNotFound(err) { // Secret doesn't exist so again we need to invalidate and recreate the API key. log.Info("API key secret not found, recreating key", "key", apiKeyName) - return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.invalidateAndCreateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } return fmt.Errorf("while retrieving API key secret %s: %w", secretName, err) } @@ -181,18 +169,16 @@ func maybeUpdateAPIKey( // Since the secret exists, we just need to verify the data is correct. if encodedKey, ok := secret.Data["api_key"]; !ok || string(encodedKey) == "" { log.Info("API key secret exists but is missing api_key, recreating key", "key", apiKeyName) - return invalidateAndCreateAPIKey(ctx, log, c, esClient, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.invalidateAndCreateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } log.V(1).Info("API key is up to date", "key", apiKeyName) return nil } -func invalidateAndCreateAPIKey( +func (r *ReconcileAutoOpsAgentPolicy) invalidateAndCreateAPIKey( ctx context.Context, log logr.Logger, - c k8s.Client, - esClient esclient.Client, activeAPIKey *esclient.APIKey, apiKeyName string, apiKeySpec apiKeySpec, @@ -200,10 +186,15 @@ func invalidateAndCreateAPIKey( policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, ) error { + esClient, err := r.esClientProvider(ctx, r.Client, r.params.Dialer, es) + if err != nil { + return fmt.Errorf("while creating Elasticsearch client for %s/%s: %w", es.Namespace, es.Name, err) + } + defer esClient.Close() if err := invalidateAPIKey(ctx, esClient, activeAPIKey.ID); err != nil { return err } - return createAPIKey(ctx, log, c, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) + return r.createAPIKey(ctx, log, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) } // apiKeyNeedsRecreation checks if the API key needs to be recreated. @@ -215,11 +206,11 @@ func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { if apiKey.Metadata == nil { return true } - managedBy, ok := apiKey.Metadata[managedByMetadataKey].(string) - if !ok || managedBy != managedByValue { + managedBy, ok := apiKey.Metadata[commonapikey.MetadataKeyManagedBy].(string) + if !ok || managedBy != commonapikey.MetadataValueECK { return true } - currentHash, ok := apiKey.Metadata[configHashMetadataKey].(string) + currentHash, ok := apiKey.Metadata[commonapikey.MetadataKeyConfigHash].(string) if !ok || currentHash != expectedHash { return true } @@ -235,22 +226,21 @@ func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID strin } // storeAPIKeyInSecret stores the API key in a Kubernetes secret. -func storeAPIKeyInSecret( +func (r *ReconcileAutoOpsAgentPolicy) storeAPIKeyInSecret( ctx context.Context, - c k8s.Client, - encodedKey string, - expectedHash string, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, + encodedKey string, + expectedHash string, ) error { secretName := autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)) expected := buildAutoOpsESAPIKeySecret(policy, es, secretName, encodedKey, expectedHash) reconciled := &corev1.Secret{} - return reconciler.ReconcileResource( + err := reconciler.ReconcileResource( reconciler.Params{ Context: ctx, - Client: c, + Client: r.Client, Owner: &policy, Expected: &expected, Reconciled: reconciled, @@ -266,6 +256,19 @@ func storeAPIKeyInSecret( }, }, ) + if err != nil { + return err + } + + watcher := k8s.ExtractNamespacedName(&policy) + + // Add a watch for the AutoOps API key secret + return watches.WatchUserProvidedSecrets( + watcher, + r.dynamicWatches, + secretName, + []string{secretName}, + ) } // buildAutoOpsESAPIKeySecret builds the expected Secret for autoops ES API key. @@ -277,7 +280,7 @@ func buildAutoOpsESAPIKeySecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es es // The 'managed-by' is only needed/wanted for the API key in // Elasticsearch so we remove it from the secret. - delete(meta.Labels, managedByMetadataKey) + delete(meta.Labels, commonapikey.MetadataKeyManagedBy) return corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -309,12 +312,12 @@ func apiKeyNameFor(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsea // newMetadataFor returns the metadata to be set in the Elasticsearch API key. func newMetadataFor(policy *autoopsv1alpha1.AutoOpsAgentPolicy, es *esv1.Elasticsearch, expectedHash string) map[string]string { return map[string]string{ - configHashMetadataKey: expectedHash, - "elasticsearch.k8s.elastic.co/name": es.Name, - "elasticsearch.k8s.elastic.co/namespace": es.Namespace, - managedByMetadataKey: managedByValue, - PolicyNameLabelKey: policy.Name, - policyNamespaceLabelKey: policy.Namespace, + commonapikey.MetadataKeyConfigHash: expectedHash, + commonapikey.MetadataKeyESName: es.Name, + commonapikey.MetadataKeyESNamespace: es.Namespace, + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + PolicyNameLabelKey: policy.Name, + policyNamespaceLabelKey: policy.Namespace, } } diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go index e1f0924b45b..38d983cb728 100644 --- a/pkg/controller/autoops/api_key_test.go +++ b/pkg/controller/autoops/api_key_test.go @@ -13,6 +13,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + commonapikey "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/apikey" esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" ) @@ -41,7 +42,7 @@ func Test_apiKeyNeedsRecreation(t *testing.T) { name: "wrong managed-by value requires recreation", apiKey: &esclient.APIKey{ Metadata: map[string]any{ - managedByMetadataKey: "wrong-value", + commonapikey.MetadataKeyManagedBy: "wrong-value", }, }, expectedHash: "hash123", @@ -51,7 +52,7 @@ func Test_apiKeyNeedsRecreation(t *testing.T) { name: "missing config hash requires recreation", apiKey: &esclient.APIKey{ Metadata: map[string]any{ - managedByMetadataKey: managedByValue, + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, }, }, expectedHash: "hash123", @@ -61,8 +62,8 @@ func Test_apiKeyNeedsRecreation(t *testing.T) { name: "wrong config hash requires recreation", apiKey: &esclient.APIKey{ Metadata: map[string]any{ - managedByMetadataKey: managedByValue, - configHashMetadataKey: "wrong-hash", + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + commonapikey.MetadataKeyConfigHash: "wrong-hash", }, }, expectedHash: "hash123", @@ -72,8 +73,8 @@ func Test_apiKeyNeedsRecreation(t *testing.T) { name: "correct metadata does not require recreation", apiKey: &esclient.APIKey{ Metadata: map[string]any{ - managedByMetadataKey: managedByValue, - configHashMetadataKey: "hash123", + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + commonapikey.MetadataKeyConfigHash: "hash123", }, }, expectedHash: "hash123", @@ -113,12 +114,12 @@ func Test_newMetadataFor(t *testing.T) { }, expectedHash: "hash123", want: map[string]string{ - configHashMetadataKey: "hash123", - "elasticsearch.k8s.elastic.co/name": "es-1", - "elasticsearch.k8s.elastic.co/namespace": "ns-2", - managedByMetadataKey: managedByValue, - PolicyNameLabelKey: "policy-1", - policyNamespaceLabelKey: "ns-1", + commonapikey.MetadataKeyConfigHash: "hash123", + commonapikey.MetadataKeyESName: "es-1", + commonapikey.MetadataKeyESNamespace: "ns-2", + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + PolicyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", }, }, } @@ -170,11 +171,12 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { Name: "secret-1", Namespace: "ns-1", Labels: map[string]string{ - configHashMetadataKey: "hash123", - "elasticsearch.k8s.elastic.co/name": "es-1", - "elasticsearch.k8s.elastic.co/namespace": "ns-2", - "autoops.k8s.elastic.co/policy-name": "policy-1", - "autoops.k8s.elastic.co/policy-namespace": "ns-1", + commonapikey.MetadataKeyConfigHash: "hash123", + commonapikey.MetadataKeyESName: "es-1", + commonapikey.MetadataKeyESNamespace: "ns-2", + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + PolicyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", }, Annotations: map[string]string{ "annotation1": "value1", @@ -207,11 +209,12 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { Name: "secret-1", Namespace: "ns-1", Labels: map[string]string{ - configHashMetadataKey: "hash123", - "elasticsearch.k8s.elastic.co/name": "es-1", - "elasticsearch.k8s.elastic.co/namespace": "ns-2", - "autoops.k8s.elastic.co/policy-name": "policy-1", - "autoops.k8s.elastic.co/policy-namespace": "ns-1", + commonapikey.MetadataKeyConfigHash: "hash123", + commonapikey.MetadataKeyESName: "es-1", + commonapikey.MetadataKeyESNamespace: "ns-2", + commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, + PolicyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", }, }, Data: map[string][]byte{ diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 35656fb8b9f..365ba2a9efa 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -27,6 +27,7 @@ const ( ccmAPIKey = "cloud-connected-mode-api-key" autoOpsOTelURL = "autoops-otel-url" autoOpsToken = "autoops-token" + ccmAPIURL = "cloud-connected-mode-api-url" ) // ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 6790f217c50..ad9c14bbf55 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -172,20 +172,20 @@ func updatePhaseFromResults(results *reconciler.Results, state *State) { } func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { - span, apmctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) + span, ctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() if _, err := policy.ValidateCreate(); err != nil { ulog.FromContext(ctx).Error(err, "Validation failed") k8s.MaybeEmitErrorEvent(r.recorder, err, policy, events.EventReasonValidation, err.Error()) - return tracing.CaptureError(apmctx, err) + return tracing.CaptureError(ctx, err) } return nil } func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { - span, _ := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) + span, ctx := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() events, policy := state.Apply() diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 23852ea4e98..66d531c0443 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -173,17 +173,18 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A } // Hash secret values from autoops-secret - autoopsSecretKey := types.NamespacedName{Namespace: policy.Namespace, Name: "autoops-secret"} + autoopsSecretNSN := types.NamespacedName{Namespace: policy.GetNamespace(), Name: policy.Spec.Config.SecretRef.SecretName} var autoopsSecret corev1.Secret - if err := c.Get(ctx, autoopsSecretKey, &autoopsSecret); err != nil { - return "", fmt.Errorf("failed to get autoops-secret: %w", err) + if err := c.Get(ctx, autoopsSecretNSN, &autoopsSecret); err != nil { + return "", fmt.Errorf("failed to get autoops configuration secret %s: %w", autoopsSecretNSN.String(), err) } - // Hash secret keys, including optional keys. There's no code here to handle missing keys as + // Hash secret keys, including optional keys. There's no code here to handle missing keys as: // 1. The optional keys are included here. + // 1a. cloud-connected-mode-api-url is optional, and is only required if connecting to an environment such as non-production or air-gapped. // 2. The required keys are already validated in the controller, so they should always be present. - requiredKeys := []string{"autoops-token", "autoops-otel-url", "cloud-connected-mode-api-key", "cloud-connected-mode-api-url"} - for _, key := range requiredKeys { + keys := []string{autoOpsToken, autoOpsOTelURL, ccmAPIKey, ccmAPIURL} + for _, key := range keys { if data, ok := autoopsSecret.Data[key]; ok { _, _ = configHash.Write(data) } @@ -216,7 +217,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: policy.Spec.Config.SecretRef.SecretName, }, Key: "autoops-token", }, @@ -231,7 +232,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: policy.Spec.Config.SecretRef.SecretName, }, Key: "autoops-otel-url", }, @@ -254,7 +255,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: policy.Spec.Config.SecretRef.SecretName, }, Key: "cloud-connected-mode-api-key", }, @@ -265,7 +266,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "autoops-secret", + Name: policy.Spec.Config.SecretRef.SecretName, }, Key: "cloud-connected-mode-api-url", Optional: ptr.To(true), diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 1f2111ed853..9d6f3961891 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -119,7 +119,7 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( } } - if err := reconcileAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, policy, es); err != nil { + if err := r.reconcileAutoOpsESAPIKey(ctx, policy, es); err != nil { log.Error(err, "Error reconciling AutoOps ES API key", "namespace", es.Namespace, "name", es.Name) errorCount++ state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) diff --git a/pkg/controller/common/apikey/metadata.go b/pkg/controller/common/apikey/metadata.go new file mode 100644 index 00000000000..a488df05641 --- /dev/null +++ b/pkg/controller/common/apikey/metadata.go @@ -0,0 +1,36 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package apikey + +const ( + // MetadataKeyManagedBy identifies API keys managed by ECK + MetadataKeyManagedBy = "elasticsearch.k8s.elastic.co/managed-by" + // MetadataValueECK is the value indicating ECK management + MetadataValueECK = "eck" + // MetadataKeyConfigHash stores the config hash for change detection + MetadataKeyConfigHash = "elasticsearch.k8s.elastic.co/config-hash" + // MetadataKeyESName stores the Elasticsearch cluster name + MetadataKeyESName = "elasticsearch.k8s.elastic.co/name" + // MetadataKeyESNamespace stores the Elasticsearch cluster namespace + MetadataKeyESNamespace = "elasticsearch.k8s.elastic.co/namespace" +) + +// IsManagedByECK checks if an API key's metadata indicates ECK management +func IsManagedByECK(metadata map[string]any) bool { + if metadata == nil { + return false + } + managedBy, ok := metadata[MetadataKeyManagedBy].(string) + return ok && managedBy == MetadataValueECK +} + +// NeedsUpdate checks if the API key needs updating based on config hash +func NeedsUpdate(metadata map[string]any, expectedHash string) bool { + if metadata == nil { + return true + } + currentHash, ok := metadata[MetadataKeyConfigHash].(string) + return !ok || currentHash != expectedHash +} diff --git a/pkg/controller/common/version/version.go b/pkg/controller/common/version/version.go index e2f2efb7782..aa3492369b9 100644 --- a/pkg/controller/common/version/version.go +++ b/pkg/controller/common/version/version.go @@ -39,7 +39,7 @@ var ( SupportedLogstashVersions = MinMaxVersion{Min: From(8, 12, 0), Max: From(9, 99, 99)} // AutoOpsAgent was introduced in 9.1.0 and is supported on all 9.x versions. - SupportedAutoOpsAgentVersions = MinMaxVersion{Min: MustParse("9.1.0-SNAPSHOT"), Max: From(9, 99, 99)} + SupportedAutoOpsAgentVersions = MinMaxVersion{Min: MustParse("9.1.0"), Max: From(9, 99, 99)} // minPreReleaseVersion is the lowest prerelease identifier as numeric prerelease takes precedence before // alphanumeric ones and it can't have leading zeros. diff --git a/pkg/controller/elasticsearch/user/roles.go b/pkg/controller/elasticsearch/user/roles.go index 4a1c84e53af..d4ae221df2b 100644 --- a/pkg/controller/elasticsearch/user/roles.go +++ b/pkg/controller/elasticsearch/user/roles.go @@ -46,6 +46,9 @@ const ( // ApmAgentUserRole is the name of the role used by APMServer instances to connect to Kibana ApmAgentUserRole = "eck_apm_agent_user_role" + // AutoOpsUserRole is the name of the role used by the AutoOps agent to connect to Elasticsearch + AutoOpsUserRole = "eck_autoops_user_role" + // StackMonitoringMetricsUserRole is the name of the role used by Metricbeat and Filebeat to send metrics and log // data to the monitoring Elasticsearch cluster when Stack Monitoring is enabled StackMonitoringUserRole = "eck_stack_mon_user_role" @@ -191,6 +194,19 @@ var ( }, }, }, + AutoOpsUserRole: esclient.Role{ + Cluster: []string{"monitor", "read_ilm", "read_slm"}, + Indices: []esclient.IndexRole{ + { + Names: []string{"*"}, + Privileges: []string{"monitor", "view_index_metadata"}, + AllowRestrictedIndices: func() *bool { + allow := true + return &allow + }(), + }, + }, + }, // StackMonitoringUserRole is a dedicated role for Stack Monitoring with Metricbeat and Filebeat used for the // user sending monitoring data. // See: https://www.elastic.co/guide/en/beats/filebeat/7.14/privileges-to-publish-monitoring.html. From f62cee3562250c6943145e7ffb117ed841308d43 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 09:33:25 -0600 Subject: [PATCH 81/90] Use the common funcs in common/apikey Move unit tests Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 22 +-- pkg/controller/autoops/api_key_test.go | 74 ---------- pkg/controller/common/apikey/metadata_test.go | 128 ++++++++++++++++++ 3 files changed, 129 insertions(+), 95 deletions(-) create mode 100644 pkg/controller/common/apikey/metadata_test.go diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index f8f07d024ae..f112e2f34a2 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -146,7 +146,7 @@ func (r *ReconcileAutoOpsAgentPolicy) maybeUpdateAPIKey( es esv1.Elasticsearch, ) error { // If the key isn't managed by ECK or it's hash is incorrect, invalidate and recreate the api key. - if apiKeyNeedsRecreation(activeAPIKey, expectedHash) { + if !commonapikey.IsManagedByECK(activeAPIKey.Metadata) || commonapikey.NeedsUpdate(activeAPIKey.Metadata, expectedHash) { return r.invalidateAndCreateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } @@ -197,26 +197,6 @@ func (r *ReconcileAutoOpsAgentPolicy) invalidateAndCreateAPIKey( return r.createAPIKey(ctx, log, esClient, apiKeyName, apiKeySpec, expectedHash, policy, es) } -// apiKeyNeedsRecreation checks if the API key needs to be recreated. -// It will be recreated in the following cases: -// - The API key has no metadata -// - The API key has the wrong "managed-by" value -// - The API key has the wrong "config-hash" value -func apiKeyNeedsRecreation(apiKey *esclient.APIKey, expectedHash string) bool { - if apiKey.Metadata == nil { - return true - } - managedBy, ok := apiKey.Metadata[commonapikey.MetadataKeyManagedBy].(string) - if !ok || managedBy != commonapikey.MetadataValueECK { - return true - } - currentHash, ok := apiKey.Metadata[commonapikey.MetadataKeyConfigHash].(string) - if !ok || currentHash != expectedHash { - return true - } - return false -} - // invalidateAPIKey invalidates an API key by its key ID by calling the Elasticsearch API. func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID string) error { _, err := esClient.InvalidateAPIKeys(ctx, esclient.APIKeysInvalidateRequest{ diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go index 38d983cb728..0faf9c6c604 100644 --- a/pkg/controller/autoops/api_key_test.go +++ b/pkg/controller/autoops/api_key_test.go @@ -14,82 +14,8 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" commonapikey "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/apikey" - esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" ) -func Test_apiKeyNeedsRecreation(t *testing.T) { - tests := []struct { - name string - apiKey *esclient.APIKey - expectedHash string - want bool - }{ - { - name: "nil metadata requires recreation", - apiKey: &esclient.APIKey{Metadata: nil}, - expectedHash: "hash123", - want: true, - }, - { - name: "missing managed-by metadata requires recreation", - apiKey: &esclient.APIKey{ - Metadata: map[string]any{}, - }, - expectedHash: "hash123", - want: true, - }, - { - name: "wrong managed-by value requires recreation", - apiKey: &esclient.APIKey{ - Metadata: map[string]any{ - commonapikey.MetadataKeyManagedBy: "wrong-value", - }, - }, - expectedHash: "hash123", - want: true, - }, - { - name: "missing config hash requires recreation", - apiKey: &esclient.APIKey{ - Metadata: map[string]any{ - commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, - }, - }, - expectedHash: "hash123", - want: true, - }, - { - name: "wrong config hash requires recreation", - apiKey: &esclient.APIKey{ - Metadata: map[string]any{ - commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, - commonapikey.MetadataKeyConfigHash: "wrong-hash", - }, - }, - expectedHash: "hash123", - want: true, - }, - { - name: "correct metadata does not require recreation", - apiKey: &esclient.APIKey{ - Metadata: map[string]any{ - commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, - commonapikey.MetadataKeyConfigHash: "hash123", - }, - }, - expectedHash: "hash123", - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := apiKeyNeedsRecreation(tt.apiKey, tt.expectedHash); got != tt.want { - t.Errorf("apiKeyNeedsRecreation() = %v, want %v", got, tt.want) - } - }) - } -} - func Test_newMetadataFor(t *testing.T) { tests := []struct { name string diff --git a/pkg/controller/common/apikey/metadata_test.go b/pkg/controller/common/apikey/metadata_test.go new file mode 100644 index 00000000000..66f232fa632 --- /dev/null +++ b/pkg/controller/common/apikey/metadata_test.go @@ -0,0 +1,128 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package apikey + +import ( + "testing" +) + +func Test_IsManagedByECK(t *testing.T) { + tests := []struct { + name string + metadata map[string]any + want bool + }{ + { + name: "nil metadata returns false", + metadata: nil, + want: false, + }, + { + name: "missing managed-by metadata returns false", + metadata: map[string]any{}, + want: false, + }, + { + name: "wrong managed-by value returns false", + metadata: map[string]any{ + MetadataKeyManagedBy: "wrong-value", + }, + want: false, + }, + { + name: "correct managed-by value returns true", + metadata: map[string]any{ + MetadataKeyManagedBy: MetadataValueECK, + }, + want: true, + }, + { + name: "correct managed-by value with other metadata returns true", + metadata: map[string]any{ + MetadataKeyManagedBy: MetadataValueECK, + MetadataKeyConfigHash: "hash123", + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsManagedByECK(tt.metadata); got != tt.want { + t.Errorf("IsManagedByECK() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_NeedsUpdate(t *testing.T) { + tests := []struct { + name string + metadata map[string]any + expectedHash string + want bool + }{ + { + name: "nil metadata requires update", + metadata: nil, + expectedHash: "hash123", + want: true, + }, + { + name: "missing config hash requires update", + metadata: map[string]any{}, + expectedHash: "hash123", + want: true, + }, + { + name: "missing config hash with managed-by requires update", + metadata: map[string]any{ + MetadataKeyManagedBy: MetadataValueECK, + }, + expectedHash: "hash123", + want: true, + }, + { + name: "wrong config hash requires update", + metadata: map[string]any{ + MetadataKeyConfigHash: "wrong-hash", + }, + expectedHash: "hash123", + want: true, + }, + { + name: "wrong config hash with managed-by requires update", + metadata: map[string]any{ + MetadataKeyManagedBy: MetadataValueECK, + MetadataKeyConfigHash: "wrong-hash", + }, + expectedHash: "hash123", + want: true, + }, + { + name: "correct config hash does not require update", + metadata: map[string]any{ + MetadataKeyConfigHash: "hash123", + }, + expectedHash: "hash123", + want: false, + }, + { + name: "correct config hash with managed-by does not require update", + metadata: map[string]any{ + MetadataKeyManagedBy: MetadataValueECK, + MetadataKeyConfigHash: "hash123", + }, + expectedHash: "hash123", + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NeedsUpdate(tt.metadata, tt.expectedHash); got != tt.want { + t.Errorf("NeedsUpdate() = %v, want %v", got, tt.want) + } + }) + } +} From 4384554face35dc89e20e132a52cff73e4f5a862 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 09:41:23 -0600 Subject: [PATCH 82/90] Move parseSecret -> validateSecret Signed-off-by: Michael Montgomery --- pkg/controller/autoops/configuration.go | 41 +++++------- pkg/controller/autoops/configuration_test.go | 66 ++++---------------- pkg/controller/autoops/reconcile.go | 6 +- 3 files changed, 31 insertions(+), 82 deletions(-) diff --git a/pkg/controller/autoops/configuration.go b/pkg/controller/autoops/configuration.go index 365ba2a9efa..dcd74a0f54a 100644 --- a/pkg/controller/autoops/configuration.go +++ b/pkg/controller/autoops/configuration.go @@ -30,44 +30,35 @@ const ( ccmAPIURL = "cloud-connected-mode-api-url" ) -// ParseConfigSecret retrieves and parses the configuration secret referenced in the AutoOpsAgentPolicy. -// It returns a Config struct containing the parsed configuration values and any error encountered. -func ParseConfigSecret(ctx context.Context, client k8s.Client, secretKey types.NamespacedName) (*Config, error) { - if secretKey.Name == "" { - return nil, fmt.Errorf("secret name cannot be empty") +// validateConfigSecret validates the configuration secret referenced in the AutoOpsAgentPolicy. +func validateConfigSecret(ctx context.Context, client k8s.Client, secretNSN types.NamespacedName) error { + if secretNSN.Name == "" { + return fmt.Errorf("secret name cannot be empty") } var secret corev1.Secret - if err := client.Get(ctx, secretKey, &secret); err != nil { + if err := client.Get(ctx, secretNSN, &secret); err != nil { if apierrors.IsNotFound(err) { - return nil, fmt.Errorf("configuration secret %s/%s not found: %w", secretKey.Namespace, secretKey.Name, err) + return fmt.Errorf("configuration secret %s/%s not found: %w", secretNSN.Namespace, secretNSN.Name, err) } - return nil, fmt.Errorf("failed to retrieve configuration secret %s/%s: %w", secretKey.Namespace, secretKey.Name, err) + return fmt.Errorf("failed to retrieve configuration secret %s/%s: %w", secretNSN.Namespace, secretNSN.Name, err) } - return validateAndPopulateConfig(secret, secretKey) + return internalValidate(secret) } -func validateAndPopulateConfig(secret corev1.Secret, secretKey types.NamespacedName) (*Config, error) { - var config Config - - if data, exists := secret.Data[ccmAPIKey]; exists && len(data) > 0 { - config.CCMApiKey = string(data) - } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", ccmAPIKey, secretKey.Namespace, secretKey.Name) +func internalValidate(secret corev1.Secret) error { + if data, exists := secret.Data[ccmAPIKey]; !exists || exists && len(data) == 0 { + return fmt.Errorf("missing required key %s in configuration secret %s/%s", ccmAPIKey, secret.Namespace, secret.Name) } - if data, exists := secret.Data[autoOpsOTelURL]; exists && len(data) > 0 { - config.AutoOpsOTelURL = string(data) - } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsOTelURL, secretKey.Namespace, secretKey.Name) + if data, exists := secret.Data[autoOpsOTelURL]; !exists || exists && len(data) == 0 { + return fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsOTelURL, secret.Namespace, secret.Name) } - if data, exists := secret.Data[autoOpsToken]; exists && len(data) > 0 { - config.AutoOpsToken = string(data) - } else { - return nil, fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsToken, secretKey.Namespace, secretKey.Name) + if data, exists := secret.Data[autoOpsToken]; !exists || exists && len(data) == 0 { + return fmt.Errorf("missing required key %s in configuration secret %s/%s", autoOpsToken, secret.Namespace, secret.Name) } - return &config, nil + return nil } diff --git a/pkg/controller/autoops/configuration_test.go b/pkg/controller/autoops/configuration_test.go index 8d7aade9d9a..cab463db9b4 100644 --- a/pkg/controller/autoops/configuration_test.go +++ b/pkg/controller/autoops/configuration_test.go @@ -9,16 +9,13 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" ) -func Test_validateAndPopulateConfig(t *testing.T) { +func Test_internalValidate(t *testing.T) { tests := []struct { - name string - secret corev1.Secret - secretKey types.NamespacedName - want *Config - wantErr bool + name string + secret corev1.Secret + wantErr bool }{ { name: "valid config with all required fields", @@ -33,12 +30,6 @@ func Test_validateAndPopulateConfig(t *testing.T) { autoOpsToken: []byte("token-value"), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: &Config{ - CCMApiKey: "ccm-api-key-value", - AutoOpsOTelURL: "https://otel.example.com", - AutoOpsToken: "token-value", - }, wantErr: false, }, { @@ -53,9 +44,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { autoOpsToken: []byte("token-value"), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "missing autoOpsOTelURL returns an error", @@ -69,9 +58,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { autoOpsToken: []byte("token-value"), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "missing autoOpsToken returns an error", @@ -85,9 +72,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { autoOpsOTelURL: []byte("https://otel.example.com"), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "empty values are not allowed", @@ -102,9 +87,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { autoOpsToken: []byte(""), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "empty secret data returns an error", @@ -115,9 +98,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { }, Data: map[string][]byte{}, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "nil secret data returns an error", @@ -128,9 +109,7 @@ func Test_validateAndPopulateConfig(t *testing.T) { }, Data: nil, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: nil, - wantErr: true, + wantErr: true, }, { name: "extra fields are ignored", @@ -146,37 +125,16 @@ func Test_validateAndPopulateConfig(t *testing.T) { "extra-field": []byte("extra-value"), }, }, - secretKey: types.NamespacedName{Name: "config-secret", Namespace: "default"}, - want: &Config{ - CCMApiKey: "ccm-api-key-value", - AutoOpsOTelURL: "https://otel.example.com", - AutoOpsToken: "token-value", - }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := validateAndPopulateConfig(tt.secret, tt.secretKey) + err := internalValidate(tt.secret) if (err != nil) != tt.wantErr { - t.Errorf("validateAndPopulateConfig() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("internalValidate() error = %v, wantErr %v", err, tt.wantErr) return } - if !tt.wantErr { - if got == nil { - t.Errorf("validateAndPopulateConfig() got = nil, want %v", tt.want) - return - } - if got.CCMApiKey != tt.want.CCMApiKey { - t.Errorf("validateAndPopulateConfig() ccmApiKey = %v, want %v", got.CCMApiKey, tt.want.CCMApiKey) - } - if got.AutoOpsOTelURL != tt.want.AutoOpsOTelURL { - t.Errorf("validateAndPopulateConfig() autoOpsOTelURL = %v, want %v", got.AutoOpsOTelURL, tt.want.AutoOpsOTelURL) - } - if got.AutoOpsToken != tt.want.AutoOpsToken { - t.Errorf("validateAndPopulateConfig() autoOpsToken = %v, want %v", got.AutoOpsToken, tt.want.AutoOpsToken) - } - } }) } } diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 9d6f3961891..bfefcf6ee37 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -65,11 +65,11 @@ func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( log := ulog.FromContext(ctx) log.V(1).Info("Internal reconcile AutoOpsAgentPolicy") - _, err := ParseConfigSecret(ctx, r.Client, types.NamespacedName{ + if err := validateConfigSecret(ctx, r.Client, types.NamespacedName{ Namespace: policy.Namespace, Name: policy.Spec.Config.SecretRef.SecretName, - }) - if err != nil { + }); err != nil { + log.Error(err, "Error validating configuration secret", "namespace", policy.Namespace, "name", policy.Spec.Config.SecretRef.SecretName) state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } From 3a3c083418477679a816652aef71ad2799cbcab4 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 09:47:36 -0600 Subject: [PATCH 83/90] rename reconciler. use apikey constant Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 15 ++++++++------- pkg/controller/autoops/api_key_test.go | 4 ++-- pkg/controller/autoops/controller.go | 22 +++++++++++----------- pkg/controller/autoops/controller_test.go | 8 ++++---- pkg/controller/autoops/expected.go | 6 +++--- pkg/controller/autoops/expected_test.go | 8 ++++---- pkg/controller/autoops/reconcile.go | 4 ++-- pkg/controller/autoops/secret.go | 2 +- 8 files changed, 35 insertions(+), 34 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index f112e2f34a2..fe3c4187e53 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -37,6 +37,7 @@ const ( PolicyNameLabelKey = "autoops.k8s.elastic.co/policy-name" // policyNamespaceLabelKey is the label key for the AutoOpsAgentPolicy namespace policyNamespaceLabelKey = "autoops.k8s.elastic.co/policy-namespace" + apiKeySecretKey = "api_key" ) // apiKeySpec represents the specification for an autoops API key @@ -45,7 +46,7 @@ type apiKeySpec struct { } // reconcileAutoOpsESAPIKey reconciles the API key and secret for a specific Elasticsearch cluster. -func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESAPIKey( +func (r *AutoOpsAgentPolicyReconciler) reconcileAutoOpsESAPIKey( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -100,7 +101,7 @@ func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESAPIKey( } // createAPIKey creates a new API key in Elasticsearch and stores it in a secret. -func (r *ReconcileAutoOpsAgentPolicy) createAPIKey( +func (r *AutoOpsAgentPolicyReconciler) createAPIKey( ctx context.Context, log logr.Logger, esClient esclient.Client, @@ -135,7 +136,7 @@ func (r *ReconcileAutoOpsAgentPolicy) createAPIKey( } // maybeUpdateAPIKey checks if the API key needs to be updated and handles it. -func (r *ReconcileAutoOpsAgentPolicy) maybeUpdateAPIKey( +func (r *AutoOpsAgentPolicyReconciler) maybeUpdateAPIKey( ctx context.Context, log logr.Logger, activeAPIKey *esclient.APIKey, @@ -167,7 +168,7 @@ func (r *ReconcileAutoOpsAgentPolicy) maybeUpdateAPIKey( } // Since the secret exists, we just need to verify the data is correct. - if encodedKey, ok := secret.Data["api_key"]; !ok || string(encodedKey) == "" { + if encodedKey, ok := secret.Data[apiKeySecretKey]; !ok || string(encodedKey) == "" { log.Info("API key secret exists but is missing api_key, recreating key", "key", apiKeyName) return r.invalidateAndCreateAPIKey(ctx, log, activeAPIKey, apiKeyName, apiKeySpec, expectedHash, policy, es) } @@ -176,7 +177,7 @@ func (r *ReconcileAutoOpsAgentPolicy) maybeUpdateAPIKey( return nil } -func (r *ReconcileAutoOpsAgentPolicy) invalidateAndCreateAPIKey( +func (r *AutoOpsAgentPolicyReconciler) invalidateAndCreateAPIKey( ctx context.Context, log logr.Logger, activeAPIKey *esclient.APIKey, @@ -206,7 +207,7 @@ func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID strin } // storeAPIKeyInSecret stores the API key in a Kubernetes secret. -func (r *ReconcileAutoOpsAgentPolicy) storeAPIKeyInSecret( +func (r *AutoOpsAgentPolicyReconciler) storeAPIKeyInSecret( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -270,7 +271,7 @@ func buildAutoOpsESAPIKeySecret(policy autoopsv1alpha1.AutoOpsAgentPolicy, es es Annotations: meta.Annotations, }, Data: map[string][]byte{ - "api_key": []byte(encodedKey), + apiKeySecretKey: []byte(encodedKey), }, } } diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go index 0faf9c6c604..c85230c1697 100644 --- a/pkg/controller/autoops/api_key_test.go +++ b/pkg/controller/autoops/api_key_test.go @@ -109,7 +109,7 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { }, }, Data: map[string][]byte{ - "api_key": []byte("encoded-api-key-value"), + apiKeySecretKey: []byte("encoded-api-key-value"), }, }, }, @@ -144,7 +144,7 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { }, }, Data: map[string][]byte{ - "api_key": []byte("key"), + apiKeySecretKey: []byte("key"), }, }, }, diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index ad9c14bbf55..40a859dd3b4 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -54,9 +54,9 @@ func Add(mgr manager.Manager, params operator.Parameters) error { return addWatches(mgr, c, r) } -func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAutoOpsAgentPolicy { +func newReconciler(mgr manager.Manager, params operator.Parameters) *AutoOpsAgentPolicyReconciler { k8sClient := mgr.GetClient() - return &ReconcileAutoOpsAgentPolicy{ + return &AutoOpsAgentPolicyReconciler{ Client: k8sClient, recorder: mgr.GetEventRecorderFor(controllerName), licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), @@ -66,7 +66,7 @@ func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAu } } -func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAutoOpsAgentPolicy) error { +func addWatches(mgr manager.Manager, c controller.Controller, r *AutoOpsAgentPolicyReconciler) error { // watch for changes to AutoOpsAgentPolicy if err := c.Watch(source.Kind(mgr.GetCache(), &autoopsv1alpha1.AutoOpsAgentPolicy{}, &handler.TypedEnqueueRequestForObject[*autoopsv1alpha1.AutoOpsAgentPolicy]{})); err != nil { return err @@ -98,10 +98,10 @@ func reconcileRequestForAllAutoOpsPolicies(clnt k8s.Client) handler.TypedEventHa }) } -var _ reconcile.Reconciler = (*ReconcileAutoOpsAgentPolicy)(nil) +var _ reconcile.Reconciler = (*AutoOpsAgentPolicyReconciler)(nil) -// ReconcileAutoOpsAgentPolicy reconciles an AutoOpsAgentPolicy object -type ReconcileAutoOpsAgentPolicy struct { +// AutoOpsAgentPolicyReconciler reconciles an AutoOpsAgentPolicy object +type AutoOpsAgentPolicyReconciler struct { k8s.Client recorder record.EventRecorder licenseChecker license.Checker @@ -113,7 +113,7 @@ type ReconcileAutoOpsAgentPolicy struct { } // Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any resources are created/updated/deleted as needed. -func (r *ReconcileAutoOpsAgentPolicy) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { +func (r *AutoOpsAgentPolicyReconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) log := ulog.FromContext(ctx).WithValues( "policy_namespace", request.Namespace, @@ -171,7 +171,7 @@ func updatePhaseFromResults(results *reconciler.Results, state *State) { } } -func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { +func (r *AutoOpsAgentPolicyReconciler) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { span, ctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() @@ -184,7 +184,7 @@ func (r *ReconcileAutoOpsAgentPolicy) validate(ctx context.Context, policy *auto return nil } -func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { +func (r *AutoOpsAgentPolicyReconciler) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { span, ctx := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() @@ -211,7 +211,7 @@ func (r *ReconcileAutoOpsAgentPolicy) updateStatusFromState(ctx context.Context, return reconcile.Result{}, nil } -func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.NamespacedName) error { +func (r *AutoOpsAgentPolicyReconciler) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() log := ulog.FromContext(ctx) log.Info("Cleaning up AutoOpsAgentPolicy resources") @@ -265,7 +265,7 @@ func (r *ReconcileAutoOpsAgentPolicy) onDelete(ctx context.Context, obj types.Na } // reconcileWatches sets up dynamic watches for secrets referenced in the AutoOpsAgentPolicy spec. -func (r *ReconcileAutoOpsAgentPolicy) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { +func (r *AutoOpsAgentPolicyReconciler) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { watcher := k8s.ExtractNamespacedName(&policy) secretNames := []string{policy.Spec.Config.SecretRef.SecretName} diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index 889cc886f1c..e68598af02f 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -89,7 +89,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { }, }, Data: map[string][]byte{ - "api_key": []byte("test-key"), + apiKeySecretKey: []byte("test-key"), }, }, }, @@ -125,7 +125,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { }, }, Data: map[string][]byte{ - "api_key": []byte("test-key-1"), + apiKeySecretKey: []byte("test-key-1"), }, }, { @@ -140,7 +140,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { }, }, Data: map[string][]byte{ - "api_key": []byte("test-key-2"), + apiKeySecretKey: []byte("test-key-2"), }, }, }, @@ -271,7 +271,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { k8sClient := k8s.NewFakeClient(objects...) esClientProvider := newFakeESClientProvider() - r := &ReconcileAutoOpsAgentPolicy{ + r := &AutoOpsAgentPolicyReconciler{ Client: k8sClient, esClientProvider: esClientProvider.Provider, params: operator.Parameters{ diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 66d531c0443..d1cace81830 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -53,7 +53,7 @@ var ( } ) -func (r *ReconcileAutoOpsAgentPolicy) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { +func (r *AutoOpsAgentPolicyReconciler) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { v, err := version.Parse(policy.Spec.Version) if err != nil { return appsv1.Deployment{}, err @@ -200,7 +200,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A // // This data may not exist on initial reconciliation, so we don't return an error if it's missing. // // This should resolve itself on the next reconciliation after the API key is created. - if apiKeyData, ok := esAPIKeySecret.Data["api_key"]; ok { + if apiKeyData, ok := esAPIKeySecret.Data[apiKeySecretKey]; ok { _, _ = configHash.Write(apiKeyData) } @@ -245,7 +245,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse LocalObjectReference: corev1.LocalObjectReference{ Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), }, - Key: "api_key", + Key: apiKeySecretKey, Optional: ptr.To(false), }, }, diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index d30590f2966..ed32dfc41c1 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -124,12 +124,12 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { Namespace: tt.args.autoops.Namespace, }, Data: map[string][]byte{ - "api_key": []byte("test-es-api-key"), + apiKeySecretKey: []byte("test-es-api-key"), }, } client := k8s.NewFakeClient(configMap, autoopsSecret, esAPIKeySecret) - r := &ReconcileAutoOpsAgentPolicy{ + r := &AutoOpsAgentPolicyReconciler{ Client: client, } ctx := context.Background() @@ -277,7 +277,7 @@ func expectedDeployment(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elast LocalObjectReference: corev1.LocalObjectReference{ Name: autoopsv1alpha1.APIKeySecret(policy.GetName(), k8s.ExtractNamespacedName(&es)), }, - Key: "api_key", + Key: apiKeySecretKey, Optional: ptr.To(false), }, }, @@ -413,7 +413,7 @@ func Test_autoopsEnvVars(t *testing.T) { LocalObjectReference: corev1.LocalObjectReference{ Name: "policy-1-autoops-apikey-2334712842", }, - Key: "api_key", + Key: apiKeySecretKey, Optional: ptr.To(false), }, }, diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index bfefcf6ee37..9b8a0e23a79 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -21,7 +21,7 @@ import ( ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" ) -func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, state *State) *reconciler.Results { +func (r *AutoOpsAgentPolicyReconciler) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, state *State) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Reconcile AutoOpsAgentPolicy") @@ -56,7 +56,7 @@ func (r *ReconcileAutoOpsAgentPolicy) doReconcile(ctx context.Context, policy au return r.internalReconcile(ctx, policy, results, state) } -func (r *ReconcileAutoOpsAgentPolicy) internalReconcile( +func (r *AutoOpsAgentPolicyReconciler) internalReconcile( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 7345d8b6a8d..69eee39b5de 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -27,7 +27,7 @@ import ( // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate // for a specific Elasticsearch cluster, copying it from the ES instance's http-ca-internal secret. -func (r *ReconcileAutoOpsAgentPolicy) reconcileAutoOpsESCASecret( +func (r *AutoOpsAgentPolicyReconciler) reconcileAutoOpsESCASecret( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, From 17b69cf7b5430f140b9b9e2585911081a60ddb1f Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 10:09:07 -0600 Subject: [PATCH 84/90] Adjust cleanup on delete logic. Signed-off-by: Michael Montgomery --- pkg/controller/autoops/controller.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index 40a859dd3b4..c85ac758dc1 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -241,19 +241,16 @@ func (r *AutoOpsAgentPolicyReconciler) onDelete(ctx context.Context, obj types.N var es esv1.Elasticsearch if err := r.Client.Get(ctx, types.NamespacedName{Namespace: esNamespace, Name: esName}, &es); err != nil { - if apierrors.IsNotFound(err) { - // The ES cluster is gone, so we need to delete the API key secret - if err := deleteESAPIKeySecret(ctx, r.Client, log, - types.NamespacedName{Namespace: obj.Namespace, Name: obj.Name}, - types.NamespacedName{Namespace: esNamespace, Name: esName}); err != nil { - log.Error(err, "Failed to delete API key secret", "es_namespace", esNamespace, "es_name", esName) - } - continue + // On any error, still attempt to delete the API key secret. + if err := deleteESAPIKeySecret(ctx, r.Client, log, + types.NamespacedName{Namespace: obj.Namespace, Name: obj.Name}, + types.NamespacedName{Namespace: esNamespace, Name: esName}); err != nil { + log.Error(err, "Failed to delete API key secret", "es_namespace", esNamespace, "es_name", esName) } - log.Error(err, "Failed to get Elasticsearch cluster", "es_namespace", esNamespace, "es_name", esName) continue } + // This cleanup requires communicating with Elasticsearch so we do not attempt this is the previous retrival of the ES cluster fails. if err := cleanupAutoOpsESAPIKey(ctx, r.Client, r.esClientProvider, r.params.Dialer, obj.Namespace, obj.Name, es); err != nil { log.Error(err, "Failed to cleanup API key for Elasticsearch cluster", "es_namespace", esNamespace, "es_name", esName) continue From f38db2457842b6e5df46b01430d8eecccbef996b Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 13:47:41 -0600 Subject: [PATCH 85/90] Adding unit tests for internal reconcile. Other review changes. Removing some unused phases. Signed-off-by: Michael Montgomery --- .../v1alpha1/autoopsagentpolicy_types.go | 20 +- pkg/controller/autoops/api_key_test.go | 2 - pkg/controller/autoops/controller_test.go | 78 ++- pkg/controller/autoops/expected_test.go | 17 + pkg/controller/autoops/reconcile.go | 6 +- pkg/controller/autoops/reconcile_test.go | 601 ++++++++++++++++++ pkg/controller/autoops/state.go | 9 +- pkg/controller/autoops/state_test.go | 21 +- 8 files changed, 710 insertions(+), 44 deletions(-) create mode 100644 pkg/controller/autoops/reconcile_test.go diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index 4574b353571..d224fed607f 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -96,22 +96,14 @@ type AutoOpsAgentPolicyStatus struct { type PolicyPhase string const ( - UnknownPhase PolicyPhase = "Unknown" - ReadyPhase PolicyPhase = "Ready" - ApplyingChangesPhase PolicyPhase = "ApplyingChanges" - InvalidPhase PolicyPhase = "Invalid" - NoResourcesPhase PolicyPhase = "NoResources" - ErrorPhase PolicyPhase = "Error" + ReadyPhase PolicyPhase = "Ready" + ApplyingChangesPhase PolicyPhase = "ApplyingChanges" + InvalidPhase PolicyPhase = "Invalid" + NoResourcesPhase PolicyPhase = "NoResources" + ResourcesNotReadyPhase PolicyPhase = "ResourcesNotReady" + ErrorPhase PolicyPhase = "Error" ) -func NewStatus(policy AutoOpsAgentPolicy) AutoOpsAgentPolicyStatus { - status := AutoOpsAgentPolicyStatus{ - Phase: UnknownPhase, - ObservedGeneration: policy.Generation, - } - return status -} - // IsMarkedForDeletion returns true if the AutoOpsAgentPolicy resource is going to be deleted. func (p *AutoOpsAgentPolicy) IsMarkedForDeletion() bool { return !p.DeletionTimestamp.IsZero() diff --git a/pkg/controller/autoops/api_key_test.go b/pkg/controller/autoops/api_key_test.go index c85230c1697..bf5ebfed6b8 100644 --- a/pkg/controller/autoops/api_key_test.go +++ b/pkg/controller/autoops/api_key_test.go @@ -100,7 +100,6 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { commonapikey.MetadataKeyConfigHash: "hash123", commonapikey.MetadataKeyESName: "es-1", commonapikey.MetadataKeyESNamespace: "ns-2", - commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", }, @@ -138,7 +137,6 @@ func Test_buildAutoOpsESAPIKeySecret(t *testing.T) { commonapikey.MetadataKeyConfigHash: "hash123", commonapikey.MetadataKeyESName: "es-1", commonapikey.MetadataKeyESNamespace: "ns-2", - commonapikey.MetadataKeyManagedBy: commonapikey.MetadataValueECK, PolicyNameLabelKey: "policy-1", policyNamespaceLabelKey: "ns-1", }, diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index e68598af02f..36914b936cb 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -6,6 +6,7 @@ package autoops import ( "context" + "errors" "net" "testing" @@ -19,6 +20,7 @@ import ( autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" esclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/elasticsearch/client" @@ -37,21 +39,40 @@ func newFakeESClientProvider() *fakeESClientProvider { } } +func newFakeESClientProviderWithClient(client *fakeESClient) *fakeESClientProvider { + return &fakeESClientProvider{ + client: client, + } +} + func (f *fakeESClientProvider) Provider(ctx context.Context, c k8s.Client, dialer netutil.Dialer, es esv1.Elasticsearch) (esclient.Client, error) { return f.client, nil } type fakeESClient struct { esclient.Client + getAPIKeysByNameErr error } func (f *fakeESClient) Close() { } func (f *fakeESClient) GetAPIKeysByName(ctx context.Context, name string) (esclient.APIKeyList, error) { + if f.getAPIKeysByNameErr != nil { + return esclient.APIKeyList{}, f.getAPIKeysByNameErr + } return esclient.APIKeyList{APIKeys: []esclient.APIKey{}}, nil } +func (f *fakeESClient) CreateAPIKey(ctx context.Context, req esclient.APIKeyCreateRequest) (esclient.APIKeyCreateResponse, error) { + return esclient.APIKeyCreateResponse{ + ID: req.ID, + Name: req.Name, + APIKey: req.APIKey.Name, + Encoded: "dGVzdC1hcGkta2V5LWlkOnRlc3QtYXBpLWtleQ==", + }, nil +} + func (f *fakeESClient) InvalidateAPIKeys(ctx context.Context, req esclient.APIKeysInvalidateRequest) (esclient.APIKeysInvalidateResponse, error) { return esclient.APIKeysInvalidateResponse{}, nil } @@ -64,11 +85,12 @@ func (f *fakeDialer) DialContext(ctx context.Context, network, addr string) (net func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { tests := []struct { - name string - policy types.NamespacedName - secrets []corev1.Secret - esClusters []esv1.Elasticsearch - wantErr bool + name string + policy types.NamespacedName + secrets []corev1.Secret + esClusters []esv1.Elasticsearch + esClientProvider commonesclient.Provider + wantErr bool }{ { name: "cleanup API keys for single ES cluster", @@ -256,6 +278,45 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { }, wantErr: false, }, + { + name: "handle ES cluster error when getting API keys", + policy: types.NamespacedName{ + Namespace: "ns-1", + Name: "policy-1", + }, + secrets: []corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1-ns-2-autoops-es-api-key", + Namespace: "ns-1", + Labels: map[string]string{ + PolicyNameLabelKey: "policy-1", + policyNamespaceLabelKey: "ns-1", + "elasticsearch.k8s.elastic.co/name": "es-1", + "elasticsearch.k8s.elastic.co/namespace": "ns-2", + }, + }, + Data: map[string][]byte{ + apiKeySecretKey: []byte("test-key"), + }, + }, + }, + esClusters: []esv1.Elasticsearch{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-2", + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + }, + esClientProvider: newFakeESClientProviderWithClient(&fakeESClient{ + getAPIKeysByNameErr: errors.New("elasticsearch cluster unavailable"), + }).Provider, + wantErr: false, // onDelete continues on error, hence no error wanted here + }, } for _, tt := range tests { @@ -269,11 +330,14 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { } k8sClient := k8s.NewFakeClient(objects...) - esClientProvider := newFakeESClientProvider() + esClientProvider := tt.esClientProvider + if esClientProvider == nil { + esClientProvider = newFakeESClientProvider().Provider + } r := &AutoOpsAgentPolicyReconciler{ Client: k8sClient, - esClientProvider: esClientProvider.Provider, + esClientProvider: esClientProvider, params: operator.Parameters{ Dialer: &fakeDialer{}, }, diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index ed32dfc41c1..47ef8dd89c8 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -33,6 +33,11 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0-SNAPSHOT", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "autoops-secret", + }, + }, }, } @@ -80,6 +85,11 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "invalid-version", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "autoops-secret", + }, + }, }, }, es: esFixture, @@ -378,6 +388,13 @@ func Test_autoopsEnvVars(t *testing.T) { Name: "policy-1", Namespace: "ns-2", }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "autoops-secret", + }, + }, + }, }, want: []corev1.EnvVar{ { diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 9b8a0e23a79..1cf4d081b0a 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -32,8 +32,6 @@ func (r *AutoOpsAgentPolicyReconciler) doReconcile(ctx context.Context, policy a if err != nil { return results.WithError(err) } - // temporary to see what happens in non-enterprise - enabled = true if !enabled { msg := "AutoOpsAgentPolicy is an enterprise feature. Enterprise features are disabled" log.Info(msg) @@ -105,6 +103,7 @@ func (r *AutoOpsAgentPolicyReconciler) internalReconcile( for _, es := range esList.Items { if es.Status.Phase != esv1.ElasticsearchReadyPhase { log.V(1).Info("Skipping ES cluster that is not ready", "namespace", es.Namespace, "name", es.Name) + state.UpdateWithPhase(autoopsv1alpha1.ResourcesNotReadyPhase) results = results.WithRequeue(defaultRequeue) continue } @@ -153,8 +152,7 @@ func (r *AutoOpsAgentPolicyReconciler) internalReconcile( continue } - // Only increment readyCount if there are no errors in previous ES instances. - if isDeploymentReady(reconciledDeployment) && errorCount == 0 { + if isDeploymentReady(reconciledDeployment) { readyCount++ } } diff --git a/pkg/controller/autoops/reconcile_test.go b/pkg/controller/autoops/reconcile_test.go new file mode 100644 index 00000000000..5a9b6d5ec13 --- /dev/null +++ b/pkg/controller/autoops/reconcile_test.go @@ -0,0 +1,601 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package autoops + +import ( + "context" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + autoopsv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/autoops/v1alpha1" + commonv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/common/v1" + esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" + commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/scheme" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/watches" + "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" +) + +func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { + scheme.SetupScheme() + + tests := []struct { + name string + policy autoopsv1alpha1.AutoOpsAgentPolicy + initialObjects []client.Object + esClientProvider commonesclient.Provider + wantStatus autoopsv1alpha1.AutoOpsAgentPolicyStatus + wantResults reconcile.Result + }{ + { + name: "config secret not found sets error phase", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "missing-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{}, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Phase: autoopsv1alpha1.ErrorPhase, + }, + wantResults: reconcile.Result{}, + }, + { + name: "config secret missing required keys sets error phase", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "invalid-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "invalid-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{}, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Phase: autoopsv1alpha1.ErrorPhase, + }, + wantResults: reconcile.Result{}, + }, + { + name: "invalid label selector sets error phase", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "app", + Operator: "InvalidOperator", + Values: []string{"elasticsearch"}, + }, + }, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Phase: autoopsv1alpha1.ErrorPhase, + }, + wantResults: reconcile.Result{}, + }, + { + name: "no ES resources found sets no resources phase", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Phase: autoopsv1alpha1.NoResourcesPhase, + Resources: 0, + }, + wantResults: reconcile.Result{}, + }, + { + name: "ES resource not ready", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchApplyingChangesPhase, + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Resources: 1, + Ready: 0, + Phase: autoopsv1alpha1.ResourcesNotReadyPhase, + }, + wantResults: reconcile.Result{RequeueAfter: 5 * time.Second}, + }, + { + name: "successful reconciliation with one ready ES", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Resources: 1, + Ready: 0, // Deployment won't be ready yet. + Errors: 0, + }, + wantResults: reconcile.Result{}, + }, + { + name: "multiple ES resources with mixed states", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-2", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchApplyingChangesPhase, + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Resources: 2, + Ready: 0, // Deployment won't be ready yet. + Errors: 0, + Phase: autoopsv1alpha1.ResourcesNotReadyPhase, // es-2 is not ready + }, + wantResults: reconcile.Result{RequeueAfter: 5 * time.Second}, + }, + { + name: "single ES with ready deployment shows ready: 1, resources: 1", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.Config("policy-1", esv1.Elasticsearch{ObjectMeta: metav1.ObjectMeta{Name: "es-1", Namespace: "ns-1"}}), + Namespace: "ns-1", + }, + Data: map[string]string{ + autoOpsESConfigFileName: "test-config", + }, + }, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.APIKeySecret("policy-1", types.NamespacedName{Name: "es-1", Namespace: "ns-1"}), + Namespace: "ns-1", + }, + Data: map[string][]byte{ + apiKeySecretKey: []byte("test-api-key"), + }, + }, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.Deployment("policy-1", esv1.Elasticsearch{ObjectMeta: metav1.ObjectMeta{Name: "es-1", Namespace: "ns-1"}}), + Namespace: "ns-1", + }, + Status: appsv1.DeploymentStatus{ + Conditions: []appsv1.DeploymentCondition{ + { + Type: appsv1.DeploymentAvailable, + Status: corev1.ConditionTrue, + }, + }, + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Resources: 1, + Ready: 1, + Errors: 0, + Phase: "", // Ready, or applyingChanges phases are set in the main Reconcile function, not here. + }, + wantResults: reconcile.Result{}, + }, + { + name: "two ES instances: one with ready deployment, one without shows ready: 1, resources: 2", + policy: autoopsv1alpha1.AutoOpsAgentPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "policy-1", + Namespace: "ns-1", + }, + Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ + Version: "9.1.0", + Config: commonv1.ConfigSource{ + SecretRef: commonv1.SecretRef{ + SecretName: "config-secret", + }, + }, + ResourceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "elasticsearch"}, + }, + }, + }, + initialObjects: []client.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config-secret", + Namespace: "ns-1", + }, + Data: map[string][]byte{ + "cloud-connected-mode-api-key": []byte("test-key"), + "autoops-otel-url": []byte("https://test-url"), + "autoops-token": []byte("test-token"), + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-1", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + &esv1.Elasticsearch{ + ObjectMeta: metav1.ObjectMeta{ + Name: "es-2", + Namespace: "ns-1", + Labels: map[string]string{"app": "elasticsearch"}, + }, + Spec: esv1.ElasticsearchSpec{ + Version: "9.1.0", + HTTP: commonv1.HTTPConfig{ + TLS: commonv1.TLSOptions{ + SelfSignedCertificate: &commonv1.SelfSignedCertificate{ + Disabled: true, + }, + }, + }, + }, + Status: esv1.ElasticsearchStatus{ + Phase: esv1.ElasticsearchReadyPhase, + }, + }, + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.Config("policy-1", esv1.Elasticsearch{ObjectMeta: metav1.ObjectMeta{Name: "es-1", Namespace: "ns-1"}}), + Namespace: "ns-1", + }, + Data: map[string]string{ + autoOpsESConfigFileName: "test-config", + }, + }, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.APIKeySecret("policy-1", types.NamespacedName{Name: "es-1", Namespace: "ns-1"}), + Namespace: "ns-1", + }, + Data: map[string][]byte{ + apiKeySecretKey: []byte("test-api-key"), + }, + }, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: autoopsv1alpha1.Deployment("policy-1", esv1.Elasticsearch{ObjectMeta: metav1.ObjectMeta{Name: "es-1", Namespace: "ns-1"}}), + Namespace: "ns-1", + }, + Status: appsv1.DeploymentStatus{ + Conditions: []appsv1.DeploymentCondition{ + { + Type: appsv1.DeploymentAvailable, + Status: corev1.ConditionTrue, + }, + }, + }, + }, + }, + wantStatus: autoopsv1alpha1.AutoOpsAgentPolicyStatus{ + Resources: 2, + Ready: 1, + Errors: 0, + Phase: "", // Ready, or applyingChanges phases are set in the main Reconcile function, not here. + }, + wantResults: reconcile.Result{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k8sClient := k8s.NewFakeClient(tt.initialObjects...) + esClientProvider := tt.esClientProvider + if esClientProvider == nil { + esClientProvider = newFakeESClientProvider().Provider + } + + r := &AutoOpsAgentPolicyReconciler{ + Client: k8sClient, + esClientProvider: esClientProvider, + params: operator.Parameters{ + Dialer: &fakeDialer{}, + }, + dynamicWatches: watches.NewDynamicWatches(), + licenseChecker: license.NewLicenseChecker(k8sClient, "test-namespace"), + } + + ctx := context.Background() + state := NewState(tt.policy) + results := reconciler.NewResult(ctx) + + gotResults := r.internalReconcile(ctx, tt.policy, results, state) + + gotResult, gotErr := gotResults.Aggregate() + require.Equal(t, tt.wantStatus.Phase == autoopsv1alpha1.ErrorPhase, gotErr != nil) + + if !cmp.Equal(tt.wantStatus, state.status, cmpopts.IgnoreFields(autoopsv1alpha1.AutoOpsAgentPolicyStatus{}, "ObservedGeneration")) { + t.Errorf("status mismatch:\n%s", cmp.Diff(tt.wantStatus, state.status, cmpopts.IgnoreFields(autoopsv1alpha1.AutoOpsAgentPolicyStatus{}, "ObservedGeneration"))) + } + require.Equal(t, tt.wantResults, gotResult) + }) + } +} diff --git a/pkg/controller/autoops/state.go b/pkg/controller/autoops/state.go index e64fd533b65..dfd3cec9f1d 100644 --- a/pkg/controller/autoops/state.go +++ b/pkg/controller/autoops/state.go @@ -37,18 +37,21 @@ func NewState(policy autoopsv1alpha1.AutoOpsAgentPolicy) *State { } // UpdateWithPhase updates the phase of the AutoOpsAgentPolicy status. -// It respects phase stickiness - InvalidPhase will not be overwritten, and ApplyingChangesPhase -// and ReadyPhase will not overwrite other non-ready phases. +// It respects phase stickiness - InvalidPhase and NoResourcesPhase will not be overwritten, +// and ApplyingChangesPhase and ReadyPhase will not overwrite other non-ready phases. func (s *State) UpdateWithPhase(phase autoopsv1alpha1.PolicyPhase) *State { nonReadyPhases := set.Make( string(autoopsv1alpha1.ErrorPhase), string(autoopsv1alpha1.NoResourcesPhase), - string(autoopsv1alpha1.UnknownPhase), + string(autoopsv1alpha1.ResourcesNotReadyPhase), ) switch { // do not overwrite the Invalid phase case s.status.Phase == autoopsv1alpha1.InvalidPhase: return s + // do not overwrite the NoResources phase + case s.status.Phase == autoopsv1alpha1.NoResourcesPhase: + return s // do not overwrite non-ready phases with ApplyingChangesPhase case phase == autoopsv1alpha1.ApplyingChangesPhase && nonReadyPhases.Has(string(s.status.Phase)): return s diff --git a/pkg/controller/autoops/state_test.go b/pkg/controller/autoops/state_test.go index 8908d9dc0ed..54c7ff01966 100644 --- a/pkg/controller/autoops/state_test.go +++ b/pkg/controller/autoops/state_test.go @@ -98,13 +98,6 @@ func TestState_UpdateWithPhase(t *testing.T) { expectedPhase: autoopsv1alpha1.NoResourcesPhase, shouldUpdate: false, }, - { - name: "UnknownPhase should not be overwritten by ApplyingChangesPhase", - initialPhase: autoopsv1alpha1.UnknownPhase, - updatePhase: autoopsv1alpha1.ApplyingChangesPhase, - expectedPhase: autoopsv1alpha1.UnknownPhase, - shouldUpdate: false, - }, { name: "ReadyPhase can be overwritten by ApplyingChangesPhase", initialPhase: autoopsv1alpha1.ReadyPhase, @@ -126,13 +119,6 @@ func TestState_UpdateWithPhase(t *testing.T) { expectedPhase: autoopsv1alpha1.NoResourcesPhase, shouldUpdate: false, }, - { - name: "UnknownPhase should not be overwritten by ReadyPhase", - initialPhase: autoopsv1alpha1.UnknownPhase, - updatePhase: autoopsv1alpha1.ReadyPhase, - expectedPhase: autoopsv1alpha1.UnknownPhase, - shouldUpdate: false, - }, { name: "ApplyingChangesPhase can transition to ReadyPhase", initialPhase: autoopsv1alpha1.ApplyingChangesPhase, @@ -140,6 +126,13 @@ func TestState_UpdateWithPhase(t *testing.T) { expectedPhase: autoopsv1alpha1.ReadyPhase, shouldUpdate: true, }, + { + name: "NoResourcesPhase should not be overwritten by ErrorPhase", + initialPhase: autoopsv1alpha1.NoResourcesPhase, + updatePhase: autoopsv1alpha1.ErrorPhase, + expectedPhase: autoopsv1alpha1.NoResourcesPhase, + shouldUpdate: false, + }, } for _, tt := range tests { From 4ab8be8cc4237915cbc113db78c4ff021c2bf290 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 14:22:04 -0600 Subject: [PATCH 86/90] unexport newstate Signed-off-by: Michael Montgomery --- pkg/controller/autoops/controller.go | 4 +--- pkg/controller/autoops/reconcile_test.go | 2 +- pkg/controller/autoops/state.go | 4 ++-- pkg/controller/autoops/state_test.go | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index c85ac758dc1..c82a5cbd22a 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -141,14 +141,12 @@ func (r *AutoOpsAgentPolicyReconciler) Reconcile(ctx context.Context, request re return reconcile.Result{}, nil } - state := NewState(policy) - + state := newState(policy) if policy.IsMarkedForDeletion() { return reconcile.Result{}, r.onDelete(ctx, k8s.ExtractNamespacedName(&policy)) } results := r.doReconcile(ctx, policy, state) - updatePhaseFromResults(results, state) result, err := r.updateStatusFromState(ctx, state) diff --git a/pkg/controller/autoops/reconcile_test.go b/pkg/controller/autoops/reconcile_test.go index 5a9b6d5ec13..ad085f4ddca 100644 --- a/pkg/controller/autoops/reconcile_test.go +++ b/pkg/controller/autoops/reconcile_test.go @@ -584,7 +584,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { } ctx := context.Background() - state := NewState(tt.policy) + state := newState(tt.policy) results := reconciler.NewResult(ctx) gotResults := r.internalReconcile(ctx, tt.policy, results, state) diff --git a/pkg/controller/autoops/state.go b/pkg/controller/autoops/state.go index dfd3cec9f1d..b0df4fc75f1 100644 --- a/pkg/controller/autoops/state.go +++ b/pkg/controller/autoops/state.go @@ -22,8 +22,8 @@ type State struct { status autoopsv1alpha1.AutoOpsAgentPolicyStatus } -// NewState creates a new reconcile state based on the given policy -func NewState(policy autoopsv1alpha1.AutoOpsAgentPolicy) *State { +// newState creates a new reconcile state based on the given policy +func newState(policy autoopsv1alpha1.AutoOpsAgentPolicy) *State { status := *policy.Status.DeepCopy() status.ObservedGeneration = policy.Generation // Similar to ES, we initially set the phase to an empty string so that we do not report an outdated phase diff --git a/pkg/controller/autoops/state_test.go b/pkg/controller/autoops/state_test.go index 54c7ff01966..fbabd9f3cb1 100644 --- a/pkg/controller/autoops/state_test.go +++ b/pkg/controller/autoops/state_test.go @@ -146,7 +146,7 @@ func TestState_UpdateWithPhase(t *testing.T) { Phase: tt.initialPhase, }, } - state := NewState(policy) + state := newState(policy) state.status.Phase = tt.initialPhase state.UpdateWithPhase(tt.updatePhase) assert.Equal(t, tt.expectedPhase, state.status.Phase) From 739bfdd0974c442c56739a64e5cf298d15bf3b12 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 14:34:04 -0600 Subject: [PATCH 87/90] Update name of reconciler. Fix unit tests in es/user Signed-off-by: Michael Montgomery --- pkg/controller/autoops/api_key.go | 10 ++++----- pkg/controller/autoops/controller.go | 22 +++++++++---------- pkg/controller/autoops/controller_test.go | 2 +- pkg/controller/autoops/expected.go | 2 +- pkg/controller/autoops/expected_test.go | 2 +- pkg/controller/autoops/reconcile.go | 4 ++-- pkg/controller/autoops/reconcile_test.go | 2 +- pkg/controller/autoops/secret.go | 2 +- .../elasticsearch/user/reconcile_test.go | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pkg/controller/autoops/api_key.go b/pkg/controller/autoops/api_key.go index fe3c4187e53..260f82fb296 100644 --- a/pkg/controller/autoops/api_key.go +++ b/pkg/controller/autoops/api_key.go @@ -46,7 +46,7 @@ type apiKeySpec struct { } // reconcileAutoOpsESAPIKey reconciles the API key and secret for a specific Elasticsearch cluster. -func (r *AutoOpsAgentPolicyReconciler) reconcileAutoOpsESAPIKey( +func (r *AgentPolicyReconciler) reconcileAutoOpsESAPIKey( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, @@ -101,7 +101,7 @@ func (r *AutoOpsAgentPolicyReconciler) reconcileAutoOpsESAPIKey( } // createAPIKey creates a new API key in Elasticsearch and stores it in a secret. -func (r *AutoOpsAgentPolicyReconciler) createAPIKey( +func (r *AgentPolicyReconciler) createAPIKey( ctx context.Context, log logr.Logger, esClient esclient.Client, @@ -136,7 +136,7 @@ func (r *AutoOpsAgentPolicyReconciler) createAPIKey( } // maybeUpdateAPIKey checks if the API key needs to be updated and handles it. -func (r *AutoOpsAgentPolicyReconciler) maybeUpdateAPIKey( +func (r *AgentPolicyReconciler) maybeUpdateAPIKey( ctx context.Context, log logr.Logger, activeAPIKey *esclient.APIKey, @@ -177,7 +177,7 @@ func (r *AutoOpsAgentPolicyReconciler) maybeUpdateAPIKey( return nil } -func (r *AutoOpsAgentPolicyReconciler) invalidateAndCreateAPIKey( +func (r *AgentPolicyReconciler) invalidateAndCreateAPIKey( ctx context.Context, log logr.Logger, activeAPIKey *esclient.APIKey, @@ -207,7 +207,7 @@ func invalidateAPIKey(ctx context.Context, esClient esclient.Client, keyID strin } // storeAPIKeyInSecret stores the API key in a Kubernetes secret. -func (r *AutoOpsAgentPolicyReconciler) storeAPIKeyInSecret( +func (r *AgentPolicyReconciler) storeAPIKeyInSecret( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index c82a5cbd22a..ce232c4edb9 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -54,9 +54,9 @@ func Add(mgr manager.Manager, params operator.Parameters) error { return addWatches(mgr, c, r) } -func newReconciler(mgr manager.Manager, params operator.Parameters) *AutoOpsAgentPolicyReconciler { +func newReconciler(mgr manager.Manager, params operator.Parameters) *AgentPolicyReconciler { k8sClient := mgr.GetClient() - return &AutoOpsAgentPolicyReconciler{ + return &AgentPolicyReconciler{ Client: k8sClient, recorder: mgr.GetEventRecorderFor(controllerName), licenseChecker: license.NewLicenseChecker(k8sClient, params.OperatorNamespace), @@ -66,7 +66,7 @@ func newReconciler(mgr manager.Manager, params operator.Parameters) *AutoOpsAgen } } -func addWatches(mgr manager.Manager, c controller.Controller, r *AutoOpsAgentPolicyReconciler) error { +func addWatches(mgr manager.Manager, c controller.Controller, r *AgentPolicyReconciler) error { // watch for changes to AutoOpsAgentPolicy if err := c.Watch(source.Kind(mgr.GetCache(), &autoopsv1alpha1.AutoOpsAgentPolicy{}, &handler.TypedEnqueueRequestForObject[*autoopsv1alpha1.AutoOpsAgentPolicy]{})); err != nil { return err @@ -98,10 +98,10 @@ func reconcileRequestForAllAutoOpsPolicies(clnt k8s.Client) handler.TypedEventHa }) } -var _ reconcile.Reconciler = (*AutoOpsAgentPolicyReconciler)(nil) +var _ reconcile.Reconciler = (*AgentPolicyReconciler)(nil) -// AutoOpsAgentPolicyReconciler reconciles an AutoOpsAgentPolicy object -type AutoOpsAgentPolicyReconciler struct { +// AgentPolicyReconciler reconciles an AutoOpsAgentPolicy object +type AgentPolicyReconciler struct { k8s.Client recorder record.EventRecorder licenseChecker license.Checker @@ -113,7 +113,7 @@ type AutoOpsAgentPolicyReconciler struct { } // Reconcile reconciles the AutoOpsAgentPolicy resource ensuring that any resources are created/updated/deleted as needed. -func (r *AutoOpsAgentPolicyReconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { +func (r *AgentPolicyReconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { ctx = common.NewReconciliationContext(ctx, &r.iteration, r.params.Tracer, controllerName, "autoops_name", request) log := ulog.FromContext(ctx).WithValues( "policy_namespace", request.Namespace, @@ -169,7 +169,7 @@ func updatePhaseFromResults(results *reconciler.Results, state *State) { } } -func (r *AutoOpsAgentPolicyReconciler) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { +func (r *AgentPolicyReconciler) validate(ctx context.Context, policy *autoopsv1alpha1.AutoOpsAgentPolicy) error { span, ctx := apm.StartSpan(ctx, "validate", tracing.SpanTypeApp) defer span.End() @@ -182,7 +182,7 @@ func (r *AutoOpsAgentPolicyReconciler) validate(ctx context.Context, policy *aut return nil } -func (r *AutoOpsAgentPolicyReconciler) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { +func (r *AgentPolicyReconciler) updateStatusFromState(ctx context.Context, state *State) (reconcile.Result, error) { span, ctx := apm.StartSpan(ctx, "update_status", tracing.SpanTypeApp) defer span.End() @@ -209,7 +209,7 @@ func (r *AutoOpsAgentPolicyReconciler) updateStatusFromState(ctx context.Context return reconcile.Result{}, nil } -func (r *AutoOpsAgentPolicyReconciler) onDelete(ctx context.Context, obj types.NamespacedName) error { +func (r *AgentPolicyReconciler) onDelete(ctx context.Context, obj types.NamespacedName) error { defer tracing.Span(&ctx)() log := ulog.FromContext(ctx) log.Info("Cleaning up AutoOpsAgentPolicy resources") @@ -260,7 +260,7 @@ func (r *AutoOpsAgentPolicyReconciler) onDelete(ctx context.Context, obj types.N } // reconcileWatches sets up dynamic watches for secrets referenced in the AutoOpsAgentPolicy spec. -func (r *AutoOpsAgentPolicyReconciler) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { +func (r *AgentPolicyReconciler) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { watcher := k8s.ExtractNamespacedName(&policy) secretNames := []string{policy.Spec.Config.SecretRef.SecretName} diff --git a/pkg/controller/autoops/controller_test.go b/pkg/controller/autoops/controller_test.go index 36914b936cb..b9c6b303354 100644 --- a/pkg/controller/autoops/controller_test.go +++ b/pkg/controller/autoops/controller_test.go @@ -335,7 +335,7 @@ func TestReconcileAutoOpsAgentPolicy_onDelete(t *testing.T) { esClientProvider = newFakeESClientProvider().Provider } - r := &AutoOpsAgentPolicyReconciler{ + r := &AgentPolicyReconciler{ Client: k8sClient, esClientProvider: esClientProvider, params: operator.Parameters{ diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index d1cace81830..01f3f36369f 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -53,7 +53,7 @@ var ( } ) -func (r *AutoOpsAgentPolicyReconciler) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { +func (r *AgentPolicyReconciler) deploymentParams(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch) (appsv1.Deployment, error) { v, err := version.Parse(policy.Spec.Version) if err != nil { return appsv1.Deployment{}, err diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 47ef8dd89c8..756f7d6a7dd 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -139,7 +139,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { } client := k8s.NewFakeClient(configMap, autoopsSecret, esAPIKeySecret) - r := &AutoOpsAgentPolicyReconciler{ + r := &AgentPolicyReconciler{ Client: client, } ctx := context.Background() diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 1cf4d081b0a..3d5913774aa 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -21,7 +21,7 @@ import ( ulog "github.com/elastic/cloud-on-k8s/v3/pkg/utils/log" ) -func (r *AutoOpsAgentPolicyReconciler) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, state *State) *reconciler.Results { +func (r *AgentPolicyReconciler) doReconcile(ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, state *State) *reconciler.Results { log := ulog.FromContext(ctx) log.V(1).Info("Reconcile AutoOpsAgentPolicy") @@ -54,7 +54,7 @@ func (r *AutoOpsAgentPolicyReconciler) doReconcile(ctx context.Context, policy a return r.internalReconcile(ctx, policy, results, state) } -func (r *AutoOpsAgentPolicyReconciler) internalReconcile( +func (r *AgentPolicyReconciler) internalReconcile( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, results *reconciler.Results, diff --git a/pkg/controller/autoops/reconcile_test.go b/pkg/controller/autoops/reconcile_test.go index ad085f4ddca..5181f818492 100644 --- a/pkg/controller/autoops/reconcile_test.go +++ b/pkg/controller/autoops/reconcile_test.go @@ -573,7 +573,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { esClientProvider = newFakeESClientProvider().Provider } - r := &AutoOpsAgentPolicyReconciler{ + r := &AgentPolicyReconciler{ Client: k8sClient, esClientProvider: esClientProvider, params: operator.Parameters{ diff --git a/pkg/controller/autoops/secret.go b/pkg/controller/autoops/secret.go index 69eee39b5de..a94417e1cdc 100644 --- a/pkg/controller/autoops/secret.go +++ b/pkg/controller/autoops/secret.go @@ -27,7 +27,7 @@ import ( // reconcileAutoOpsESCASecret reconciles the Secret containing the CA certificate // for a specific Elasticsearch cluster, copying it from the ES instance's http-ca-internal secret. -func (r *AutoOpsAgentPolicyReconciler) reconcileAutoOpsESCASecret( +func (r *AgentPolicyReconciler) reconcileAutoOpsESCASecret( ctx context.Context, policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticsearch, diff --git a/pkg/controller/elasticsearch/user/reconcile_test.go b/pkg/controller/elasticsearch/user/reconcile_test.go index daac766b992..547c38ccd75 100644 --- a/pkg/controller/elasticsearch/user/reconcile_test.go +++ b/pkg/controller/elasticsearch/user/reconcile_test.go @@ -131,6 +131,6 @@ func Test_aggregateRoles(t *testing.T) { c := k8s.NewFakeClient(sampleUserProvidedRolesSecret...) roles, err := aggregateRoles(context.Background(), c, sampleEsWithAuth, initDynamicWatches(), record.NewFakeRecorder(10)) require.NoError(t, err) - require.Len(t, roles, 57) + require.Len(t, roles, 58) require.Contains(t, roles, ProbeUserRole, ClusterManageRole, "role1", "role2") } From ad239f59f52df0887cee795a99d0e45d7b7074ef Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 16:21:08 -0600 Subject: [PATCH 88/90] Allow ability to override the configuration Signed-off-by: Michael Montgomery --- config/samples/autoops/autoops.yaml | 2 +- .../eck-stack/charts/eck-autoops/values.yaml | 6 +++++ .../v1alpha1/autoopsagentpolicy_types.go | 9 +++++-- pkg/apis/autoops/v1alpha1/validations.go | 2 +- pkg/controller/autoops/configmap.go | 27 ++++++++++++++++++- pkg/controller/autoops/controller.go | 2 +- pkg/controller/autoops/expected.go | 10 +++---- pkg/controller/autoops/expected_test.go | 6 ++--- pkg/controller/autoops/reconcile.go | 4 +-- pkg/controller/autoops/reconcile_test.go | 18 ++++++------- 10 files changed, 61 insertions(+), 25 deletions(-) diff --git a/config/samples/autoops/autoops.yaml b/config/samples/autoops/autoops.yaml index 07de2b8097f..42ef0bd9373 100644 --- a/config/samples/autoops/autoops.yaml +++ b/config/samples/autoops/autoops.yaml @@ -22,7 +22,7 @@ metadata: name: autoops-sample spec: version: 9.2.0 - config: + configRef: # This secret contains the AutoOps configuration. # It must contain the following: # - ccmApiKey: the Cloud Connected Mode API key. This is used to register the Agent with Elastic Cloud AutoOps. diff --git a/deploy/eck-stack/charts/eck-autoops/values.yaml b/deploy/eck-stack/charts/eck-autoops/values.yaml index 996156f5d5a..ef6e0434f6a 100644 --- a/deploy/eck-stack/charts/eck-autoops/values.yaml +++ b/deploy/eck-stack/charts/eck-autoops/values.yaml @@ -44,6 +44,12 @@ annotations: {} configRef: {} # secretName: "" +# Config holds the AutoOps Agent configuration for Elasticsearch monitoring. +# This configuration is intended to override parts of the autoops_es.yml configmap. +# See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml +# +kubebuilder:pruning:PreserveUnknownFields +# config: {} + # Image is the AutoOps Agent Docker image to deploy. # image: "docker.elastic.co/elastic-agent/elastic-otel-collector-wolfi:9.3.0-SNAPSHOT" diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index d224fed607f..ea050591bbc 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -53,7 +53,7 @@ type AutoOpsAgentPolicySpec struct { // ResourceSelector is a label selector for the resources to be configured. // Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. ResourceSelector metav1.LabelSelector `json:"resourceSelector,omitempty"` - // Config holds the AutoOpsAgentPolicy configuration. + // ConfigRef holds the AutoOpsAgentPolicy configuration. // The contents of the referenced secret requires the following format: // kind: Secret // apiVersion: v1 @@ -63,7 +63,12 @@ type AutoOpsAgentPolicySpec struct { // ccmApiKey: aslkfjsldkjfslkdjflksdjfl // autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co // autoOpsToken: skdfjdskjf - Config commonv1.ConfigSource `json:"config,omitempty"` + ConfigRef commonv1.ConfigSource `json:"config,omitempty"` + // Config holds the AutoOps agent configuration for Elasticsearch monitoring. + // This configuration is intended to override parts of the autoops_es.yml configmap. + // See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + // +kubebuilder:pruning:PreserveUnknownFields + Config *commonv1.Config `json:"esConfig,omitempty"` // AutoOpsRef is a reference to an AutoOps instance running in the same Kubernetes cluster. // (TODO) AutoOpsRef is not yet implemented. // AutoOpsRef commonv1.ObjectSelector `json:"autoOpsRef,omitempty"` diff --git a/pkg/apis/autoops/v1alpha1/validations.go b/pkg/apis/autoops/v1alpha1/validations.go index 59e9355f25a..eec29a0cbb1 100644 --- a/pkg/apis/autoops/v1alpha1/validations.go +++ b/pkg/apis/autoops/v1alpha1/validations.go @@ -24,7 +24,7 @@ func checkSupportedVersion(policy *AutoOpsAgentPolicy) field.ErrorList { } func checkConfigSecretName(policy *AutoOpsAgentPolicy) field.ErrorList { - if policy.Spec.Config.SecretName == "" { + if policy.Spec.ConfigRef.SecretName == "" { return field.ErrorList{field.Required(field.NewPath("spec").Child("config").Child("secretName"), "Config secret name must be specified")} } return nil diff --git a/pkg/controller/autoops/configmap.go b/pkg/controller/autoops/configmap.go index 4a1016c4d15..da21ef2174b 100644 --- a/pkg/controller/autoops/configmap.go +++ b/pkg/controller/autoops/configmap.go @@ -20,6 +20,7 @@ import ( "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/certificates" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/metadata" "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler" + "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/settings" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/k8s" "github.com/elastic/cloud-on-k8s/v3/pkg/utils/maps" ) @@ -172,6 +173,30 @@ func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1. return corev1.ConfigMap{}, err } + // Parse the template-rendered YAML into a CanonicalConfig + baseConfig, err := settings.ParseConfig(configBuf.Bytes()) + if err != nil { + return corev1.ConfigMap{}, fmt.Errorf("failed to parse template config: %w", err) + } + + // Parse user-provided config if specified + if policy.Spec.Config != nil { + userConfig, err := settings.NewCanonicalConfigFrom(policy.Spec.Config.Data) + if err != nil { + return corev1.ConfigMap{}, fmt.Errorf("failed to parse user config: %w", err) + } + // Merge user config with base config (user config takes precedence) + if err := baseConfig.MergeWith(userConfig); err != nil { + return corev1.ConfigMap{}, fmt.Errorf("failed to merge user config: %w", err) + } + } + + // Render the merged config back to YAML + finalConfigBytes, err := baseConfig.Render() + if err != nil { + return corev1.ConfigMap{}, fmt.Errorf("failed to render final config: %w", err) + } + // Use ES-specific ConfigMap name to allow per-ES configuration configMapName := autoopsv1alpha1.Config(policy.GetName(), es) @@ -183,7 +208,7 @@ func buildAutoOpsESConfigMap(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1. Annotations: meta.Annotations, }, Data: map[string]string{ - autoOpsESConfigFileName: configBuf.String(), + autoOpsESConfigFileName: string(finalConfigBytes), }, }, nil } diff --git a/pkg/controller/autoops/controller.go b/pkg/controller/autoops/controller.go index ce232c4edb9..d1fe3312d69 100644 --- a/pkg/controller/autoops/controller.go +++ b/pkg/controller/autoops/controller.go @@ -263,7 +263,7 @@ func (r *AgentPolicyReconciler) onDelete(ctx context.Context, obj types.Namespac func (r *AgentPolicyReconciler) reconcileWatches(policy autoopsv1alpha1.AutoOpsAgentPolicy) error { watcher := k8s.ExtractNamespacedName(&policy) - secretNames := []string{policy.Spec.Config.SecretRef.SecretName} + secretNames := []string{policy.Spec.ConfigRef.SecretRef.SecretName} // Set up dynamic watches for referenced secrets return watches.WatchUserProvidedSecrets( diff --git a/pkg/controller/autoops/expected.go b/pkg/controller/autoops/expected.go index 01f3f36369f..0e65059e60a 100644 --- a/pkg/controller/autoops/expected.go +++ b/pkg/controller/autoops/expected.go @@ -173,7 +173,7 @@ func buildConfigHash(ctx context.Context, c k8s.Client, policy autoopsv1alpha1.A } // Hash secret values from autoops-secret - autoopsSecretNSN := types.NamespacedName{Namespace: policy.GetNamespace(), Name: policy.Spec.Config.SecretRef.SecretName} + autoopsSecretNSN := types.NamespacedName{Namespace: policy.GetNamespace(), Name: policy.Spec.ConfigRef.SecretRef.SecretName} var autoopsSecret corev1.Secret if err := c.Get(ctx, autoopsSecretNSN, &autoopsSecret); err != nil { return "", fmt.Errorf("failed to get autoops configuration secret %s: %w", autoopsSecretNSN.String(), err) @@ -217,7 +217,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: policy.Spec.Config.SecretRef.SecretName, + Name: policy.Spec.ConfigRef.SecretRef.SecretName, }, Key: "autoops-token", }, @@ -232,7 +232,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: policy.Spec.Config.SecretRef.SecretName, + Name: policy.Spec.ConfigRef.SecretRef.SecretName, }, Key: "autoops-otel-url", }, @@ -255,7 +255,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: policy.Spec.Config.SecretRef.SecretName, + Name: policy.Spec.ConfigRef.SecretRef.SecretName, }, Key: "cloud-connected-mode-api-key", }, @@ -266,7 +266,7 @@ func autoopsEnvVars(policy autoopsv1alpha1.AutoOpsAgentPolicy, es esv1.Elasticse ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: policy.Spec.Config.SecretRef.SecretName, + Name: policy.Spec.ConfigRef.SecretRef.SecretName, }, Key: "cloud-connected-mode-api-url", Optional: ptr.To(true), diff --git a/pkg/controller/autoops/expected_test.go b/pkg/controller/autoops/expected_test.go index 756f7d6a7dd..62f10178303 100644 --- a/pkg/controller/autoops/expected_test.go +++ b/pkg/controller/autoops/expected_test.go @@ -33,7 +33,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0-SNAPSHOT", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "autoops-secret", }, @@ -85,7 +85,7 @@ func TestReconcileAutoOpsAgentPolicy_deploymentParams(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "invalid-version", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "autoops-secret", }, @@ -389,7 +389,7 @@ func Test_autoopsEnvVars(t *testing.T) { Namespace: "ns-2", }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "autoops-secret", }, diff --git a/pkg/controller/autoops/reconcile.go b/pkg/controller/autoops/reconcile.go index 3d5913774aa..f1e14588062 100644 --- a/pkg/controller/autoops/reconcile.go +++ b/pkg/controller/autoops/reconcile.go @@ -65,9 +65,9 @@ func (r *AgentPolicyReconciler) internalReconcile( if err := validateConfigSecret(ctx, r.Client, types.NamespacedName{ Namespace: policy.Namespace, - Name: policy.Spec.Config.SecretRef.SecretName, + Name: policy.Spec.ConfigRef.SecretRef.SecretName, }); err != nil { - log.Error(err, "Error validating configuration secret", "namespace", policy.Namespace, "name", policy.Spec.Config.SecretRef.SecretName) + log.Error(err, "Error validating configuration secret", "namespace", policy.Namespace, "name", policy.Spec.ConfigRef.SecretRef.SecretName) state.UpdateWithPhase(autoopsv1alpha1.ErrorPhase) return results.WithError(err) } diff --git a/pkg/controller/autoops/reconcile_test.go b/pkg/controller/autoops/reconcile_test.go index 5181f818492..cf102e7db47 100644 --- a/pkg/controller/autoops/reconcile_test.go +++ b/pkg/controller/autoops/reconcile_test.go @@ -51,7 +51,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "missing-secret", }, @@ -76,7 +76,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "invalid-secret", }, @@ -109,7 +109,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -152,7 +152,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -190,7 +190,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -239,7 +239,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -298,7 +298,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -368,7 +368,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, @@ -460,7 +460,7 @@ func TestAutoOpsAgentPolicyReconciler_internalReconcile(t *testing.T) { }, Spec: autoopsv1alpha1.AutoOpsAgentPolicySpec{ Version: "9.1.0", - Config: commonv1.ConfigSource{ + ConfigRef: commonv1.ConfigSource{ SecretRef: commonv1.SecretRef{ SecretName: "config-secret", }, From a8b69ae3bcdc60f3268efd96d3a044d5af2938e4 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 16:28:19 -0600 Subject: [PATCH 89/90] make generate Signed-off-by: Michael Montgomery --- config/crds/v1/all-crds.yaml | 9 ++++++++- .../autoops.k8s.elastic.co_autoopsagentpolicies.yaml | 9 ++++++++- .../charts/eck-operator-crds/templates/all-crds.yaml | 9 ++++++++- docs/reference/api-reference/main.md | 4 +++- pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go | 6 +++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index e613a2a236d..2b2d751bc73 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2410,7 +2410,7 @@ spec: properties: config: description: |- - Config holds the AutoOpsAgentPolicy configuration. + ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: kind: Secret apiVersion: v1 @@ -2425,6 +2425,13 @@ spec: description: SecretName is the name of the secret. type: string type: object + esConfig: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 2a4a239782c..01a97677ffa 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -56,7 +56,7 @@ spec: properties: config: description: |- - Config holds the AutoOpsAgentPolicy configuration. + ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: kind: Secret apiVersion: v1 @@ -71,6 +71,13 @@ spec: description: SecretName is the name of the secret. type: string type: object + esConfig: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index ae5d35bc8ff..9c6114ed609 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2431,7 +2431,7 @@ spec: properties: config: description: |- - Config holds the AutoOpsAgentPolicy configuration. + ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: kind: Secret apiVersion: v1 @@ -2446,6 +2446,13 @@ spec: description: SecretName is the name of the secret. type: string type: object + esConfig: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index f592e1e4e6b..426a5b3b25d 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -293,7 +293,8 @@ AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes | --- | --- | | *`version`* __string__ | Version of the AutoOpsAgentPolicy. | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | -| *`config`* __[ConfigSource](#configsource)__ | Config holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`config`* __[ConfigSource](#configsource)__ | ConfigRef holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`esConfig`* __[Config](#config)__ | Config holds the AutoOps agent configuration for Elasticsearch monitoring.
This configuration is intended to override parts of the autoops_es.yml configmap.
See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml | | *`image`* __string__ | Image is the AutoOps Agent Docker image to deploy. | | *`podTemplate`* __[PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#podtemplatespec-v1-core)__ | PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods | | *`revisionHistoryLimit`* __integer__ | RevisionHistoryLimit is the number of revisions to retain to allow rollback in the underlying Deployment. | @@ -454,6 +455,7 @@ Config represents untyped YAML configuration. :::{admonition} Appears In: * [AgentSpec](#agentspec) * [ApmServerSpec](#apmserverspec) +* [AutoOpsAgentPolicySpec](#autoopsagentpolicyspec) * [BeatSpec](#beatspec) * [ElasticsearchConfigPolicySpec](#elasticsearchconfigpolicyspec) * [EnterpriseSearchSpec](#enterprisesearchspec) diff --git a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go index 5ccb76348a9..5deddbc3718 100644 --- a/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/autoops/v1alpha1/zz_generated.deepcopy.go @@ -75,7 +75,11 @@ func (in *AutoOpsAgentPolicyList) DeepCopyObject() runtime.Object { func (in *AutoOpsAgentPolicySpec) DeepCopyInto(out *AutoOpsAgentPolicySpec) { *out = *in in.ResourceSelector.DeepCopyInto(&out.ResourceSelector) - out.Config = in.Config + out.ConfigRef = in.ConfigRef + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = (*in).DeepCopy() + } in.PodTemplate.DeepCopyInto(&out.PodTemplate) if in.RevisionHistoryLimit != nil { in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit From 1dd58b8e4b10d4b9b6e168a6d6d18505f9949a17 Mon Sep 17 00:00:00 2001 From: Michael Montgomery Date: Fri, 12 Dec 2025 22:10:38 -0600 Subject: [PATCH 90/90] Fix json tags Signed-off-by: Michael Montgomery --- config/crds/v1/all-crds.yaml | 14 +++++++------- ...utoops.k8s.elastic.co_autoopsagentpolicies.yaml | 14 +++++++------- .../eck-operator-crds/templates/all-crds.yaml | 14 +++++++------- docs/reference/api-reference/main.md | 4 ++-- .../autoops/v1alpha1/autoopsagentpolicy_types.go | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/config/crds/v1/all-crds.yaml b/config/crds/v1/all-crds.yaml index 2b2d751bc73..e8b2284a1e2 100644 --- a/config/crds/v1/all-crds.yaml +++ b/config/crds/v1/all-crds.yaml @@ -2409,6 +2409,13 @@ spec: spec: properties: config: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: description: |- ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: @@ -2425,13 +2432,6 @@ spec: description: SecretName is the name of the secret. type: string type: object - esConfig: - description: |- - Config holds the AutoOps agent configuration for Elasticsearch monitoring. - This configuration is intended to override parts of the autoops_es.yml configmap. - See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml - type: object - x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml index 01a97677ffa..1a519229959 100644 --- a/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml +++ b/config/crds/v1/resources/autoops.k8s.elastic.co_autoopsagentpolicies.yaml @@ -55,6 +55,13 @@ spec: spec: properties: config: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: description: |- ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: @@ -71,13 +78,6 @@ spec: description: SecretName is the name of the secret. type: string type: object - esConfig: - description: |- - Config holds the AutoOps agent configuration for Elasticsearch monitoring. - This configuration is intended to override parts of the autoops_es.yml configmap. - See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml - type: object - x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml index 9c6114ed609..31bb8c3adb7 100644 --- a/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml +++ b/deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml @@ -2430,6 +2430,13 @@ spec: spec: properties: config: + description: |- + Config holds the AutoOps agent configuration for Elasticsearch monitoring. + This configuration is intended to override parts of the autoops_es.yml configmap. + See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml + type: object + x-kubernetes-preserve-unknown-fields: true + configRef: description: |- ConfigRef holds the AutoOpsAgentPolicy configuration. The contents of the referenced secret requires the following format: @@ -2446,13 +2453,6 @@ spec: description: SecretName is the name of the secret. type: string type: object - esConfig: - description: |- - Config holds the AutoOps agent configuration for Elasticsearch monitoring. - This configuration is intended to override parts of the autoops_es.yml configmap. - See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml - type: object - x-kubernetes-preserve-unknown-fields: true image: description: Image is the AutoOps Agent Docker image to deploy. type: string diff --git a/docs/reference/api-reference/main.md b/docs/reference/api-reference/main.md index 426a5b3b25d..e22e95d8730 100644 --- a/docs/reference/api-reference/main.md +++ b/docs/reference/api-reference/main.md @@ -293,8 +293,8 @@ AutoOpsAgentPolicy represents an Elastic AutoOps Policy resource in a Kubernetes | --- | --- | | *`version`* __string__ | Version of the AutoOpsAgentPolicy. | | *`resourceSelector`* __[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#labelselector-v1-meta)__ | ResourceSelector is a label selector for the resources to be configured.
Any Elasticsearch instances that match the selector will be configured to send data to AutoOps. | -| *`config`* __[ConfigSource](#configsource)__ | ConfigRef holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | -| *`esConfig`* __[Config](#config)__ | Config holds the AutoOps agent configuration for Elasticsearch monitoring.
This configuration is intended to override parts of the autoops_es.yml configmap.
See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml | +| *`configRef`* __[ConfigSource](#configsource)__ | ConfigRef holds the AutoOpsAgentPolicy configuration.
The contents of the referenced secret requires the following format:
kind: Secret
apiVersion: v1
metadata:
name: autoops-agent-policy-config
stringData:
ccmApiKey: aslkfjsldkjfslkdjflksdjfl
autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co
autoOpsToken: skdfjdskjf | +| *`config`* __[Config](#config)__ | Config holds the AutoOps agent configuration for Elasticsearch monitoring.
This configuration is intended to override parts of the autoops_es.yml configmap.
See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml | | *`image`* __string__ | Image is the AutoOps Agent Docker image to deploy. | | *`podTemplate`* __[PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#podtemplatespec-v1-core)__ | PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the Agent pods | | *`revisionHistoryLimit`* __integer__ | RevisionHistoryLimit is the number of revisions to retain to allow rollback in the underlying Deployment. | diff --git a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go index ea050591bbc..73c1a9e520d 100644 --- a/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go +++ b/pkg/apis/autoops/v1alpha1/autoopsagentpolicy_types.go @@ -63,12 +63,12 @@ type AutoOpsAgentPolicySpec struct { // ccmApiKey: aslkfjsldkjfslkdjflksdjfl // autoOpsOTelURL: https://otel.auto-ops.console.qa.cld.elstc.co // autoOpsToken: skdfjdskjf - ConfigRef commonv1.ConfigSource `json:"config,omitempty"` + ConfigRef commonv1.ConfigSource `json:"configRef,omitempty"` // Config holds the AutoOps agent configuration for Elasticsearch monitoring. // This configuration is intended to override parts of the autoops_es.yml configmap. // See: https://github.com/elastic/elastic-agent/blob/c6eaa3c903d4357824d345ee2002123fdffbec91/internal/pkg/otel/samples/linux/autoops_es.yml // +kubebuilder:pruning:PreserveUnknownFields - Config *commonv1.Config `json:"esConfig,omitempty"` + Config *commonv1.Config `json:"config,omitempty"` // AutoOpsRef is a reference to an AutoOps instance running in the same Kubernetes cluster. // (TODO) AutoOpsRef is not yet implemented. // AutoOpsRef commonv1.ObjectSelector `json:"autoOpsRef,omitempty"`