From: Yao Le Date: Sun, 27 Sep 2020 08:29:44 +0000 (+0000) Subject: Service CR implemention X-Git-Tag: v1.0~11^2 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=e67f9c4d3ce10e1391a4c8b0f3e016b06630a51f;p=icn%2Fsdwan.git Service CR implemention When apply a Service CR, the controller will call service RESTful API to configure iptables in CNF. Signed-off-by: Yao Le Change-Id: Ifb645c7d0712b9719a72c09623cba9f7fe778459 --- diff --git a/platform/crd-ctrlr/src/api/v1alpha1/cnfservice_types.go b/platform/crd-ctrlr/src/api/v1alpha1/cnfservice_types.go index ad73fbf..10660c1 100644 --- a/platform/crd-ctrlr/src/api/v1alpha1/cnfservice_types.go +++ b/platform/crd-ctrlr/src/api/v1alpha1/cnfservice_types.go @@ -24,24 +24,21 @@ import ( // CNFServiceSpec defines the desired state of CNFService type CNFServiceSpec struct { - Name string `json:"name,omitempty"` -} - -// CNFServiceStatus defines the observed state of CNFService -type CNFServiceStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + FullName string `json:"fullname,omitempty"` + Port string `json:"port,omitempty"` + DPort string `json:"dport,omitempty"` } // +kubebuilder:object:root=true +// +kubebuilder:subresource:status // CNFService is the Schema for the cnfservices API type CNFService struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec CNFServiceSpec `json:"spec,omitempty"` - Status CNFServiceStatus `json:"status,omitempty"` + Spec CNFServiceSpec `json:"spec,omitempty"` + Status SdewanStatus `json:"status,omitempty"` } // +kubebuilder:object:root=true 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 3216eea..83a43ee 100644 --- a/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go +++ b/platform/crd-ctrlr/src/api/v1alpha1/zz_generated.deepcopy.go @@ -58,7 +58,7 @@ func (in *CNFService) DeepCopyInto(out *CNFService) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) out.Spec = in.Spec - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CNFService. @@ -126,21 +126,6 @@ func (in *CNFServiceSpec) DeepCopy() *CNFServiceSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CNFServiceStatus) DeepCopyInto(out *CNFServiceStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CNFServiceStatus. -func (in *CNFServiceStatus) DeepCopy() *CNFServiceStatus { - if in == nil { - return nil - } - out := new(CNFServiceStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Connection) DeepCopyInto(out *Connection) { *out = *in diff --git a/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfservices.yaml b/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfservices.yaml index 09ad424..948dceb 100644 --- a/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfservices.yaml +++ b/platform/crd-ctrlr/src/config/crd/bases/batch.sdewan.akraino.org_cnfservices.yaml @@ -15,6 +15,8 @@ spec: plural: cnfservices singular: cnfservice scope: Namespaced + subresources: + status: {} validation: openAPIV3Schema: description: CNFService is the Schema for the cnfservices API @@ -34,11 +36,28 @@ spec: spec: description: CNFServiceSpec defines the desired state of CNFService properties: - name: + dport: + type: string + fullname: + type: string + port: type: string type: object status: - description: CNFServiceStatus defines the observed state of CNFService + 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 diff --git a/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfservice.yaml b/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfservice.yaml index a3f2ddb..d4664f2 100644 --- a/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfservice.yaml +++ b/platform/crd-ctrlr/src/config/samples/batch_v1alpha1_cnfservice.yaml @@ -2,6 +2,9 @@ apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: CNFService metadata: name: cnfservice-sample + labels: + sdewanPurpose: cnf1 spec: - # Add fields here - foo: bar + fullname: foo.default.svc.cluster.local + port: "8866" + dport: "8080" diff --git a/platform/crd-ctrlr/src/controllers/cnfservice_controller.go b/platform/crd-ctrlr/src/controllers/cnfservice_controller.go index 2dc0d8d..7047347 100644 --- a/platform/crd-ctrlr/src/controllers/cnfservice_controller.go +++ b/platform/crd-ctrlr/src/controllers/cnfservice_controller.go @@ -17,6 +17,7 @@ package controllers import ( "context" + "reflect" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -56,33 +57,51 @@ func (m *CNFServiceHandler) GetInstance(r client.Client, ctx context.Context, re } func (m *CNFServiceHandler) Convert(instance runtime.Object, deployment appsv1.Deployment) (openwrt.IOpenWrtObject, error) { - return nil, nil + svc := instance.(*batchv1alpha1.CNFService) + openwrtsvc := openwrt.SdewanSvc{ + Name: svc.Name, + FullName: svc.Spec.FullName, + Port: svc.Spec.Port, + DPort: svc.Spec.DPort, + } + return &openwrtsvc, nil } func (m *CNFServiceHandler) IsEqual(instance1 openwrt.IOpenWrtObject, instance2 openwrt.IOpenWrtObject) bool { - return false + service1 := instance1.(*openwrt.SdewanSvc) + service2 := instance2.(*openwrt.SdewanSvc) + return reflect.DeepEqual(*service1, *service2) } func (m *CNFServiceHandler) GetObject(clientInfo *openwrt.OpenwrtClientInfo, name string) (openwrt.IOpenWrtObject, error) { - return nil, nil + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + svc := openwrt.SvcClient{OpenwrtClient: openwrtClient} + ret, err := svc.GetSvc(name) + return ret, err } func (m *CNFServiceHandler) CreateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) { - return nil, nil + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + svc := openwrt.SvcClient{OpenwrtClient: openwrtClient} + service := instance.(*openwrt.SdewanSvc) + return svc.CreateSvc(*service) } func (m *CNFServiceHandler) UpdateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) { - return nil, nil + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + svc := openwrt.SvcClient{OpenwrtClient: openwrtClient} + service := instance.(*openwrt.SdewanSvc) + return svc.UpdateSvc(*service) } func (m *CNFServiceHandler) DeleteObject(clientInfo *openwrt.OpenwrtClientInfo, name string) error { - return nil + openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) + svc := openwrt.SvcClient{OpenwrtClient: openwrtClient} + return svc.DeleteSvc(name) } func (m *CNFServiceHandler) Restart(clientInfo *openwrt.OpenwrtClientInfo) (bool, error) { - openwrtClient := openwrt.GetOpenwrtClient(*clientInfo) - service := openwrt.ServiceClient{OpenwrtClient: openwrtClient} - return service.ExecuteService("cnfService", "restart") + return true, nil } // CNFServiceReconciler reconciles a CNFService object diff --git a/platform/crd-ctrlr/src/openwrt/svc.go b/platform/crd-ctrlr/src/openwrt/svc.go new file mode 100644 index 0000000..2210e87 --- /dev/null +++ b/platform/crd-ctrlr/src/openwrt/svc.go @@ -0,0 +1,107 @@ +package openwrt + +import ( + "encoding/json" +) + +const ( + svcBaseURL = "sdewan/service/v1/" +) + +type SvcClient struct { + OpenwrtClient *openwrtClient +} + +// Svc Info +type SdewanSvc struct { + Name string `json:"name"` + FullName string `json:"fullname"` + Port string `json:"port"` + DPort string `json:"dport"` +} + +type SdewanSvcs struct { + Svcs []SdewanSvc `json:"svcs"` +} + +func (o *SdewanSvc) GetName() string { + return o.Name +} + +// Svc APIs +// get svcs +func (m *SvcClient) GetSvcs() (*SdewanSvcs, error) { + response, err := m.OpenwrtClient.Get(svcBaseURL + "services") + if err != nil { + return nil, err + } + + var sdewanSvcs SdewanSvcs + err2 := json.Unmarshal([]byte(response), &sdewanSvcs) + if err2 != nil { + return nil, err2 + } + + return &sdewanSvcs, nil +} + +// get svc +func (m *SvcClient) GetSvc(svc_name string) (*SdewanSvc, error) { + response, err := m.OpenwrtClient.Get(svcBaseURL + "services/" + svc_name) + if err != nil { + return nil, err + } + + var sdewanSvc SdewanSvc + err2 := json.Unmarshal([]byte(response), &sdewanSvc) + if err2 != nil { + return nil, err2 + } + + return &sdewanSvc, nil +} + +// create svc +func (m *SvcClient) CreateSvc(svc SdewanSvc) (*SdewanSvc, error) { + svc_obj, _ := json.Marshal(svc) + response, err := m.OpenwrtClient.Post(svcBaseURL+"services/", string(svc_obj)) + if err != nil { + return nil, err + } + + var sdewanSvc SdewanSvc + err2 := json.Unmarshal([]byte(response), &sdewanSvc) + if err2 != nil { + return nil, err2 + } + + return &sdewanSvc, nil +} + +// delete svc +func (m *SvcClient) DeleteSvc(svc_name string) error { + _, err := m.OpenwrtClient.Delete(svcBaseURL + "services/" + svc_name) + if err != nil { + return err + } + + return nil +} + +// update svc +func (m *SvcClient) UpdateSvc(svc SdewanSvc) (*SdewanSvc, error) { + svc_obj, _ := json.Marshal(svc) + svc_name := svc.Name + response, err := m.OpenwrtClient.Put(svcBaseURL+"services/"+svc_name, string(svc_obj)) + if err != nil { + return nil, err + } + + var sdewanSvc SdewanSvc + err2 := json.Unmarshal([]byte(response), &sdewanSvc) + if err2 != nil { + return nil, err2 + } + + return &sdewanSvc, nil +}