Skip to content

Commit

Permalink
Introduce machineConfigServer and nodePool versions
Browse files Browse the repository at this point in the history
In order to have fine grained control over the versioning of nodePools, machines and nodes we want to decouple the machine config server, the ign endpoint and the user data secret giving the ignition endpoint from the controlPlane lifecycle. This will let us have nodePools coexisting at different versions and orchestrate rolling upgrades from an authoritative source of truth.

To that end this PR introduces a new CRD machineConfigServer and introduce the concept of versioning for nodePools. A nodePool always target a release version and generates the appropiate mcs for it to get the right ignition config.
  • Loading branch information
enxebre committed Mar 23, 2021
1 parent 0e7168e commit d98c7a7
Show file tree
Hide file tree
Showing 17 changed files with 1,049 additions and 304 deletions.
51 changes: 51 additions & 0 deletions api/v1alpha1/machineconfigserver_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package v1alpha1

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

func init() {
SchemeBuilder.Register(&MachineConfigServer{}, &MachineConfigServerList{})
}

// MachineConfigServerSpec defines the desired state of MachineConfigServer
type MachineConfigServerSpec struct {

// Release specifies the release image to use for this MachineConfigServer
ReleaseImage string `json:"releaseImage"`
}

// MachineConfigServerStatus defines the observed state of MachineConfigServer
type MachineConfigServerStatus struct {
// Version is the semantic version of the release used by the mcs.
// For a mcs a given version represents the ignition config served by
// the ignition endpoint referenced in the userdata secret.
// +kubebuilder:validation:Optional
Version string `json:"version,omitempty"`

// +kubebuilder:validation:Optional
Host string `json:"host,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=machineconfigservers,shortName=mcs;mcss,scope=Namespaced
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version",description="Version"
// +kubebuilder:printcolumn:name="Host",type="string",JSONPath=".status.host",description="Host"
// MachineConfigServer is the Schema for the MachineConfigServers API
type MachineConfigServer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec MachineConfigServerSpec `json:"spec,omitempty"`
Status MachineConfigServerStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// MachineConfigServerList contains a list of MachineConfigServer
type MachineConfigServerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []MachineConfigServer `json:"items"`
}
11 changes: 7 additions & 4 deletions api/v1alpha1/nodepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const (
NodePoolAutoscalingEnabledConditionType = "AutoscalingEnabled"
NodePoolAsExpectedConditionReason = "AsExpected"
NodePoolValidationFailedConditionReason = "ValidationFailed"
NodePoolUpgradingConditionType = "Upgrading"
)

func init() {
Expand All @@ -24,6 +25,8 @@ func init() {
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".spec.clusterName",description="Cluster"
// +kubebuilder:printcolumn:name="NodeCount",type="integer",JSONPath=".status.nodeCount",description="Available Nodes"
// +kubebuilder:printcolumn:name="Autoscaling",type="string",JSONPath=".status.conditions[?(@.type==\"AutoscalingEnabled\")].status",description="Autoscaling Enabled"
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version",description="Current version"
// +kubebuilder:printcolumn:name="Upgrading",type="string",JSONPath=".status.conditions[?(@.type==\"Upgrading\")].status",description="Upgrade in progress"
type NodePool struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Expand All @@ -46,12 +49,12 @@ type NodePoolSpec struct {
Management NodePoolManagement `json:"nodePoolManagement"`
Platform NodePoolPlatform `json:"platform"`

// Version is the semantic version of the release applied by
// the hosted control plane operator.
// +kubebuilder:validation:Optional
// Release specifies the release image to use for this NodePool
// For a nodePool a given version dictates the ignition config and
// an image artifact e.g an AMI in AWS.
// +kubebuilder:validation:Optional
Version string `json:"version,omitempty"`
// Release specifies the release image to use for this HostedCluster
Release Release `json:"release"`
}

// NodePoolStatus defines the observed state of NodePool
Expand Down
90 changes: 90 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.5.0
creationTimestamp: null
name: machineconfigservers.hypershift.openshift.io
spec:
group: hypershift.openshift.io
names:
kind: MachineConfigServer
listKind: MachineConfigServerList
plural: machineconfigservers
shortNames:
- mcs
- mcss
singular: machineconfigserver
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Version
jsonPath: .status.version
name: Version
type: string
- description: Host
jsonPath: .status.host
name: Host
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: MachineConfigServer is the Schema for the MachineConfigServers API
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:
description: MachineConfigServerSpec defines the desired state of MachineConfigServer
properties:
releaseImage:
description: Release specifies the release image to use for this MachineConfigServer
type: string
required:
- releaseImage
type: object
status:
description: MachineConfigServerStatus defines the observed state of MachineConfigServer
properties:
host:
type: string
version:
description: Version is the semantic version of the release used by the mcs. For a mcs a given version represents the ignition config served by the ignition endpoint referenced in the userdata secret.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ spec:
jsonPath: .status.conditions[?(@.type=="AutoscalingEnabled")].status
name: Autoscaling
type: string
- description: Current version
jsonPath: .status.version
name: Version
type: string
- description: Upgrade in progress
jsonPath: .status.conditions[?(@.type=="Upgrading")].status
name: Upgrading
type: string
name: v1alpha1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -160,9 +168,15 @@ spec:
- instanceType
type: object
type: object
version:
description: Version is the semantic version of the release applied by the hosted control plane operator. For a nodePool a given version dictates the ignition config and an image artifact e.g an AMI in AWS.
type: string
release:
description: Release specifies the release image to use for this NodePool For a nodePool a given version dictates the ignition config and an image artifact e.g an AMI in AWS. Release specifies the release image to use for this HostedCluster
properties:
image:
description: Image is the release image pullspec for the control plane
type: string
required:
- image
type: object
required:
- clusterName
- platform
Expand Down
11 changes: 11 additions & 0 deletions cmd/install/assets/hypershift_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,14 @@ func (o HyperShiftExternalInfraClustersCustomResourceDefinition) Build() *apiext
crd.Labels["cluster.x-k8s.io/v1alpha4"] = "v1alpha1"
return crd
}

type HyperShiftMachineConfigServersCustomResourceDefinition struct{}

func (o HyperShiftMachineConfigServersCustomResourceDefinition) Build() *apiextensionsv1.CustomResourceDefinition {
crd := getCustomResourceDefinition("hypershift-operator/hypershift.openshift.io_machineconfigservers.yaml")
if crd.Labels == nil {
crd.Labels = map[string]string{}
}
crd.Labels["cluster.x-k8s.io/v1alpha4"] = "v1alpha1"
return crd
}
2 changes: 2 additions & 0 deletions cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func hyperShiftOperatorManifests(opts Options) []crclient.Object {
nodePoolsCRD := assets.HyperShiftNodePoolsCustomResourceDefinition{}.Build()
hostedControlPlanesCRD := assets.HyperShiftHostedControlPlaneCustomResourceDefinition{}.Build()
externalInfraClustersCRD := assets.HyperShiftExternalInfraClustersCustomResourceDefinition{}.Build()
machineConfigServersCRD := assets.HyperShiftMachineConfigServersCustomResourceDefinition{}.Build()
operatorNamespace := assets.HyperShiftNamespace{
Name: opts.Namespace,
}.Build()
Expand All @@ -139,6 +140,7 @@ func hyperShiftOperatorManifests(opts Options) []crclient.Object {
nodePoolsCRD,
hostedControlPlanesCRD,
externalInfraClustersCRD,
machineConfigServersCRD,
operatorNamespace,
operatorServiceAccount,
operatorClusterRole,
Expand Down
Loading

0 comments on commit d98c7a7

Please sign in to comment.