From: Le Yao Date: Fri, 15 Jan 2021 07:32:23 +0000 (+0000) Subject: Implement Route CR controller X-Git-Tag: 21-12-01~14^2 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=722b64b911187de95a96edb87255226c3751fe0d;p=icn%2Fsdwan.git Implement Route CR controller The Route CR controller handles the Route resource and call CNF Route RESTful API to add/update/delete/get the route rule. Signed-off-by: Le Yao Change-Id: I95871e1e95ccacf5790697d2e5105448f630aac2 --- diff --git a/platform/crd-ctrlr/examples/sdewan-controller.yaml b/platform/crd-ctrlr/examples/sdewan-controller.yaml index 48edbb1..b5ddfd6 100644 --- a/platform/crd-ctrlr/examples/sdewan-controller.yaml +++ b/platform/crd-ctrlr/examples/sdewan-controller.yaml @@ -7,6 +7,79 @@ metadata: --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.5 + creationTimestamp: null + name: cnfroutes.batch.sdewan.akraino.org +spec: + group: batch.sdewan.akraino.org + names: + kind: CNFRoute + listKind: CNFRouteList + plural: cnfroutes + singular: cnfroute + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: CNFRoute is the Schema for the cnfroutes 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: CNFRouteSpec defines the desired state of CNFRoute + properties: + dev: + type: string + dst: + type: string + gw: + type: string + table: + enum: + - default + - cnf + type: string + type: object + status: + description: status subsource used for Sdewan rule CRDs + properties: + appliedGeneration: + format: int64 + type: integer + appliedTime: + format: date-time + type: string + message: + type: string + state: + type: string + required: + - state + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.2.5 @@ -1253,6 +1326,26 @@ rules: - get - list - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes/status + verbs: + - get + - patch + - update - apiGroups: - batch.sdewan.akraino.org resources: diff --git a/platform/crd-ctrlr/src/PROJECT b/platform/crd-ctrlr/src/PROJECT index 26c2994..eee5715 100644 --- a/platform/crd-ctrlr/src/PROJECT +++ b/platform/crd-ctrlr/src/PROJECT @@ -40,4 +40,7 @@ resources: - group: batch kind: CNFStatus version: v1alpha1 +- group: batch + kind: CNFRoute + version: v1alpha1 version: "2" diff --git a/platform/crd-ctrlr/src/api/v1alpha1/cnfroute_types.go b/platform/crd-ctrlr/src/api/v1alpha1/cnfroute_types.go new file mode 100644 index 0000000..8cceaa9 --- /dev/null +++ b/platform/crd-ctrlr/src/api/v1alpha1/cnfroute_types.go @@ -0,0 +1,57 @@ +/* + +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. + +// CNFRouteSpec defines the desired state of CNFRoute +type CNFRouteSpec struct { + Dst string `json:"dst,omitempty"` + Gw string `json:"gw,omitempty"` + Dev string `json:"dev,omitempty"` + // +kubebuilder:validation:Enum=default;cnf + Table string `json:"table,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status + +// CNFRoute is the Schema for the cnfroutes API +type CNFRoute struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CNFRouteSpec `json:"spec,omitempty"` + Status SdewanStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// CNFRouteList contains a list of CNFRoute +type CNFRouteList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []CNFRoute `json:"items"` +} + +func init() { + SchemeBuilder.Register(&CNFRoute{}, &CNFRouteList{}) +} diff --git a/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go b/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go index 9a21a7a..cf75319 100644 --- a/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go +++ b/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go @@ -68,6 +68,80 @@ func (in BucketPermission) DeepCopy() BucketPermission { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CNFRoute) DeepCopyInto(out *CNFRoute) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CNFRoute. +func (in *CNFRoute) DeepCopy() *CNFRoute { + if in == nil { + return nil + } + out := new(CNFRoute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CNFRoute) 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 *CNFRouteList) DeepCopyInto(out *CNFRouteList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CNFRoute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CNFRouteList. +func (in *CNFRouteList) DeepCopy() *CNFRouteList { + if in == nil { + return nil + } + out := new(CNFRouteList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CNFRouteList) 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 *CNFRouteSpec) DeepCopyInto(out *CNFRouteSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CNFRouteSpec. +func (in *CNFRouteSpec) DeepCopy() *CNFRouteSpec { + if in == nil { + return nil + } + out := new(CNFRouteSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CNFService) DeepCopyInto(out *CNFService) { *out = *in diff --git a/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfroutes.yaml b/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfroutes.yaml new file mode 100644 index 0000000..d8dd4f4 --- /dev/null +++ b/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfroutes.yaml @@ -0,0 +1,78 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.5 + creationTimestamp: null + name: cnfroutes.batch.sdewan.akraino.org +spec: + group: batch.sdewan.akraino.org + names: + kind: CNFRoute + listKind: CNFRouteList + plural: cnfroutes + singular: cnfroute + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: CNFRoute is the Schema for the cnfroutes 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: CNFRouteSpec defines the desired state of CNFRoute + properties: + dev: + type: string + dst: + type: string + gw: + type: string + table: + enum: + - default + - cnf + type: string + type: object + status: + description: status subsource used for Sdewan rule CRDs + properties: + appliedGeneration: + format: int64 + type: integer + appliedTime: + format: date-time + type: string + message: + type: string + state: + type: string + required: + - state + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/platform/crd-ctrlr/src/config/crd/kustomization.yaml b/platform/crd-ctrlr/src/config/crd/kustomization.yaml index 54a6b47..d43e045 100644 --- a/platform/crd-ctrlr/src/config/crd/kustomization.yaml +++ b/platform/crd-ctrlr/src/config/crd/kustomization.yaml @@ -15,6 +15,7 @@ resources: - bases/batch.sdewan.akraino.org_cnfservices.yaml - bases/batch.sdewan.akraino.org_sdewanapplications.yaml - bases/batch.sdewan.akraino.org_cnfstatuses.yaml +- bases/batch.sdewan.akraino.org_cnfroutes.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -33,6 +34,7 @@ patchesStrategicMerge: #- patches/webhook_in_cnfservices.yaml #- patches/webhook_in_sdewanapplications.yaml #- patches/webhook_in_cnfstatuses.yaml +#- patches/webhook_in_cnfroutes.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. @@ -50,6 +52,7 @@ patchesStrategicMerge: #- patches/cainjection_in_cnfservices.yaml #- patches/cainjection_in_sdewanapplications.yaml #- patches/cainjection_in_cnfstatuses.yaml +#- patches/cainjection_in_cnfroutes.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/platform/crd-ctrlr/src/config/crd/patches/cainjection_in_cnfroutes.yaml b/platform/crd-ctrlr/src/config/crd/patches/cainjection_in_cnfroutes.yaml new file mode 100644 index 0000000..84c0120 --- /dev/null +++ b/platform/crd-ctrlr/src/config/crd/patches/cainjection_in_cnfroutes.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: cnfroutes.batch.sdewan.akraino.org diff --git a/platform/crd-ctrlr/src/config/crd/patches/webhook_in_cnfroutes.yaml b/platform/crd-ctrlr/src/config/crd/patches/webhook_in_cnfroutes.yaml new file mode 100644 index 0000000..504e81c --- /dev/null +++ b/platform/crd-ctrlr/src/config/crd/patches/webhook_in_cnfroutes.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: cnfroutes.batch.sdewan.akraino.org +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/platform/crd-ctrlr/src/config/rbac/cnfroute_editor_role.yaml b/platform/crd-ctrlr/src/config/rbac/cnfroute_editor_role.yaml new file mode 100644 index 0000000..4ad5146 --- /dev/null +++ b/platform/crd-ctrlr/src/config/rbac/cnfroute_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit cnfroutes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cnfroute-editor-role +rules: +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes/status + verbs: + - get diff --git a/platform/crd-ctrlr/src/config/rbac/cnfroute_viewer_role.yaml b/platform/crd-ctrlr/src/config/rbac/cnfroute_viewer_role.yaml new file mode 100644 index 0000000..af5e474 --- /dev/null +++ b/platform/crd-ctrlr/src/config/rbac/cnfroute_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view cnfroutes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cnfroute-viewer-role +rules: +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes + verbs: + - get + - list + - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes/status + verbs: + - get diff --git a/platform/crd-ctrlr/src/config/rbac/role.yaml b/platform/crd-ctrlr/src/config/rbac/role.yaml index c2ce53f..24215d5 100644 --- a/platform/crd-ctrlr/src/config/rbac/role.yaml +++ b/platform/crd-ctrlr/src/config/rbac/role.yaml @@ -22,6 +22,26 @@ rules: - get - list - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch.sdewan.akraino.org + resources: + - cnfroutes/status + verbs: + - get + - patch + - update - apiGroups: - batch.sdewan.akraino.org resources: diff --git a/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfroute.yaml b/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfroute.yaml new file mode 100644 index 0000000..ef0f161 --- /dev/null +++ b/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfroute.yaml @@ -0,0 +1,11 @@ +apiVersion: batch.sdewan.akraino.org/v1alpha1 +kind: CNFRoute +metadata: + name: cnfroute-sample + labels: + sdewanPurpose: cnf1 +spec: + dst: "192.167.23.0/24" + gw: "172.16.44.11" + dev: "net1" + table: "cnf" diff --git a/platform/crd-ctrlr/src/controllers/cnfroute_controller.go b/platform/crd-ctrlr/src/controllers/cnfroute_controller.go new file mode 100644 index 0000000..f8ebdc3 --- /dev/null +++ b/platform/crd-ctrlr/src/controllers/cnfroute_controller.go @@ -0,0 +1,131 @@ +/* + +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 controllers + +import ( + "context" + "reflect" + + "github.com/go-logr/logr" + appsv1 "k8s.io/api/apps/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/handler" + "sigs.k8s.io/controller-runtime/pkg/source" + + batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1" + "sdewan.akraino.org/sdewan/openwrt" +) + +var cnfRouteHandler = new(CNFRouteHandler) + +type CNFRouteHandler struct { +} + +func (m *CNFRouteHandler) GetType() string { + return "cnfRoute" +} + +func (m *CNFRouteHandler) GetName(instance runtime.Object) string { + route := instance.(*batchv1alpha1.CNFRoute) + return route.Name +} + +func (m *CNFRouteHandler) GetFinalizer() string { + return "rule.finalizers.sdewan.akraino.org" +} + +func (m *CNFRouteHandler) GetInstance(r client.Client, ctx context.Context, req ctrl.Request) (runtime.Object, error) { + instance := &batchv1alpha1.CNFRoute{} + err := r.Get(ctx, req.NamespacedName, instance) + return instance, err +} + +func (m *CNFRouteHandler) Convert(instance runtime.Object, deployment appsv1.Deployment) (openwrt.IOpenWrtObject, error) { + route := instance.(*batchv1alpha1.CNFRoute) + openwrtroute := openwrt.SdewanRoute{ + Name: route.Name, + Dst: route.Spec.Dst, + Gw: route.Spec.Gw, + Dev: route.Spec.Dev, + Table: route.Spec.Table, + } + return &openwrtroute, nil +} + +func (m *CNFRouteHandler) IsEqual(instance1 openwrt.IOpenWrtObject, instance2 openwrt.IOpenWrtObject) bool { + route1 := instance1.(*openwrt.SdewanRoute) + route2 := instance2.(*openwrt.SdewanRoute) + return reflect.DeepEqual(*route1, *route2) +} + +func (m *CNFRouteHandler) GetObject(clientInfo *openwrt.OpenwrtClientInfo, name string) (openwrt.IOpenWrtObject, error) { + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + route := openwrt.RouteClient{OpenwrtClient: openwrtClient} + ret, err := route.GetRoute(name) + return ret, err +} + +func (m *CNFRouteHandler) CreateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) { + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + route := openwrt.RouteClient{OpenwrtClient: openwrtClient} + obj := instance.(*openwrt.SdewanRoute) + return route.CreateRoute(*obj) +} + +func (m *CNFRouteHandler) UpdateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) { + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + route := openwrt.RouteClient{OpenwrtClient: openwrtClient} + obj := instance.(*openwrt.SdewanRoute) + return route.UpdateRoute(*obj) +} + +func (m *CNFRouteHandler) DeleteObject(clientInfo *openwrt.OpenwrtClientInfo, name string) error { + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + route := openwrt.RouteClient{OpenwrtClient: openwrtClient} + return route.DeleteRoute(name) +} + +func (m *CNFRouteHandler) Restart(clientInfo *openwrt.OpenwrtClientInfo) (bool, error) { + return true, nil +} + +// CNFRouteReconciler reconciles a CNFRoute object +type CNFRouteReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme +} + +// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=cnfroutes,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=cnfroutes/status,verbs=get;update;patch + +func (r *CNFRouteReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { + return ProcessReconcile(r, r.Log, req, cnfRouteHandler) +} + +func (r *CNFRouteReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&batchv1alpha1.CNFRoute{}). + Watches( + &source.Kind{Type: &appsv1.Deployment{}}, + &handler.EnqueueRequestsFromMapFunc{ + ToRequests: handler.ToRequestsFunc(GetToRequestsFunc(r, &batchv1alpha1.CNFRouteList{})), + }, + Filter). + Complete(r) +} diff --git a/platform/crd-ctrlr/src/controllers/suite_test.go b/platform/crd-ctrlr/src/controllers/suite_test.go index bf86e57..f48b8b4 100644 --- a/platform/crd-ctrlr/src/controllers/suite_test.go +++ b/platform/crd-ctrlr/src/controllers/suite_test.go @@ -95,6 +95,9 @@ var _ = BeforeSuite(func(done Done) { err = batchv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = batchv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + // +kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) diff --git a/platform/crd-ctrlr/src/main.go b/platform/crd-ctrlr/src/main.go index beb3dee..a516398 100644 --- a/platform/crd-ctrlr/src/main.go +++ b/platform/crd-ctrlr/src/main.go @@ -229,6 +229,14 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "SdewanApplication") os.Exit(1) } + if err = (&controllers.CNFRouteReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("CNFRoute"), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "CNFRoute") + os.Exit(1) + } // +kubebuilder:scaffold:builder setupLog.Info("start CNFStatusController to query CNF status periodicly") diff --git a/platform/crd-ctrlr/src/openwrt/route.go b/platform/crd-ctrlr/src/openwrt/route.go new file mode 100644 index 0000000..797ef54 --- /dev/null +++ b/platform/crd-ctrlr/src/openwrt/route.go @@ -0,0 +1,108 @@ +package openwrt + +import ( + "encoding/json" +) + +const ( + routeBaseURL = "sdewan/route/v1/" +) + +type RouteClient struct { + OpenwrtClient *openwrtClient +} + +// Route Info +type SdewanRoute struct { + Name string `json:"name"` + Dst string `json:"dst"` + Gw string `json:"gw"` + Dev string `json:"dev"` + Table string `json:"table"` +} + +type SdewanRoutes struct { + Routes []SdewanRoute `json:"routes"` +} + +func (o *SdewanRoute) GetName() string { + return o.Name +} + +// Route APIs +// get routes +func (m *RouteClient) GetRoutes() (*SdewanRoutes, error) { + response, err := m.OpenwrtClient.Get(routeBaseURL + "routes") + if err != nil { + return nil, err + } + + var sdewanRoutes SdewanRoutes + err2 := json.Unmarshal([]byte(response), &sdewanRoutes) + if err2 != nil { + return nil, err2 + } + + return &sdewanRoutes, nil +} + +// get route +func (m *RouteClient) GetRoute(route_name string) (*SdewanRoute, error) { + response, err := m.OpenwrtClient.Get(routeBaseURL + "routes/" + route_name) + if err != nil { + return nil, err + } + + var sdewanRoute SdewanRoute + err2 := json.Unmarshal([]byte(response), &sdewanRoute) + if err2 != nil { + return nil, err2 + } + + return &sdewanRoute, nil +} + +// create route +func (m *RouteClient) CreateRoute(route SdewanRoute) (*SdewanRoute, error) { + route_obj, _ := json.Marshal(route) + response, err := m.OpenwrtClient.Post(routeBaseURL+"routes/", string(route_obj)) + if err != nil { + return nil, err + } + + var sdewanRoute SdewanRoute + err2 := json.Unmarshal([]byte(response), &sdewanRoute) + if err2 != nil { + return nil, err2 + } + + return &sdewanRoute, nil +} + +// delete route +func (m *RouteClient) DeleteRoute(route_name string) error { + _, err := m.OpenwrtClient.Delete(routeBaseURL + "routes/" + route_name) + if err != nil { + return err + } + + return nil +} + +// update route +func (m *RouteClient) UpdateRoute(route SdewanRoute) (*SdewanRoute, error) { + route_obj, _ := json.Marshal(route) + route_name := route.Name + response, err := m.OpenwrtClient.Put(routeBaseURL+"routes/"+route_name, string(route_obj)) + if err != nil { + return nil, err + } + + var sdewanRoute SdewanRoute + err2 := json.Unmarshal([]byte(response), &sdewanRoute) + if err2 != nil { + return nil, err2 + } + + return &sdewanRoute, nil +}