Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: CRD too long, to reduce crd size #155

Open
10 tasks
whg517 opened this issue Sep 21, 2024 · 1 comment
Open
10 tasks

[Feature]: CRD too long, to reduce crd size #155

whg517 opened this issue Sep 21, 2024 · 1 comment
Assignees
Labels
tracking list The issue contains a task list to tracking

Comments

@whg517
Copy link
Member

whg517 commented Sep 21, 2024

trace

  • operator-go
  • zookeeper
  • hdfs
  • hbase
  • hive
  • spark
  • trino
  • dolphinscheduler
  • superset
  • kafka

Implement with memcached example

define go struct with kubebuilder

package v1alpha1

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

// MemcachedSpec defines the desired state of Memcached
type MemcachedSpec struct {
	// +kubebuilder:pruning:PreserveUnknownFields
	// +kubebuilder:validation:Type=object
	// +kubebuilder:validation:Optional
	Afficinity *runtime.RawExtension `json:"affinity,omitempty"`

	// +kubebuilder:pruning:PreserveUnknownFields
	// +kubebuilder:validation:Type=object
	// +kubebuilder:validation:Optional
	PodOverrides *runtime.RawExtension `json:"podOverrides,omitempty"`
}

// MemcachedStatus defines the observed state of Memcached
type MemcachedStatus struct {
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// Memcached is the Schema for the memcacheds API
type Memcached struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   MemcachedSpec   `json:"spec,omitempty"`
	Status MemcachedStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// MemcachedList contains a list of Memcached
type MemcachedList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []Memcached `json:"items"`
}

func init() {
	SchemeBuilder.Register(&Memcached{}, &MemcachedList{})
}

generate crd with controller-tool

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
	$(CONTROLLER_GEN) rbac:roleName=manager-role crd:crdVersions=v1,ignoreUnexportedFields=true,generateEmbeddedObjectMeta=false webhook paths="./..." output:crd:artifacts:config=config/crd/bases

crd

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.16.2
  name: memcacheds.cache.example.com
spec:
  group: cache.example.com
  names:
    kind: Memcached
    listKind: MemcachedList
    plural: memcacheds
    singular: memcached
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        description: Memcached is the Schema for the memcacheds 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: MemcachedSpec defines the desired state of Memcached
            properties:
              affinity:
                type: object
                x-kubernetes-preserve-unknown-fields: true
              podOverrides:
                type: object
                x-kubernetes-preserve-unknown-fields: true
            type: object
          status:
            description: MemcachedStatus defines the observed state of Memcached
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}

use json package to Unmarshal object

example CR

apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  labels:
    app.kubernetes.io/name: foo
    app.kubernetes.io/managed-by: kustomize
  name: memcached-sample
spec:
  podOverrides:
    spec:
      securityContext:
        runAsUser: 1000

implemented controller logic

package controller

import (
	"context"
	"encoding/json"

	corev1 "k8s.io/api/core/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/log"

	cachev1alpha1 "github.com/whg517/memcached-operator/api/v1alpha1"
)

// MemcachedReconciler reconciles a Memcached object
type MemcachedReconciler struct {
	client.Client
	Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update

func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	log := log.FromContext(ctx)
	obj := cachev1alpha1.Memcached{}

	if err := r.Get(ctx, req.NamespacedName, &obj); err != nil {
		if client.IgnoreNotFound(err) == nil {
			log.Info("Memcached resource not found. Ignoring since object must be deleted.")
			return ctrl.Result{}, nil
		}
		return ctrl.Result{}, err
	}

	podTemplate, err := convertRawExtension[corev1.PodTemplateSpec](obj.Spec.PodOverrides)
	if err != nil {
		return ctrl.Result{}, err
	}

	log.Info("Pod run as user is", "user", podTemplate.Spec.SecurityContext.RunAsUser)

	return ctrl.Result{}, nil
}

func convertRawExtension[T any](raw *runtime.RawExtension) (T, error) {
	var obj T
	if raw == nil || raw.Raw == nil {
		return obj, nil
	}

	if err := json.Unmarshal(raw.Raw, &obj); err != nil {
		return obj, err
	}
	return obj, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&cachev1alpha1.Memcached{}).
		Complete(r)
}
@whg517 whg517 changed the title CRD too long, to reduce crd size [Feature]: CRD too long, to reduce crd size Sep 21, 2024
@whg517
Copy link
Member Author

whg517 commented Sep 29, 2024

@whg517 whg517 transferred this issue from zncdatadev/operator-go Sep 29, 2024
@whg517 whg517 added the tracking list The issue contains a task list to tracking label Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracking list The issue contains a task list to tracking
Projects
None yet
Development

No branches or pull requests

2 participants