Skip to content

Commit

Permalink
operator: changes to support multiple api versions
Browse files Browse the repository at this point in the history
By moving the core deployment API fields that are expected to be
supported by all future API versions, we could minimize the code
duplication. Hence moved such fields into the `base` package that
supposed to inherited by all the API versions.

Made '{Controller,Node}Resources' specific to v1alpha1 api as upcoming
v1beta1 version plans to deprecate them in favour of container specific
resources.
  • Loading branch information
avalluri committed Nov 14, 2020
1 parent 486a9fc commit 9b39142
Show file tree
Hide file tree
Showing 25 changed files with 657 additions and 544 deletions.
6 changes: 3 additions & 3 deletions deploy/yamls.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"fmt"
"regexp"

api "github.com/intel/pmem-csi/pkg/apis/pmemcsi/v1alpha1"
"github.com/intel/pmem-csi/pkg/apis/pmemcsi/base"
"github.com/intel/pmem-csi/pkg/version"
)

Expand All @@ -29,7 +29,7 @@ type YamlFile struct {

// DeviceMode defines in which mode the deployed driver will
// operate.
DeviceMode api.DeviceMode
DeviceMode base.DeviceMode
}

var yamls []YamlFile
Expand All @@ -50,7 +50,7 @@ func init() {
Name: file,
Kubernetes: kubernetes,
Flavor: parts[3],
DeviceMode: api.DeviceMode(parts[3]),
DeviceMode: base.DeviceMode(parts[3]),
})
}
}
Expand Down
291 changes: 291 additions & 0 deletions pkg/apis/pmemcsi/base/base_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
/*
Copyright 2020 The Kubernetes Authors.
SPDX-License-Identifier: Apache-2.0
*/

package base

import (
"errors"
"fmt"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// DeviceMode type decleration for allowed driver device managers
type DeviceMode string

// +kubebuilder:validation:Enum=lvm,direct
const (
// DeviceModeLVM represents 'lvm' device manager
DeviceModeLVM DeviceMode = "lvm"
// DeviceModeDirect represents 'direct' device manager
DeviceModeDirect DeviceMode = "direct"
// DeviceModeFake represents a device manager for testing:
// volume creation and deletion is just recorded in memory,
// without any actual backing store. Such fake volumes cannot
// be used for pods.
DeviceModeFake DeviceMode = "fake"
)

// Set sets the value
func (mode *DeviceMode) Set(value string) error {
switch value {
case string(DeviceModeLVM), string(DeviceModeDirect), string(DeviceModeFake):
*mode = DeviceMode(value)
case "ndctl":
// For backwards-compatibility.
*mode = DeviceModeDirect
default:
return errors.New("invalid device manager mode")
}
return nil
}

func (mode *DeviceMode) String() string {
return string(*mode)
}

// DriverType type decleration for representing the type of driver instance
type DriverType int

const (
// ControllerDriver represents controller driver instance
ControllerDriver DriverType = iota
// NodeDriver represents driver instance running on worker nodes
NodeDriver
)

func (t DriverType) String() string {
switch t {
case ControllerDriver:
return "Controller"
case NodeDriver:
return "Node"
}
return ""
}

// NOTE(avalluri): Due to below errors we stop setting
// few CRD schema fields by prefixing those lines a '-'.
// Once the below issues go fixed replace those '-' with '+'
// Setting default(+kubebuilder:default=value) for v1beta1 CRD fails, only supports since v1 CRD.
// Related issue : https://github.com/kubernetes-sigs/controller-tools/issues/478
// Fails setting min/max for integers: https://github.com/helm/helm/issues/5806

// DeploymentSpec defines the desired state of Deployment
// +k8s:deepcopy-gen=true
type DeploymentSpec struct {
// Important: Run "make operator-generate-k8s" to regenerate code after modifying this file

// PMEM-CSI driver container image
Image string `json:"image,omitempty"`
// PullPolicy image pull policy one of Always, Never, IfNotPresent
PullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
// ProvisionerImage CSI provisioner sidecar image
ProvisionerImage string `json:"provisionerImage,omitempty"`
// NodeRegistrarImage CSI node driver registrar sidecar image
NodeRegistrarImage string `json:"nodeRegistrarImage,omitempty"`
// DeviceMode to use to manage PMEM devices. One of lvm, direct
// +kubebuilder:default:lvm
DeviceMode DeviceMode `json:"deviceMode,omitempty"`
// LogLevel number for the log verbosity
// +kubebuilder:validation:Required
// kubebuilder:default=3
LogLevel uint16 `json:"logLevel,omitempty"`
// RegistryCert encoded certificate signed by a CA for registry server authentication
// If not provided, provisioned one by the operator using self-signed CA
RegistryCert []byte `json:"registryCert,omitempty"`
// RegistryPrivateKey encoded private key used for registry server certificate
// If not provided, provisioned one by the operator
RegistryPrivateKey []byte `json:"registryKey,omitempty"`
// NodeControllerCert encoded certificate signed by a CA for node controller server authentication
// If not provided, provisioned one by the operator using self-signed CA
NodeControllerCert []byte `json:"nodeControllerCert,omitempty"`
// NodeControllerPrivateKey encoded private key used for node controller server certificate
// If not provided, provisioned one by the operator
NodeControllerPrivateKey []byte `json:"nodeControllerKey,omitempty"`
// CACert encoded root certificate of the CA by which the registry and node controller certificates are signed
// If not provided operator uses a self-signed CA certificate
CACert []byte `json:"caCert,omitempty"`
// NodeSelector node labels to use for selection of driver node
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// PMEMPercentage represents the percentage of space to be used by the driver in each PMEM region
// on every node.
// This is only valid for driver in LVM mode.
// +kubebuilder:validation:Required
// -kubebuilder:validation:Minimum=1
// -kubebuilder:validation:Maximum=100
// -kubebuilder:default=100
PMEMPercentage uint16 `json:"pmemPercentage,omitempty"`
// Labels contains additional labels for all objects created by the operator.
Labels map[string]string `json:"labels,omitempty"`
// KubeletDir kubelet's root directory path
KubeletDir string `json:"kubeletDir,omitempty"`
}

const (
// EventReasonNew new driver deployment found
EventReasonNew = "NewDeployment"
// EventReasonRunning driver has been successfully deployed
EventReasonRunning = "Running"
// EventReasonFailed driver deployment failed, Event.Message holds detailed information
EventReasonFailed = "Failed"
)

// DeploymentPhase represents the status phase of a driver deployment
type DeploymentPhase string

const (
// DeploymentPhaseNew indicates a new deployment
DeploymentPhaseNew DeploymentPhase = ""
// DeploymentPhaseRunning indicates that the deployment was successful
DeploymentPhaseRunning DeploymentPhase = "Running"
// DeploymentPhaseFailed indicates that the deployment was failed
DeploymentPhaseFailed DeploymentPhase = "Failed"
)

// DeploymentConditionType type for representing a deployment status condition
type DeploymentConditionType string

const (
// CertsVerified means the provided deployment secrets are verified and valid for usage
CertsVerified DeploymentConditionType = "CertsVerified"
// CertsReady means secrests/certificates required for running the PMEM-CSI driver
// are ready and the deployment could progress further
CertsReady DeploymentConditionType = "CertsReady"
// DriverDeployed means that the all the sub-resources required for the deployment CR
// got created
DriverDeployed DeploymentConditionType = "DriverDeployed"
)

// DeploymentCondition type definition for driver deployment status conditions
// +k8s:deepcopy-gen=true
type DeploymentCondition struct {
// Type of condition.
Type DeploymentConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status corev1.ConditionStatus `json:"status"`
// Message human readable text that explain why this condition is in this state
// +optional
Reason string `json:"reason,omitempty"`
// Last time the condition was probed.
// +optional
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
}

// DriverStatus type definition for representing deployed driver status
// +k8s:deepcopy-gen=true
type DriverStatus struct {
// DriverComponent represents type of the driver: controller or node
DriverComponent string `json:"component"`
// Status represents the state of the component; one of `Ready` or `NotReady`.
// Component becomes `Ready` if all the instances(Pods) of the driver component
// are in running state. Otherwise, `NotReady`.
Status string `json:"status"`
// Reason represents the human readable text that explains why the
// driver is in this state.
Reason string `json:"reason"`
// LastUpdated time of the driver status
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
}

// DeploymentStatus defines the observed state of Deployment
// +k8s:deepcopy-gen=true
type DeploymentStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make operator-generate-k8s" to regenerate code after modifying this file

// Phase indicates the state of the deployment
Phase DeploymentPhase `json:"phase,omitempty"`
Reason string `json:"reason,omitempty"`
// Conditions
Conditions []DeploymentCondition `json:"conditions,omitempty"`
Components []DriverStatus `json:"driverComponents,omitempty"`
// LastUpdated time of the deployment status
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
}

// SetDriverStatus set/updates the deployment status for given driver component
func (s *DeploymentStatus) SetDriverStatus(t DriverType, status, reason string) {
if s.Components == nil {
s.Components = make([]DriverStatus, 2)
}
s.Components[t] = DriverStatus{
DriverComponent: t.String(),
Status: status,
Reason: reason,
LastUpdated: metav1.Now(),
}
}

// SetCondition set/updates the deployment status condition
func (s *DeploymentStatus) SetCondition(t DeploymentConditionType, state corev1.ConditionStatus, reason string) {
for _, c := range s.Conditions {
if c.Type == t {
c.Status = state
c.Reason = reason
c.LastUpdateTime = metav1.Now()
return
}
}
s.Conditions = append(s.Conditions, DeploymentCondition{
Type: t,
Status: state,
Reason: reason,
LastUpdateTime: metav1.Now(),
})
}

// EnsureDefaults make sure that the deployment object has all defaults set properly
func (spec *DeploymentSpec) EnsureDefaults(operatorImage string) error {
// Validate the given driver mode.
// In a realistic case this check might not needed as it should be
// handled by JSON schema as we defined deviceMode as enumeration.
switch spec.DeviceMode {
case "":
spec.DeviceMode = DefaultDeviceMode
case DeviceModeDirect, DeviceModeLVM:
default:
return fmt.Errorf("invalid device mode %q", spec.DeviceMode)
}

if spec.Image == "" {
// If provided use operatorImage
if operatorImage != "" {
spec.Image = operatorImage
} else {
spec.Image = DefaultDriverImage
}
}
if spec.PullPolicy == "" {
spec.PullPolicy = DefaultImagePullPolicy
}
if spec.LogLevel == 0 {
spec.LogLevel = DefaultLogLevel
}

if spec.ProvisionerImage == "" {
spec.ProvisionerImage = DefaultProvisionerImage
}

if spec.NodeRegistrarImage == "" {
spec.NodeRegistrarImage = DefaultRegistrarImage
}

if spec.NodeSelector == nil {
spec.NodeSelector = DefaultNodeSelector
}

if spec.PMEMPercentage == 0 {
spec.PMEMPercentage = DefaultPMEMPercentage
}

if spec.KubeletDir == "" {
spec.KubeletDir = DefaultKubeletDir
}

return nil
}
57 changes: 57 additions & 0 deletions pkg/apis/pmemcsi/base/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright 2020 The Kubernetes Authors.
SPDX-License-Identifier: Apache-2.0
*/

package base

import (
corev1 "k8s.io/api/core/v1"
)

const (
// DefaultLogLevel default logging level used for the driver
DefaultLogLevel = uint16(5)
// DefaultImagePullPolicy default image pull policy for all the images used by the deployment
DefaultImagePullPolicy = corev1.PullIfNotPresent

defaultDriverImageName = "intel/pmem-csi-driver"
defaultDriverImageTag = "canary"
// DefaultDriverImage default PMEM-CSI driver docker image
DefaultDriverImage = defaultDriverImageName + ":" + defaultDriverImageTag

// The sidecar versions must be kept in sync with the
// deploy/kustomize YAML files!

defaultProvisionerImageName = "k8s.gcr.io/sig-storage/csi-provisioner"
defaultProvisionerImageTag = "v2.0.2"
// DefaultProvisionerImage default external provisioner image to use
DefaultProvisionerImage = defaultProvisionerImageName + ":" + defaultProvisionerImageTag

defaultRegistrarImageName = "k8s.gcr.io/sig-storage/csi-node-driver-registrar"
defaultRegistrarImageTag = "v1.2.0"
// DefaultRegistrarImage default node driver registrar image to use
DefaultRegistrarImage = defaultRegistrarImageName + ":" + defaultRegistrarImageTag

// DefaultControllerResourceLimitCPU default CPU resource limit used for controller driver container
DefaultControllerResourceLimitCPU = "500m" // MilliSeconds
// DefaultControllerResourceLimitMemory default memory resource limit used for controller driver container
DefaultControllerResourceLimitMemory = "250Mi" // MB
// DefaultNodeResourceLimitCPU default CPU resource limit used for node driver container
DefaultNodeResourceLimitCPU = "600m" // MilliSeconds
// DefaultNodeResourceLimitMemory default memory resource limit used for node driver container
DefaultNodeResourceLimitMemory = "500Mi" // MB

// DefaultDeviceMode default device manger used for deployment
DefaultDeviceMode = DeviceModeLVM
// DefaultPMEMPercentage PMEM space to reserve for the driver
DefaultPMEMPercentage = 100
// DefaultKubeletDir default kubelet's path
DefaultKubeletDir = "/var/lib/kubelet"
)

var (
// DefaultNodeSelector default node label used for node selection
DefaultNodeSelector = map[string]string{"storage": "pmem"}
)
11 changes: 11 additions & 0 deletions pkg/apis/pmemcsi/base/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Copyright 2020 The Kubernetes Authors.
SPDX-License-Identifier: Apache-2.0
*/

// Package base contains definitions for types and functions that are
// supposed to shared by all the operator API groups
// +k8s:deepcopy-gen=package,register
// +groupName=pmem-csi.intel.com
package base
Loading

0 comments on commit 9b39142

Please sign in to comment.