Skip to content

Commit

Permalink
feat: report filter status into vgstatus
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobmoellerdev committed Sep 18, 2023
1 parent 3b83b72 commit 3cc0553
Show file tree
Hide file tree
Showing 20 changed files with 722 additions and 297 deletions.
9 changes: 2 additions & 7 deletions api/v1alpha1/lvmcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,8 @@ type Storage struct {
// NodeStatus defines the observed state of the deviceclass on the node
type NodeStatus struct {
// Node is the name of the node
Node string `json:"node,omitempty"`
// Status is the status of the VG on the node
Status VGStatusType `json:"status,omitempty"`
// Reason provides more detail on the VG creation status
Reason string `json:"reason,omitempty"`
// Devices is the list of devices used by the deviceclass
Devices []string `json:"devices,omitempty"`
Node string `json:"node,omitempty"`
VGStatus `json:",inline"`
}

//+kubebuilder:object:root=true
Expand Down
81 changes: 81 additions & 0 deletions api/v1alpha1/lvmvolumegroup_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package v1alpha1

import (
"fmt"

"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

// log is for logging in this package.
var lvmvolumegrouplog = logf.Log.WithName("lvmvolumegroup-webhook")

var _ webhook.Validator = &LVMVolumeGroup{}

//+kubebuilder:webhook:path=/validate-lvm-topolvm-io-v1alpha1-lvmvolumegroup,mutating=false,failurePolicy=fail,sideEffects=None,groups=lvm.topolvm.io,resources=lvmvolumegroups,verbs=create;update,versions=v1alpha1,name=vlvmvolumegroup.kb.io,admissionReviewVersions=v1

func (in *LVMVolumeGroup) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(in).
Complete()
}

func (in *LVMVolumeGroup) ValidateCreate() (warnings admission.Warnings, err error) {
lvmvolumegrouplog.Info("validate create", "name", in.Name)
return in.ValidateUpdate(nil)
}

func (in *LVMVolumeGroup) ValidateUpdate(_ runtime.Object) (warnings admission.Warnings, err error) {
lvmvolumegrouplog.Info("validate update", "name", in.Name)
if err := in.validateDeviceSelector(); err != nil {
return nil, fmt.Errorf(".Spec.DeviceSelector is invalid: %w", err)
}
return nil, nil
}

func (in *LVMVolumeGroup) validateDeviceSelector() error {
selector := in.Spec.DeviceSelector

uniquePaths := make(map[string]bool)
duplicatePaths := make(map[string]bool)

// Check for duplicate required paths
for _, path := range selector.Paths {
if _, exists := uniquePaths[path]; exists {
duplicatePaths[path] = true
continue
}

uniquePaths[path] = true
}

// Check for duplicate optional paths
for _, path := range selector.OptionalPaths {
if _, exists := uniquePaths[path]; exists {
duplicatePaths[path] = true
continue
}

uniquePaths[path] = true
}

// Report any duplicate paths
if len(duplicatePaths) > 0 {
keys := make([]string, 0, len(duplicatePaths))
for k := range duplicatePaths {
keys = append(keys, k)
}

return fmt.Errorf("duplicate device paths found: %v", keys)
}

return nil
}

func (in *LVMVolumeGroup) ValidateDelete() (warnings admission.Warnings, err error) {
lvmvolumegrouplog.Info("validate delete", "name", in.Name)
return []string{}, nil
}
20 changes: 19 additions & 1 deletion api/v1alpha1/lvmvolumegroupnodestatus_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,26 @@ type VGStatus struct {
Status VGStatusType `json:"status,omitempty"`
// Reason provides more detail on the VG creation status
Reason string `json:"reason,omitempty"`
//Devices is the list of devices used by the VG
// Devices is the list of devices used by the VG
Devices []string `json:"devices,omitempty"`
// FilterStatus contains the per node status of applied filters and their respective filtered devices.
// It can be consulted in case the device is not picked up as a device for LVM to use.
FilterStatus *FilterStatus `json:"filterStatus,omitempty"`
}

type FilteredDevice struct {
// Name is a human-readable Identifier for a generic function that is ran on every block devices
// before it is considered by LVMS to be valid and usable.
Name string `json:"name"`
// FilteredReason is the human-readable reason why the device was filtered and could not be used
FilteredReason string `json:"filteredReason"`
}

type FilterStatus struct {
// Registered lists all filters that are run on the node
Registered []string `json:"registered"`
// Devices lists a map that relates all currently filtered devices to the filter that excluded them.
Devices map[string][]FilteredDevice `json:"devices,omitempty"`
}

// LVMVolumeGroupNodeStatusStatus defines the observed state of LVMVolumeGroupNodeStatus
Expand Down
4 changes: 2 additions & 2 deletions api/v1alpha1/webhook_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ var _ = BeforeSuite(func() {
})
Expect(err).NotTo(HaveOccurred())

err = (&LVMCluster{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
Expect((&LVMCluster{}).SetupWebhookWithManager(mgr)).NotTo(HaveOccurred())
Expect((&LVMVolumeGroup{}).SetupWebhookWithManager(mgr)).NotTo(HaveOccurred())

//+kubebuilder:scaffold:webhook

Expand Down
62 changes: 57 additions & 5 deletions api/v1alpha1/zz_generated.deepcopy.go

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

47 changes: 45 additions & 2 deletions bundle/manifests/lvm.topolvm.io_lvmclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,52 @@ spec:
properties:
devices:
description: Devices is the list of devices used by the
deviceclass
VG
items:
type: string
type: array
filterStatus:
description: FilterStatus contains the per node status
of applied filters and their respective filtered devices.
It can be consulted in case the device is not picked
up as a device for LVM to use.
properties:
devices:
additionalProperties:
items:
properties:
filteredReason:
description: FilteredReason is the human-readable
reason why the device was filtered and could
not be used
type: string
name:
description: Name is a human-readable Identifier
for a generic function that is ran on every
block devices before it is considered by
LVMS to be valid and usable.
type: string
required:
- filteredReason
- name
type: object
type: array
description: Devices lists a map that relates all
currently filtered devices to the filter that excluded
them.
type: object
registered:
description: Registered lists all filters that are
run on the node
items:
type: string
type: array
required:
- registered
type: object
name:
description: Name is the name of the VG
type: string
node:
description: Node is the name of the node
type: string
Expand All @@ -313,7 +355,8 @@ spec:
status
type: string
status:
description: Status is the status of the VG on the node
description: Status tells if the VG was created on the
node
type: string
type: object
type: array
Expand Down
38 changes: 38 additions & 0 deletions bundle/manifests/lvm.topolvm.io_lvmvolumegroupnodestatuses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,44 @@ spec:
items:
type: string
type: array
filterStatus:
description: FilterStatus contains the per node status of applied
filters and their respective filtered devices. It can be consulted
in case the device is not picked up as a device for LVM to
use.
properties:
devices:
additionalProperties:
items:
properties:
filteredReason:
description: FilteredReason is the human-readable
reason why the device was filtered and could not
be used
type: string
name:
description: Name is a human-readable Identifier
for a generic function that is ran on every block
devices before it is considered by LVMS to be
valid and usable.
type: string
required:
- filteredReason
- name
type: object
type: array
description: Devices lists a map that relates all currently
filtered devices to the filter that excluded them.
type: object
registered:
description: Registered lists all filters that are run on
the node
items:
type: string
type: array
required:
- registered
type: object
name:
description: Name is the name of the VG
type: string
Expand Down
20 changes: 20 additions & 0 deletions bundle/manifests/lvms-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -888,3 +888,23 @@ spec:
targetPort: 9443
type: ValidatingAdmissionWebhook
webhookPath: /validate-lvm-topolvm-io-v1alpha1-lvmcluster
- admissionReviewVersions:
- v1
containerPort: 443
deploymentName: lvms-operator
failurePolicy: Fail
generateName: vlvmvolumegroup.kb.io
rules:
- apiGroups:
- lvm.topolvm.io
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- lvmvolumegroups
sideEffects: None
targetPort: 9443
type: ValidatingAdmissionWebhook
webhookPath: /validate-lvm-topolvm-io-v1alpha1-lvmvolumegroup
Loading

0 comments on commit 3cc0553

Please sign in to comment.