Skip to content

Commit

Permalink
Introduce ClusterBundle API as a copy of Bundle
Browse files Browse the repository at this point in the history
Signed-off-by: Erik Godding Boye <[email protected]>
  • Loading branch information
erikgb committed Dec 14, 2024
1 parent 31fa3a2 commit 286c98b
Show file tree
Hide file tree
Showing 8 changed files with 1,569 additions and 0 deletions.

Large diffs are not rendered by default.

441 changes: 441 additions & 0 deletions deploy/crds/trust-manager.io_clusterbundles.yaml

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions pkg/api/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

const GroupName = "trust-manager.io"
19 changes: 19 additions & 0 deletions pkg/api/v1alpha1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// +kubebuilder:object:generate=true
// +groupName=trust-manager.io
package v1alpha1
69 changes: 69 additions & 0 deletions pkg/api/v1alpha1/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes/scheme"

"github.com/cert-manager/trust-manager/pkg/api"
)

// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: api.GroupName, Version: "v1alpha1"}

// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

var (
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme

GlobalScheme *runtime.Scheme
)

func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)

GlobalScheme = runtime.NewScheme()
if err := scheme.AddToScheme(GlobalScheme); err != nil {
panic(fmt.Sprintf("failed to add k8s.io scheme: %s", err))
}
if err := AddToScheme(GlobalScheme); err != nil {
panic(fmt.Sprintf("failed to add trust-manager.io scheme: %s", err))
}
}

// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ClusterBundle{},
&ClusterBundleList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
268 changes: 268 additions & 0 deletions pkg/api/v1alpha1/types_cluster_bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var ClusterBundleKind = "ClusterBundle"

var BundleLabelKey = "trust-manager.io/bundle"
var BundleHashAnnotationKey = "trust-manager.io/hash"

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="ConfigMap Target",type="string",JSONPath=".spec.target.configMap.key",description="Bundle ConfigMap Target Key"
// +kubebuilder:printcolumn:name="Secret Target",type="string",JSONPath=".spec.target.secret.key",description="Bundle Secret Target Key"
// +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=`.status.conditions[?(@.type == "Synced")].status`,description="Bundle has been synced"
// +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=`.status.conditions[?(@.type == "Synced")].reason`,description="Reason Bundle has Synced status"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Timestamp Bundle was created"
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// +genclient
// +genclient:nonNamespaced

type ClusterBundle struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// Desired state of the Bundle resource.
Spec BundleSpec `json:"spec"`

// Status of the Bundle. This is set and managed automatically.
// +optional
Status BundleStatus `json:"status"`
}

// +kubebuilder:object:root=true
type ClusterBundleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`

Items []ClusterBundle `json:"items"`
}

// BundleSpec defines the desired state of a Bundle.
type BundleSpec struct {
// Sources is a set of references to data whose data will sync to the target.
// +listType=atomic
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=100
Sources []BundleSource `json:"sources"`

// Target is the target location in all namespaces to sync source data to.
Target BundleTarget `json:"target"`
}

// BundleSource is the set of sources whose data will be appended and synced to
// the BundleTarget in all Namespaces.
// +structType=atomic
type BundleSource struct {
// ConfigMap is a reference (by name) to a ConfigMap's `data` key(s), or to a
// list of ConfigMap's `data` key(s) using label selector, in the trust Namespace.
// +optional
ConfigMap *SourceObjectKeySelector `json:"configMap,omitempty"`

// Secret is a reference (by name) to a Secret's `data` key(s), or to a
// list of Secret's `data` key(s) using label selector, in the trust Namespace.
// +optional
Secret *SourceObjectKeySelector `json:"secret,omitempty"`

// InLine is a simple string to append as the source data.
// +optional
InLine *string `json:"inLine,omitempty"`

// UseDefaultCAs, when true, requests the default CA bundle to be used as a source.
// Default CAs are available if trust-manager was installed via Helm
// or was otherwise set up to include a package-injecting init container by using the
// "--default-package-location" flag when starting the trust-manager controller.
// If default CAs were not configured at start-up, any request to use the default
// CAs will fail.
// The version of the default CA package which is used for a Bundle is stored in the
// defaultCAPackageVersion field of the Bundle's status field.
// +optional
UseDefaultCAs *bool `json:"useDefaultCAs,omitempty"`
}

// BundleTarget is the target resource that the Bundle will sync all source
// data to.
type BundleTarget struct {
// ConfigMap is the target ConfigMap in Namespaces that all Bundle source
// data will be synced to.
// +optional
ConfigMap *KeySelector `json:"configMap,omitempty"`

// Secret is the target Secret that all Bundle source data will be synced to.
// Using Secrets as targets is only supported if enabled at trust-manager startup.
// By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace.
// +optional
Secret *KeySelector `json:"secret,omitempty"`

// AdditionalFormats specifies any additional formats to write to the target
// +optional
AdditionalFormats *AdditionalFormats `json:"additionalFormats,omitempty"`

// NamespaceSelector will, if set, only sync the target resource in
// Namespaces which match the selector.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
}

// AdditionalFormats specifies any additional formats to write to the target
type AdditionalFormats struct {
// JKS requests a JKS-formatted binary trust bundle to be written to the target.
// The bundle has "changeit" as the default password.
// For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords
// +optional
JKS *JKS `json:"jks,omitempty"`
// PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target.
// The bundle is by default created without a password.
// +optional
PKCS12 *PKCS12 `json:"pkcs12,omitempty"`
}

// JKS specifies additional target JKS files
// +structType=atomic
type JKS struct {
KeySelector `json:",inline"`

// Password for JKS trust store
//+optional
//+kubebuilder:validation:MinLength=1
//+kubebuilder:validation:MaxLength=128
//+kubebuilder:default=changeit
Password *string `json:"password"`
}

// PKCS12 specifies additional target PKCS#12 files
// +structType=atomic
type PKCS12 struct {
KeySelector `json:",inline"`

// Password for PKCS12 trust store
//+optional
//+kubebuilder:validation:MaxLength=128
//+kubebuilder:default=""
Password *string `json:"password,omitempty"`
}

// SourceObjectKeySelector is a reference to a source object and its `data` key(s)
// in the trust Namespace.
// +structType=atomic
type SourceObjectKeySelector struct {
// Name is the name of the source object in the trust Namespace.
// This field must be left empty when `selector` is set
//+optional
// +kubebuilder:validation:MinLength=1
Name string `json:"name,omitempty"`

// Selector is the label selector to use to fetch a list of objects. Must not be set
// when `Name` is set.
//+optional
Selector *metav1.LabelSelector `json:"selector,omitempty"`

// Key of the entry in the object's `data` field to be used.
//+optional
// +kubebuilder:validation:MinLength=1
Key string `json:"key,omitempty"`

// IncludeAllKeys is a flag to include all keys in the object's `data` field to be used. False by default.
// This field must not be true when `Key` is set.
//+optional
IncludeAllKeys bool `json:"includeAllKeys,omitempty"`
}

// KeySelector is a reference to a key for some map data object.
type KeySelector struct {
// Key is the key of the entry in the object's `data` field to be used.
// +kubebuilder:validation:MinLength=1
Key string `json:"key"`
}

// BundleStatus defines the observed state of the Bundle.
type BundleStatus struct {
// List of status conditions to indicate the status of the Bundle.
// Known condition types are `Bundle`.
// +listType=map
// +listMapKey=type
// +optional
Conditions []BundleCondition `json:"conditions,omitempty"`

// DefaultCAPackageVersion, if set and non-empty, indicates the version information
// which was retrieved when the set of default CAs was requested in the bundle
// source. This should only be set if useDefaultCAs was set to "true" on a source,
// and will be the same for the same version of a bundle with identical certificates.
// +optional
DefaultCAPackageVersion *string `json:"defaultCAVersion,omitempty"`
}

// BundleCondition contains condition information for a Bundle.
type BundleCondition struct {
// Type of the condition, known values are (`Synced`).
// +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$`
// +kubebuilder:validation:MaxLength=316
Type string `json:"type"`

// Status of the condition, one of True, False, Unknown.
// +kubebuilder:validation:Enum=True;False;Unknown
Status metav1.ConditionStatus `json:"status"`

// LastTransitionTime is the timestamp corresponding to the last status
// change of this condition.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Format=date-time
LastTransitionTime metav1.Time `json:"lastTransitionTime"`

// Reason is a brief machine-readable explanation for the condition's last
// transition.
// The value should be a CamelCase string.
// This field may not be empty.
// +kubebuilder:validation:MaxLength=1024
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$`
Reason string `json:"reason"`

// Message is a human-readable description of the details of the last
// transition, complementing reason.
// +optional
// +kubebuilder:validation:MaxLength=32768
Message string `json:"message,omitempty"`

// If set, this represents the .metadata.generation that the condition was
// set based upon.
// For instance, if .metadata.generation is currently 12, but the
// .status.condition[x].observedGeneration is 9, the condition is out of date
// with respect to the current state of the Bundle.
// +optional
// +kubebuilder:validation:Minimum=0
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

const (
// DefaultJKSPassword is the default password that Java uses; it's a Java convention to use this exact password.
// Since we're not storing anything secret in the JKS files we generate, this password is not a meaningful security measure
// but seems often to be expected by applications consuming JKS files
DefaultJKSPassword = "changeit"
// DefaultPKCS12Password is the empty string, that will create a password-less PKCS12 truststore.
// Password-less PKCS is the new default Java truststore from Java 18.
// By password-less, it means the certificates are not encrypted, and it contains no MacData for integrity check.
DefaultPKCS12Password = ""

// BundleConditionSynced indicates that the Bundle has successfully synced
// all source bundle data to the Bundle target in all Namespaces.
BundleConditionSynced string = "Synced"
)
Loading

0 comments on commit 286c98b

Please sign in to comment.