diff --git a/PROJECT b/PROJECT
index c6a8525..e1ea7ab 100644
--- a/PROJECT
+++ b/PROJECT
@@ -80,4 +80,13 @@ resources:
kind: ApiServerOverload
path: stackzoo.io/khaos/api/v1alpha1
version: v1alpha1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: stackzoo.io
+ group: khaos
+ kind: EventsEntropy
+ path: stackzoo.io/khaos/api/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/README.md b/README.md
index 3c38faf..08d7793 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@ Currently, Khaos does not implement *cronjobs*; any scheduling of Khaos Custom R
- [X] Inject resource constraints in pods
- [X] Add o remove labels in pods
- [X] Flood api server with calls
+- [X] Create custom kubernetes events
- [X] Exec commands inside pods (**experimental**).
@@ -85,14 +86,15 @@ Install and list the operator CRDs with the following command:
make install && kubectl get crds
NAME CREATED AT
-apiserveroverloads.khaos.stackzoo.io 2023-11-30T06:25:59Z
-commandinjections.khaos.stackzoo.io 2023-11-30T06:25:59Z
-configmapdestroyers.khaos.stackzoo.io 2023-11-30T06:25:59Z
-containerresourcechaos.khaos.stackzoo.io 2023-11-30T06:25:59Z
-nodedestroyers.khaos.stackzoo.io 2023-11-30T06:25:59Z
-poddestroyers.khaos.stackzoo.io 2023-11-30T06:25:59Z
-podlabelchaos.khaos.stackzoo.io 2023-11-30T06:25:59Z
-secretdestroyers.khaos.stackzoo.io 2023-11-30T06:25:59Z
+apiserveroverloads.khaos.stackzoo.io 2023-11-30T08:43:49Z
+commandinjections.khaos.stackzoo.io 2023-11-30T08:43:49Z
+configmapdestroyers.khaos.stackzoo.io 2023-11-30T08:43:49Z
+containerresourcechaos.khaos.stackzoo.io 2023-11-30T08:43:49Z
+eventsentropies.khaos.stackzoo.io 2023-11-30T08:43:49Z
+nodedestroyers.khaos.stackzoo.io 2023-11-30T08:43:49Z
+poddestroyers.khaos.stackzoo.io 2023-11-30T08:43:49Z
+podlabelchaos.khaos.stackzoo.io 2023-11-30T08:43:49Z
+secretdestroyers.khaos.stackzoo.io 2023-11-30T08:43:49Z
```
In order to run the operator on your cluster (current context - i.e. whatever cluster `kubectl cluster-info` shows) run:
@@ -122,7 +124,7 @@ In vscode you need to create a `.vscode/launch.json` file similar to the followi
-## Examples
+## Some Examples
In order to test the following examples, you can use the local *KinD* cluster (see the `Local Testing and Debugging` section).
Once you have the cluster up and running, procede to create a new namespace called `prod` and apply an example deployment:
@@ -482,6 +484,60 @@ metadata:
+
+
+
+
+
+
+
+
+
+
+
+ CREATE CUSTOM KUBERNETES EVENTS
+
+Apply the following `EventsEntropy` manifest:
+
+```yaml
+apiVersion: khaos.stackzoo.io/v1alpha1
+kind: EventsEntropy
+metadata:
+ name: example-eventsentropy
+spec:
+ events:
+ - "Custom event 1 with some gibberish - dfsdfsdffdgt egeg4e 😊"
+ - "Custom event 2 - with some gibberish dfsdfsdffdgt 676565 🥴"
+ - "Custom event 3 - with some gibberish 8/ihfwgf sufdh 🤪"
+
+```
+
+```console
+kubectl apply -f examples/events-entropy.yaml
+```
+
+Now retrieve kubernetes events via kubectl:
+```console
+kubectl get events | grep gibberish
+
+ Custom event 1 with some gibberish - dfsdfsdffdgt egeg4e 😊
+ Custom event 3 - with some gibberish 8/ihfwgf sufdh 🤪
+ Custom event 2 - with some gibberish dfsdfsdffdgt 676565 🥴
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api/v1alpha1/eventsentropy_types.go b/api/v1alpha1/eventsentropy_types.go
new file mode 100644
index 0000000..b496b21
--- /dev/null
+++ b/api/v1alpha1/eventsentropy_types.go
@@ -0,0 +1,60 @@
+/*
+Copyright 2023.
+
+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"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// EventsEntropySpec defines the desired state of EventsEntropy
+type EventsEntropySpec struct {
+ Events []string `json:"events"`
+}
+
+// EventsEntropyStatus defines the observed state of EventsEntropy
+type EventsEntropyStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// EventsEntropy is the Schema for the eventsentropies API
+type EventsEntropy struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec EventsEntropySpec `json:"spec,omitempty"`
+ Status EventsEntropyStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// EventsEntropyList contains a list of EventsEntropy
+type EventsEntropyList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []EventsEntropy `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&EventsEntropy{}, &EventsEntropyList{})
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index b99fc62..57bb2fa 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -385,6 +385,100 @@ func (in *ContainerResourceChaosStatus) DeepCopy() *ContainerResourceChaosStatus
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EventsEntropy) DeepCopyInto(out *EventsEntropy) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventsEntropy.
+func (in *EventsEntropy) DeepCopy() *EventsEntropy {
+ if in == nil {
+ return nil
+ }
+ out := new(EventsEntropy)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *EventsEntropy) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EventsEntropyList) DeepCopyInto(out *EventsEntropyList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]EventsEntropy, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventsEntropyList.
+func (in *EventsEntropyList) DeepCopy() *EventsEntropyList {
+ if in == nil {
+ return nil
+ }
+ out := new(EventsEntropyList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *EventsEntropyList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EventsEntropySpec) DeepCopyInto(out *EventsEntropySpec) {
+ *out = *in
+ if in.Events != nil {
+ in, out := &in.Events, &out.Events
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventsEntropySpec.
+func (in *EventsEntropySpec) DeepCopy() *EventsEntropySpec {
+ if in == nil {
+ return nil
+ }
+ out := new(EventsEntropySpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EventsEntropyStatus) DeepCopyInto(out *EventsEntropyStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventsEntropyStatus.
+func (in *EventsEntropyStatus) DeepCopy() *EventsEntropyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(EventsEntropyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeDestroyer) DeepCopyInto(out *NodeDestroyer) {
*out = *in
diff --git a/cmd/main.go b/cmd/main.go
index 188935a..b4cbd96 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -145,6 +145,13 @@ func main() {
setupLog.Error(err, "unable to create controller", "controller", "ApiServerOverload")
os.Exit(1)
}
+ if err = (&controller.EventsEntropyReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "EventsEntropy")
+ os.Exit(1)
+ }
//+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
diff --git a/config/crd/bases/khaos.stackzoo.io_eventsentropies.yaml b/config/crd/bases/khaos.stackzoo.io_eventsentropies.yaml
new file mode 100644
index 0000000..1eba77a
--- /dev/null
+++ b/config/crd/bases/khaos.stackzoo.io_eventsentropies.yaml
@@ -0,0 +1,51 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.13.0
+ name: eventsentropies.khaos.stackzoo.io
+spec:
+ group: khaos.stackzoo.io
+ names:
+ kind: EventsEntropy
+ listKind: EventsEntropyList
+ plural: eventsentropies
+ singular: eventsentropy
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: EventsEntropy is the Schema for the eventsentropies API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: EventsEntropySpec defines the desired state of EventsEntropy
+ properties:
+ events:
+ items:
+ type: string
+ type: array
+ required:
+ - events
+ type: object
+ status:
+ description: EventsEntropyStatus defines the observed state of EventsEntropy
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 80bfc5a..39fe0f1 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -10,6 +10,7 @@ resources:
- bases/khaos.stackzoo.io_podlabelchaos.yaml
- bases/khaos.stackzoo.io_configmapdestroyers.yaml
- bases/khaos.stackzoo.io_apiserveroverloads.yaml
+- bases/khaos.stackzoo.io_eventsentropies.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patches:
@@ -23,6 +24,7 @@ patches:
#- path: patches/webhook_in_podlabelchaos.yaml
#- path: patches/webhook_in_configmapdestroyers.yaml
#- path: patches/webhook_in_apiserveroverloads.yaml
+#- path: patches/webhook_in_eventsentropies.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
@@ -35,6 +37,7 @@ patches:
#- path: patches/cainjection_in_podlabelchaos.yaml
#- path: patches/cainjection_in_configmapdestroyers.yaml
#- path: patches/cainjection_in_apiserveroverloads.yaml
+#- path: patches/cainjection_in_eventsentropies.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# [WEBHOOK] To enable webhook, uncomment the following section
diff --git a/config/rbac/eventsentropy_editor_role.yaml b/config/rbac/eventsentropy_editor_role.yaml
new file mode 100644
index 0000000..f82b047
--- /dev/null
+++ b/config/rbac/eventsentropy_editor_role.yaml
@@ -0,0 +1,31 @@
+# permissions for end users to edit eventsentropies.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/instance: eventsentropy-editor-role
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: khaos
+ app.kubernetes.io/part-of: khaos
+ app.kubernetes.io/managed-by: kustomize
+ name: eventsentropy-editor-role
+rules:
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropies
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropies/status
+ verbs:
+ - get
diff --git a/config/rbac/eventsentropy_viewer_role.yaml b/config/rbac/eventsentropy_viewer_role.yaml
new file mode 100644
index 0000000..ce1ed68
--- /dev/null
+++ b/config/rbac/eventsentropy_viewer_role.yaml
@@ -0,0 +1,27 @@
+# permissions for end users to view eventsentropies.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/name: clusterrole
+ app.kubernetes.io/instance: eventsentropy-viewer-role
+ app.kubernetes.io/component: rbac
+ app.kubernetes.io/created-by: khaos
+ app.kubernetes.io/part-of: khaos
+ app.kubernetes.io/managed-by: kustomize
+ name: eventsentropy-viewer-role
+rules:
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropies
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropies/status
+ verbs:
+ - get
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 4b5baaf..5c74f22 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -13,6 +13,12 @@ rules:
- get
- list
- watch
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
- apiGroups:
- ""
resources:
@@ -192,6 +198,26 @@ rules:
- get
- patch
- update
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropy
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - khaos.stackzoo.io
+ resources:
+ - eventsentropy/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- khaos.stackzoo.io
resources:
diff --git a/config/samples/khaos_v1alpha1_eventsentropy.yaml b/config/samples/khaos_v1alpha1_eventsentropy.yaml
new file mode 100644
index 0000000..2feeab0
--- /dev/null
+++ b/config/samples/khaos_v1alpha1_eventsentropy.yaml
@@ -0,0 +1,12 @@
+apiVersion: khaos.stackzoo.io/v1alpha1
+kind: EventsEntropy
+metadata:
+ labels:
+ app.kubernetes.io/name: eventsentropy
+ app.kubernetes.io/instance: eventsentropy-sample
+ app.kubernetes.io/part-of: khaos
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/created-by: khaos
+ name: eventsentropy-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index f4b8a77..f252318 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -8,4 +8,5 @@ resources:
- khaos_v1alpha1_podlabelchaos.yaml
- khaos_v1alpha1_configmapdestroyer.yaml
- khaos_v1alpha1_apiserveroverload.yaml
+- khaos_v1alpha1_eventsentropy.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/examples/events-entropy.yaml b/examples/events-entropy.yaml
new file mode 100644
index 0000000..bb34485
--- /dev/null
+++ b/examples/events-entropy.yaml
@@ -0,0 +1,9 @@
+apiVersion: khaos.stackzoo.io/v1alpha1
+kind: EventsEntropy
+metadata:
+ name: example-eventsentropy
+spec:
+ events:
+ - "Custom event 1 with some gibberish - dfsdfsdffdgt egeg4e 😊"
+ - "Custom event 2 - with some gibberish dfsdfsdffdgt 676565 🥴"
+ - "Custom event 3 - with some gibberish 8/ihfwgf sufdh 🤪"
diff --git a/internal/controller/eventsentropy_controller.go b/internal/controller/eventsentropy_controller.go
new file mode 100644
index 0000000..b2f60b7
--- /dev/null
+++ b/internal/controller/eventsentropy_controller.go
@@ -0,0 +1,69 @@
+package controller
+
+import (
+ "context"
+
+ "github.com/go-logr/logr"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+
+ khaosv1alpha1 "stackzoo.io/khaos/api/v1alpha1"
+)
+
+// EventsEntropyReconciler reconciles a EventsEntropy object
+type EventsEntropyReconciler struct {
+ client.Client
+ Log logr.Logger
+ Scheme *runtime.Scheme
+}
+
+// +kubebuilder:rbac:groups=khaos.stackzoo.io,resources=eventsentropy,verbs=get;list;watch;create;update;patch;delete
+// +kubebuilder:rbac:groups=khaos.stackzoo.io,resources=eventsentropy/status,verbs=get;update;patch
+// +kubebuilder:rbac:groups="",resources=events,verbs=create
+
+func (r *EventsEntropyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = r.Log.WithValues("eventsentropy", req.NamespacedName)
+
+ // Fetch the EventsEntropy resource
+ eventsEntropy := &khaosv1alpha1.EventsEntropy{}
+ if err := r.Get(ctx, req.NamespacedName, eventsEntropy); err != nil {
+ return reconcile.Result{}, client.IgnoreNotFound(err)
+ }
+
+ // Process the EventsEntropy and create random events
+ r.createRandomEvents(eventsEntropy)
+
+ return reconcile.Result{}, nil
+}
+
+func (r *EventsEntropyReconciler) createRandomEvents(eventsEntropy *khaosv1alpha1.EventsEntropy) {
+ for _, eventStr := range eventsEntropy.Spec.Events {
+ // Create a random event object
+ event := &corev1.Event{
+ ObjectMeta: metav1.ObjectMeta{
+ GenerateName: "eventsentropy-",
+ Namespace: eventsEntropy.Namespace,
+ },
+ Message: eventStr,
+ }
+
+ // Set the reference to the EventsEntropy
+ controllerutil.SetControllerReference(eventsEntropy, event, r.Scheme)
+
+ // Create the event
+ if err := r.Create(context.Background(), event); err != nil {
+ r.Log.Error(err, "Failed to create random event")
+ }
+ }
+}
+
+func (r *EventsEntropyReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&khaosv1alpha1.EventsEntropy{}).
+ Complete(r)
+}