Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mikolaj-krzyzanowski-f3 committed Jan 7, 2025
1 parent 6a30e2e commit c700078
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 0 deletions.
41 changes: 41 additions & 0 deletions api/v1alpha1/moveazchaos_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package v1alpha1

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

//var (
// _ InnerObject = (*MoveAZChaos)(nil)
// _ InnerObjectWithSelector = (*MoveAZChaos)(nil)
//)

// +kubebuilder:object:root=true
// +chaos-mesh:experiment
// +chaos-mesh:oneshot=true
type MoveAZChaos struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec MoveAZChaosSpec `json:"spec"`
Status MoveAZChaosStatus `json:"status"`
}

type MoveAZChaosSpec struct {
DeploymentSelector `json:",inline"`
Zone string `json:"zone"`
// Duration represents the duration of the chaos
// +optional
Duration *string `json:"duration,omitempty"`
// RemoteCluster represents the remote cluster where the chaos will be deployed
// +optional
RemoteCluster string `json:"remoteCluster,omitempty"`
}
type MoveAZChaosStatus struct {
ChaosStatus `json:",inline"`
}

func (obj *MoveAZChaos) GetSelectorSpecs() map[string]interface{} {
return map[string]interface{}{
".": &obj.Spec.Selector,
}
}
21 changes: 21 additions & 0 deletions api/v1alpha1/selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,24 @@ type NodeSelectorSpec struct {
// +optional
ExpressionSelectors LabelSelectorRequirements `json:"expressionSelectors,omitempty" swaggerignore:"true"`
}

type DeploymentSelectorSpec struct {
// Map of namespace names to a list of deployments in that namespace.
Deployments map[string][]string `json:"deployments,omitempty"`
}

type DeploymentSelector struct {
Selector DeploymentSelectorSpec `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"`
}
2 changes: 2 additions & 0 deletions controllers/chaosimpl/fx.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/jvmchaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/k8schaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/kernelchaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/moveazchaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/networkchaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/physicalmachinechaos"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/podchaos"
Expand Down Expand Up @@ -66,5 +67,6 @@ var AllImpl = fx.Options(
rollingrestartchaos.Module,
podpvcchaos.Module,
certificatechaos.Module,
moveazchaos.Module,

utils.Module)
62 changes: 62 additions & 0 deletions controllers/chaosimpl/moveazchaos/impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package moveazchaos

import (
"context"
"fmt"

"go.uber.org/fx"
v1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
"github.com/chaos-mesh/chaos-mesh/controllers/utils/controller"
)

type Impl struct {
client.Client
}

func (i *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
moveAz, ok := obj.(*v1alpha1.MoveAZChaos)

if !ok {
return v1alpha1.NotInjected, fmt.Errorf("not MoveAZChaos")
}

name, err := controller.ParseNamespacedName(records[index].Id)
if err != nil {
return v1alpha1.NotInjected, err
}

var deployment *v1.Deployment
err = i.Client.Get(ctx, name, deployment)
if err != nil {
return v1alpha1.NotInjected, err
}

data := []byte(fmt.Sprintf("{\"spec\": {\"template\": {\"spec\": {\"nodeSelector\": {\"topology.kubernetes.io/zone\":\"%s\"}}}}}", moveAz.Spec.Zone))
patch := client.RawPatch(types.JSONPatchType, data)
err = i.Client.Patch(ctx, deployment, patch)
if err != nil {
return v1alpha1.NotInjected, err
}

return v1alpha1.Injected, nil
}

func (i *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
//TODO implement me
panic("implement me")
}

func NewImpl(c client.Client) Impl {
return Impl{c}
}

var Module = fx.Provide(
fx.Annotated{
Group: "impl",
Target: NewImpl,
},
)
78 changes: 78 additions & 0 deletions pkg/selector/deployment/selector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package deployment

import (
"context"

v1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"

"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
)

type Deployment struct {
v1.Deployment
}

func (d *Deployment) Id() string {
return (types.NamespacedName{
Name: d.Name,
Namespace: d.Namespace,
}).String()
}

type SelectImpl struct{}

func (impl *SelectImpl) Select(ctx context.Context, selector *v1alpha1.DeploymentSelector) ([]*Deployment, error) {
if selector == nil {
return []*Deployment{}, nil
}

client, err := kubernetesClient()
if err != nil {
return []*Deployment{}, err
}

var deployments []*Deployment
for namespace, names := range selector.Selector.Deployments {
deploymentList, err := client.AppsV1().Deployments(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return []*Deployment{}, err
}

matched := match(deploymentList, names)
deployments = append(deployments, matched...)

}

return deployments, nil
}

func match(list *v1.DeploymentList, names []string) []*Deployment {
var deployments []*Deployment
for _, selectorName := range names {
for _, deployment := range list.Items {
if selectorName == deployment.Name {
deployments = append(deployments, &Deployment{
Deployment: deployment,
})
}
}
}

return deployments
}

func kubernetesClient() (*kubernetes.Clientset, error) {
config, err := ctrl.GetConfig()
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}

func New() SelectImpl {
return SelectImpl{}
}

0 comments on commit c700078

Please sign in to comment.