Skip to content

Commit

Permalink
feat: cilium chaos (#60)
Browse files Browse the repository at this point in the history
* feat: cilium chaos

Basic node isolation chaos implementation using cilium policy injection

Co-authored-by: Andrius Navasaitis <[email protected]>
  • Loading branch information
grahambrereton-form3 and rekfuki-f3 authored Nov 15, 2023
1 parent aa23dff commit 1e6f566
Show file tree
Hide file tree
Showing 46 changed files with 5,098 additions and 106 deletions.
77 changes: 77 additions & 0 deletions api/v1alpha1/ciliumchaos_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2023 Chaos Mesh 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"
)

// +kubebuilder:object:root=true
// +chaos-mesh:experiment

// CiliumChaos is the control script's spec.
type CiliumChaos struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec defines the behavior of a cilium chaos experiment
Spec CiliumChaosSpec `json:"spec"`

// +optional
// Most recently observed status of the chaos experiment
Status CiliumChaosStatus `json:"status,omitempty"`
}

var _ InnerObject = (*CiliumChaos)(nil)

// CiliumChaosSpec defines the attributes that a user creates on a chaos experiment affecting cilium CNI.
type CiliumChaosSpec struct {
NodeSelector `json:",inline"`

// Duration represents the duration of the chaos action.
Duration *string `json:"duration" webhook:"Duration"`

// CiliumPodSelector provides a custom selector to find the cilium-agent pod for the node.
//
// If not specified, it will default to selecting pods from the `kube-system` namespace with labels
// `app.kubernetes.io/name=cilium-agent` and `app.kubernetes.io/part-of=cilium` (which are used by default by the cilium
// helm chart)
CiliumPodSelector *CiliumPodSelectorSpec `json:"ciliumPodSelector"`

// RemoteCluster represents the remote cluster where the chaos will be deployed
// +optional
RemoteCluster string `json:"remoteCluster,omitempty"`
}

type CiliumPodSelectorSpec struct {
// Namespace to restrict cilium-agent pod selection to
// +optional
Namespace string `json:"namespace,omitempty"`

// Map of label selector expressions that can be used to select the cilium-agent pods..
LabelSelectors map[string]string `json:"labelSelectors,omitempty"`
}

// CiliumChaosStatus represents the current status of the chaos experiment about pods.
type CiliumChaosStatus struct {
ChaosStatus `json:",inline"`
}

func (obj *CiliumChaos) GetSelectorSpecs() map[string]interface{} {
return map[string]interface{}{
".": &obj.Spec.NodeSelector,
}
}
36 changes: 36 additions & 0 deletions api/v1alpha1/ciliumchaos_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 Chaos Mesh 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 (
"reflect"
)

func (in *CiliumChaosSpec) Default(root interface{}, field *reflect.StructField) {
if in == nil {
return
}

if in.CiliumPodSelector == nil {
in.CiliumPodSelector = &CiliumPodSelectorSpec{
Namespace: "kube-system",
LabelSelectors: map[string]string{
"app.kubernetes.io/name": "cilium-agent",
"app.kubernetes.io/part-of": "cilium",
},
}
}
}
13 changes: 13 additions & 0 deletions api/v1alpha1/common_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"time"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"

"github.com/chaos-mesh/chaos-mesh/api/genericwebhook"
Expand Down Expand Up @@ -173,6 +174,18 @@ func (f *FloatStr) Default(root interface{}, field *reflect.StructField) {
}
}

func (in *LabelSelectorRequirements) Validate(root interface{}, path *field.Path) field.ErrorList {
if in == nil {
return nil
}

if _, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{MatchExpressions: *in}); err != nil {
return field.ErrorList{field.Invalid(path, in, fmt.Sprintf("invalid expression selector: %s", err))}
}

return nil
}

func init() {
genericwebhook.Register("Duration", reflect.PtrTo(reflect.TypeOf(Duration(""))))
genericwebhook.Register("Percent", reflect.PtrTo(reflect.TypeOf(Percent(0))))
Expand Down
29 changes: 29 additions & 0 deletions api/v1alpha1/selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,32 @@ func (in PodSelectorSpec) ClusterScoped() bool {

return false
}

type NodeSelector struct {
// Selector is used to select nodes into which to inject chaos.
Selector NodeSelectorSpec `json:"selector"`

// Mode defines the mode to run chaos action.
// Supported mode: one / all / fixed / fixed-percent / random-max-percent
// +kubebuilder:validation:Enum=one;all;fixed;fixed-percent;random-max-percent
Mode SelectorMode `json:"mode"`

// Value is required when the mode is set to `FixedMode` / `FixedPercentMode` / `RandomMaxPercentMode`.
// If `FixedMode`, provide an integer of pods to do chaos action.
// If `FixedPercentMode`, provide a number from 0-100 to specify the percent of pods the server can do chaos action.
// IF `RandomMaxPercentMode`, provide a number from 0-100 to specify the max percent of pods to do chaos action
// +optional
Value string `json:"value,omitempty"`
}

type NodeSelectorSpec struct {
// Map of string keys and values that can be used to select objects.
// A selector based on labels.
// +optional
LabelSelectors map[string]string `json:"labelSelectors,omitempty"`

// a slice of label selector expressions that can be used to select objects.
// A list of selectors based on set-based label expressions.
// +optional
ExpressionSelectors LabelSelectorRequirements `json:"expressionSelectors,omitempty" swaggerignore:"true"`
}
149 changes: 149 additions & 0 deletions api/v1alpha1/zz_generated.chaosmesh.go

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

Loading

0 comments on commit 1e6f566

Please sign in to comment.