Skip to content

Commit

Permalink
[api] Objects in use removal validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Frostman committed Feb 13, 2024
1 parent 729444c commit 827412e
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 25 deletions.
6 changes: 4 additions & 2 deletions api/wiring/v1alpha2/connection_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ func (c *ConnectionSpec) ConnectionLabels() map[string]string {
labels[LabelConnectionType] = CONNECTION_STATIC_EXTERNAL
}

if c.StaticExternal != nil && c.StaticExternal.WithinVPC != "" {
labels[LabelVPC] = c.StaticExternal.WithinVPC
}

return labels
}

Expand Down Expand Up @@ -809,7 +813,5 @@ func (conn *Connection) Validate(ctx context.Context, client validation.Client,
}
}

// TODO validate that snat pool is in the nat subnet and unique per conn type=nat

return nil, nil
}
5 changes: 5 additions & 0 deletions api/wiring/v1alpha2/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (
LabelSwitches = LabelName("switches")
LabelServers = LabelName("servers")
LabelGroups = LabelName("groups")
LabelVPC = LabelName("vpc")
ListLabelValue = "true"
ConnectionLabelTypeServer = "server"
ConnectionLabelTypeSwitch = "switch"
Expand Down Expand Up @@ -56,6 +57,10 @@ func ListLabelRack(rackName string) string {
return ListLabel(ConnectionLabelTypeRack, rackName)
}

func ListLabelVLANNamespace(vlanNamespace string) string {
return ListLabel("vlanns", vlanNamespace)
}

func MatchingLabelsForListLabelServer(serverName string) client.MatchingLabels {
return client.MatchingLabels{
ListLabel(ConnectionLabelTypeServer, serverName): ListLabelValue,
Expand Down
4 changes: 4 additions & 0 deletions api/wiring/v1alpha2/switch_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ func (sw *Switch) Default() {
sw.Spec.Groups = append(sw.Spec.Groups, sw.Spec.Redundancy.Group)
}

for _, vlanNs := range sw.Spec.VLANNamespaces {
sw.Labels[ListLabelVLANNamespace(vlanNs)] = ListLabelValue
}

sort.Strings(sw.Spec.Groups)
sort.Strings(sw.Spec.VLANNamespaces)
}
Expand Down
11 changes: 11 additions & 0 deletions config/webhook/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- connections
sideEffects: None
Expand All @@ -267,6 +268,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- externals
sideEffects: None
Expand All @@ -287,6 +289,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- externalattachments
sideEffects: None
Expand All @@ -307,6 +310,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- externalpeerings
sideEffects: None
Expand All @@ -327,6 +331,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- ipv4namespaces
sideEffects: None
Expand All @@ -347,6 +352,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- servers
sideEffects: None
Expand All @@ -367,6 +373,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- switches
sideEffects: None
Expand All @@ -387,6 +394,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- vlannamespaces
sideEffects: None
Expand All @@ -407,6 +415,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- vpcs
sideEffects: None
Expand All @@ -427,6 +436,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- vpcattachments
sideEffects: None
Expand All @@ -447,6 +457,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- vpcpeerings
sideEffects: None
28 changes: 21 additions & 7 deletions pkg/webhook/connection/connection_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-wiring-githedgehog-com-v1alpha2-connection,mutating=true,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=connections,verbs=create;update,versions=v1alpha2,name=mconnection.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-connection,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=connections,verbs=create;update,versions=v1alpha2,name=vconnection.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-connection,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=connections,verbs=create;update;delete,versions=v1alpha2,name=vconnection.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("connection-webhook")

Expand Down Expand Up @@ -103,22 +103,36 @@ func (w *ConnectionWebhook) ValidateUpdate(ctx context.Context, oldObj runtime.O
return warns, err
}

if newConn.Spec.Unbundled != nil || newConn.Spec.Bundled != nil || newConn.Spec.MCLAG != nil {
if newConn.Spec.Unbundled != nil || newConn.Spec.Bundled != nil || newConn.Spec.MCLAG != nil || newConn.Spec.ESLAG != nil {
if !equality.Semantic.DeepEqual(oldConn.Spec, newConn.Spec) {
return nil, errors.Errorf("connection spec is immutable")
return nil, errors.Errorf("server-facing Connection spec is immutable")
}
}

return warns, w.validateStaticExternal(ctx, w.Validation, newConn)
}

func (w *ConnectionWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
// TODO prevent deleting connections that are in use

conn := obj.(*wiringapi.Connection)

if conn.Spec.Management != nil {
return nil, errors.New("cannot delete management connection")
vpcAttachments := &vpcapi.VPCAttachmentList{}
if err := w.Client.List(ctx, vpcAttachments, client.MatchingLabels{
wiringapi.LabelConnection: conn.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing vpc attachments") // TODO hide internal error
}
if len(vpcAttachments.Items) > 0 {
return nil, errors.Errorf("connection has attachments")
}

extAttachments := &vpcapi.ExternalAttachmentList{}
if err := w.Client.List(ctx, extAttachments, client.MatchingLabels{
wiringapi.LabelConnection: conn.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing external attachments") // TODO hide internal error
}
if len(extAttachments.Items) > 0 {
return nil, errors.Errorf("connection has external attachments")
}

return nil, nil
Expand Down
25 changes: 24 additions & 1 deletion pkg/webhook/external/external_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package external
import (
"context"

"github.com/pkg/errors"
vpcapi "go.githedgehog.com/fabric/api/vpc/v1alpha2"
"go.githedgehog.com/fabric/pkg/manager/config"
"go.githedgehog.com/fabric/pkg/manager/validation"
Expand Down Expand Up @@ -40,7 +41,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-vpc-githedgehog-com-v1alpha2-external,mutating=true,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externals,verbs=create;update,versions=v1alpha2,name=mexternal.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-external,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externals,verbs=create;update,versions=v1alpha2,name=vexternal.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-external,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externals,verbs=create;update;delete,versions=v1alpha2,name=vexternal.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("external-webhook")

Expand Down Expand Up @@ -80,5 +81,27 @@ func (w *ExternalWebhook) ValidateUpdate(ctx context.Context, oldObj runtime.Obj
}

func (w *ExternalWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
ext := obj.(*vpcapi.External)

extAttachments := &vpcapi.ExternalAttachmentList{}
if err := w.Client.List(ctx, extAttachments, client.MatchingLabels{
vpcapi.LabelExternal: ext.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing external attachments") // TODO hide internal error
}
if len(extAttachments.Items) > 0 {
return nil, errors.Errorf("external has attachments")
}

extPeerings := &vpcapi.ExternalPeeringList{}
if err := w.Client.List(ctx, extPeerings, client.MatchingLabels{
vpcapi.LabelExternal: ext.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing external peerings") // TODO hide internal error
}
if len(extPeerings.Items) > 0 {
return nil, errors.Errorf("external has peerings")
}

return nil, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-vpc-githedgehog-com-v1alpha2-externalattachment,mutating=true,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalattachments,verbs=create;update,versions=v1alpha2,name=mexternalattachment.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-externalattachment,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalattachments,verbs=create;update,versions=v1alpha2,name=vexternalattachment.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-externalattachment,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalattachments,verbs=create;update;delete,versions=v1alpha2,name=vexternalattachment.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("externalattachment-webhook")

Expand Down
2 changes: 1 addition & 1 deletion pkg/webhook/externalpeering/externalpeering_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-vpc-githedgehog-com-v1alpha2-externalpeering,mutating=true,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalpeerings,verbs=create;update,versions=v1alpha2,name=mexternalpeering.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-externalpeering,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalpeerings,verbs=create;update,versions=v1alpha2,name=vexternalpeering.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-externalpeering,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=externalpeerings,verbs=create;update;delete,versions=v1alpha2,name=vexternalpeering.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("externalpeering-webhook")

Expand Down
24 changes: 21 additions & 3 deletions pkg/webhook/ipv4ns/ipv4ns_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-vpc-githedgehog-com-v1alpha2-ipv4namespace,mutating=true,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=ipv4namespaces,verbs=create;update,versions=v1alpha2,name=mipv4namespace.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-ipv4namespace,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=ipv4namespaces,verbs=create;update,versions=v1alpha2,name=vipv4namespace.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-vpc-githedgehog-com-v1alpha2-ipv4namespace,mutating=false,failurePolicy=fail,sideEffects=None,groups=vpc.githedgehog.com,resources=ipv4namespaces,verbs=create;update;delete,versions=v1alpha2,name=vipv4namespace.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("ipv4namespace-webhook")

Expand Down Expand Up @@ -77,9 +77,27 @@ func (w *IPv4NamespaceWebhook) ValidateUpdate(ctx context.Context, oldObj runtim
}

func (w *IPv4NamespaceWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
// TODO prevent deleting IPv4Namespace that are in use
ipns := obj.(*vpcapi.IPv4Namespace)

// ns := obj.(*vpcapi.IPv4Namespace)
vpcs := &vpcapi.VPCList{}
if err := w.Client.List(ctx, vpcs, client.MatchingLabels{
vpcapi.LabelIPv4NS: ipns.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing vpcs") // TODO hide internal error
}
if len(vpcs.Items) > 0 {
return nil, errors.Errorf("IPv4Namespace has VPCs")
}

externals := &vpcapi.ExternalList{}
if err := w.Client.List(ctx, externals, client.MatchingLabels{
vpcapi.LabelIPv4NS: ipns.Name,
}); err != nil {
return nil, errors.Wrapf(err, "error listing externals") // TODO hide internal error
}
if len(externals.Items) > 0 {
return nil, errors.Errorf("IPv4Namespace has externals")
}

return nil, nil
}
15 changes: 13 additions & 2 deletions pkg/webhook/server/server_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package server
import (
"context"

"github.com/pkg/errors"
wiringapi "go.githedgehog.com/fabric/api/wiring/v1alpha2"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -34,7 +35,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-wiring-githedgehog-com-v1alpha2-server,mutating=true,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=servers,verbs=create;update,versions=v1alpha2,name=mserver.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-server,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=servers,verbs=create;update,versions=v1alpha2,name=vserver.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-server,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=servers,verbs=create;update;delete,versions=v1alpha2,name=vserver.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("server-webhook")

Expand Down Expand Up @@ -69,7 +70,17 @@ func (w *ServerWebhook) ValidateUpdate(ctx context.Context, oldObj runtime.Objec
}

func (w *ServerWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
// TODO prevent deleting servers that are in use
server := obj.(*wiringapi.Server)

conns := &wiringapi.ConnectionList{}
if err := w.Client.List(ctx, conns, client.MatchingLabels{
wiringapi.ListLabelServer(server.Name): wiringapi.ListLabelValue,
}); err != nil {
return nil, errors.Wrapf(err, "error listing connections") // TODO hide internal error
}
if len(conns.Items) > 0 {
return nil, errors.Errorf("server has connections")
}

return nil, nil
}
14 changes: 12 additions & 2 deletions pkg/webhook/switchh/switch_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var (
)

//+kubebuilder:webhook:path=/mutate-wiring-githedgehog-com-v1alpha2-switch,mutating=true,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=switches,verbs=create;update,versions=v1alpha2,name=mswitch.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-switch,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=switches,verbs=create;update,versions=v1alpha2,name=vswitch.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-wiring-githedgehog-com-v1alpha2-switch,mutating=false,failurePolicy=fail,sideEffects=None,groups=wiring.githedgehog.com,resources=switches,verbs=create;update;delete,versions=v1alpha2,name=vswitch.kb.io,admissionReviewVersions=v1

// var log = ctrl.Log.WithName("switch-webhook")

Expand Down Expand Up @@ -82,7 +82,17 @@ func (w *SwitchWebhook) ValidateUpdate(ctx context.Context, oldObj runtime.Objec
}

func (w *SwitchWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
// TODO prevent deleting switches that are in use
sw := obj.(*wiringapi.Switch)

conns := &wiringapi.ConnectionList{}
if err := w.Client.List(ctx, conns, client.MatchingLabels{
wiringapi.ListLabelSwitch(sw.Name): wiringapi.ListLabelValue,
}); err != nil {
return nil, errors.Wrapf(err, "error listing connections") // TODO hide internal error
}
if len(conns.Items) > 0 {
return nil, errors.Errorf("switch has connections")
}

return nil, nil
}
Loading

0 comments on commit 827412e

Please sign in to comment.