https support for mepagent 22/3622/3
authorkhemendra kumar <khemendra.kumar@huawei.com>
Thu, 16 Jul 2020 02:37:52 +0000 (08:07 +0530)
committerkhemendra kumar <khemendra.kumar@huawei.com>
Thu, 16 Jul 2020 03:07:29 +0000 (03:07 +0000)
support both http and https,
support mep GW interface.

Signed-off-by: khemendra kumar <khemendra.kumar@huawei.com>
Change-Id: I407261eba7fb6d1f1af1fb447ceaf2d0bedc55b3

mep/mepagent/SampleApp/conf/app_info.yaml [new file with mode: 0644]
mep/mepagent/SampleApp/conf/app_instance_info.yaml
mep/mepagent/SampleApp/docker-build.sh [new file with mode: 0755]
mep/mepagent/SampleApp/docker/Dockerfile [moved from mep/mepagent/SampleApp/Dockerfile with 100% similarity]
mep/mepagent/SampleApp/mepagent.yaml [changed mode: 0644->0755]
mep/mepagent/SampleApp/src/main/main.go
mep/mepagent/pkg/model/appconf.go [new file with mode: 0644]
mep/mepagent/pkg/model/instance.go
mep/mepagent/pkg/service/register.go
mep/mepagent/pkg/service/request.go [new file with mode: 0644]
mep/mepagent/pkg/service/util.go

diff --git a/mep/mepagent/SampleApp/conf/app_info.yaml b/mep/mepagent/SampleApp/conf/app_info.yaml
new file mode 100644 (file)
index 0000000..ad6a655
--- /dev/null
@@ -0,0 +1,18 @@
+# Copyright 2020 Huawei Technologies Co., Ltd.
+#
+# 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.
+
+#ssl_cipher configuration
+sslCiphers: >
+  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
index 37f764c..01be19c 100644 (file)
 
 ---
 appInstanceId: id12345
-mepServerIP: 192.168.0.101
-mepServerPORT: 30088
+mepGWIP: 192.168.0.102
+httpGWPORT: 31082
+httpsGWPORT: 30126
+mepGWROUTES: /mp1
 serviceInfoPosts:
   - serName: ExampleService
     serInstanceId:
diff --git a/mep/mepagent/SampleApp/docker-build.sh b/mep/mepagent/SampleApp/docker-build.sh
new file mode 100755 (executable)
index 0000000..55376ae
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+# Copyright 2020 Huawei Technologies Co., Ltd.
+#
+# 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.
+
+MEP_VERSION=latest
+docker build --no-cache -t khemendra/mepagent:${MEP_VERSION} -f docker/Dockerfile .
+docker push khemendra/mepagent:${MEP_VERSION}
old mode 100644 (file)
new mode 100755 (executable)
index 79b7ef6..d450817
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+
+# mep pod
 ---
-apiVersion: apps/v1
-kind: Deployment
+apiVersion: v1
+kind: Pod
 metadata:
   name: mepagent
   namespace: mep
+  labels:
+    app: mepagent
 spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: mepagent
-  template:
-    metadata:
-      labels:
-        app: mepagent
-    spec:
-      containers:
-        -
-          image: "mepagent:latest"
-          imagePullPolicy: IfNotPresent
-          name: mepagent
-          ports:
-            -
-              containerPort: 80
+  containers:
+    - image: khemendra/mepagent:latest
+      imagePullPolicy: Always
+      name: mepagent-pod
+      env:
+        - name: CA_CERT_DOMAIN_NAME
+          value: "www.ealtedge.com"
+        - name: SSL_ROOT
+          value: "/etc/mepagent_ssl/ca.crt"
+        - name: APP_SSL_MODE
+          value: "0"
+      ports:
+        - containerPort: 80
+      volumeMounts:
+        - name: mepagentssl
+          mountPath: "/etc/mepagent_ssl"
+          readOnly: true
+  volumes:
+    - name: mepagentssl
+      secret:
+        secretName: default-vault-certificate
index 6c6fcee..9f536e5 100644 (file)
@@ -18,8 +18,15 @@ package main
 
 import (
        "github.com/akraino-edge-stack/ealt-edge/mep/mepagent/pkg/service"
+       "time"
 )
 
 func main() {
        _, _ = service.SvcReg("./conf/app_instance_info.yaml")
+       Heart()
 }
+
+func Heart() {
+       time.Sleep(time.Hour)
+}
+
diff --git a/mep/mepagent/pkg/model/appconf.go b/mep/mepagent/pkg/model/appconf.go
new file mode 100644 (file)
index 0000000..b5fd5e2
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *  Copyright 2020 Huawei Technologies Co., Ltd.
+ *
+ *  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 model
+
+type AppConf struct {
+       SslCipherSuite string `yaml:"sslCiphers" json:"sslCiphers"`
+}
index 66f4202..d51009d 100644 (file)
@@ -19,8 +19,10 @@ package model
 
 type AppInstanceInfo struct {
        AppInstanceId                            string                                    `yaml:"appInstanceId" json:"appInstanceId"`
-       MepServerIP                              string                                    `yaml:"mepServerIP" json:"mepServerIP"`
-       MepServerPORT                            string                                    `yaml:"mepServerPORT" json:"mepServerPORT"`
+       MepGWIP                                  string                                    `yaml:"mepGWIP" json:"mepGWIP"`
+       HttpGWPORT                               string                                    `yaml:"httpGWPORT" json:"httpGWPORT"`
+       HttpsGWPORT                              string                                    `yaml:"httpsGWPORT" json:"httpsGWPORT"`
+       MepGWROUTES                              string                                    `yaml:"mepGWROUTES" json:"mepGWROUTES"`
        ServiceInfoPosts                         []ServiceInfoPost                         `yaml:"serviceInfoPosts" json:"serviceInfoPosts"`
        SerAvailabilityNotificationSubscriptions []SerAvailabilityNotificationSubscription `yaml:"serAvailabilityNotificationSubscriptions" json:"serAvailabilityNotificationSubscriptions"`
 }
index 9341574..5dd6dc3 100644 (file)
@@ -19,11 +19,15 @@ package service
 import (
        "encoding/json"
        "log"
+       "os"
        "strconv"
        "time"
 )
 
 func SvcReg(confPath string) (string, error) {
+    var urlProto string
+       var gwPORT string
+
        conf, err := GetConf(confPath)
        if err != nil {
                log.Println(err.Error())
@@ -32,9 +36,21 @@ func SvcReg(confPath string) (string, error) {
 
        appInstanceId := conf.AppInstanceId
        serviceInfos := conf.ServiceInfoPosts
-       mepServerIP := conf.MepServerIP
-       mepServerPORT := conf.MepServerPORT
-       url := "http://" + mepServerIP + ":" + mepServerPORT + "/mep/mec_service_mgmt/v1/applications/" + appInstanceId + "/services"
+       gwRoutes := conf.MepGWROUTES
+       gwIP := conf.MepGWIP
+
+       sslMode := os.Getenv("APP_SSL_MODE")
+       //if ssl mode is enabled, then config tls
+       if sslMode == "0" {
+               gwPORT = conf.HttpGWPORT
+               urlProto = "http://"
+       } else {
+               gwPORT = conf.HttpsGWPORT
+               urlProto = "https://"
+       }
+
+       url := urlProto + gwIP + ":" + gwPORT + gwRoutes + "/mep/mec_service_mgmt/v1/applications/" + appInstanceId + "/services"
+       log.Println("Register url is" + url)
 
     for _, serviceInfo := range serviceInfos {
                data, e := json.Marshal(serviceInfo)
diff --git a/mep/mepagent/pkg/service/request.go b/mep/mepagent/pkg/service/request.go
new file mode 100644 (file)
index 0000000..1d40c40
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  Copyright 2020 Huawei Technologies Co., Ltd.
+ *
+ *  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 service
+
+import (
+       "crypto/tls"
+       "crypto/x509"
+       "errors"
+       "io/ioutil"
+       "log"
+       "net/http"
+       "os"
+       "strconv"
+       "strings"
+)
+
+// const
+var cipherSuiteMap = map[string]uint16{
+       "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+       "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+}
+
+// register to mep
+func RegisterToMep(param string, url string) (string, error) {
+       response, errPost := DoPost(param, url)
+       if errPost != nil {
+               log.Println("Failed to send request")
+               return "", errPost
+       }
+       defer response.Body.Close()
+
+       if response.StatusCode != http.StatusCreated {
+               return "", errors.New("request failed, status is " + strconv.Itoa(response.StatusCode))
+       }
+       body, err := ioutil.ReadAll(response.Body)
+       if err != nil {
+               log.Println("Failed to read response")
+               return "", err
+       }
+
+       return string(body), nil
+}
+
+func DoPost(param string, url string) (*http.Response, error) {
+       sslMode := os.Getenv("APP_SSL_MODE")
+
+       //if ssl mode is enabled, then config tls
+       if sslMode == "0" {
+               response, errPost := http.Post(url, "application/json", strings.NewReader(param))
+               if errPost != nil {
+                       log.Println("Failed to create http request")
+                       return nil, errPost
+               }
+               return response, nil
+       } else {
+               req, errReq := http.NewRequest("POST", url, strings.NewReader(param))
+               if errReq != nil {
+                       log.Println("Failed to create https request")
+                       return nil, errReq
+               }
+               response, errDo := DoRegister(req)
+               if errDo != nil {
+                       log.Println("Failed to post https request %s", errDo)
+                       return nil, errDo
+               }
+               return response, nil
+       }
+}
+
+func DoRegister(req *http.Request) (*http.Response, error) {
+       config, err := TlsConfig()
+       if err != nil {
+               log.Println("Failed to config HTTPS")
+               return nil, err
+       }
+
+       trans := &http.Transport{
+               TLSClientConfig: config,
+       }
+
+       client := &http.Client{Transport: trans}
+
+       return client.Do(req)
+}
+
+func TlsConfig() (*tls.Config, error) {
+       caCert, err := ioutil.ReadFile(os.Getenv("SSL_ROOT"))
+       if err != nil {
+               log.Println("Failed to read  cert from file")
+               return nil, err
+       }
+
+       CACERT := x509.NewCertPool()
+       CACERT.AppendCertsFromPEM(caCert)
+
+       appconf, err1 := GetAppConf("./conf/app_info.yaml")
+       if err1 != nil {
+               log.Println("Failed to read  cipher from file")
+               return nil, err1
+       }
+
+       cipherslist := appconf.SslCipherSuite
+       if cipherslist == "" {
+               log.Println("no cipher provided in conf")
+               return nil, err
+       }
+
+    ciphermap := getcipher(cipherslist)
+    if ciphermap == nil {
+               return nil, err
+       }
+
+       return &tls.Config{
+               RootCAs: CACERT,
+               ServerName:   os.Getenv("CA_CERT_DOMAIN_NAME"),
+               CipherSuites: ciphermap,
+               MinVersion: tls.VersionTLS12,
+       }, nil
+}
+
+func getcipher(ciphers string) []uint16 {
+       ciphersmap := make([]uint16, 0)
+       cipherlist := strings.Split(ciphers, ",")
+       for _, ciphername := range cipherlist {
+               ciphernametrim := strings.TrimSpace(ciphername)
+               if len(ciphernametrim) == 0 {
+                       continue
+               }
+
+               ciphervalue, ok := cipherSuiteMap[ciphernametrim]
+               if !ok {
+                       log.Println("not recommended cipher")
+                       return nil
+               }
+               ciphersmap = append(ciphersmap, ciphervalue)
+       }
+
+       if len(ciphersmap) <= 0 {
+               log.Println("no cipher in list")
+               return nil
+       }
+
+       return ciphersmap
+}
index 49313f4..9cfe217 100644 (file)
 package service
 
 import (
-       "errors"
        "gopkg.in/yaml.v2"
        "io/ioutil"
-       "net/http"
-       "strings"
        "github.com/akraino-edge-stack/ealt-edge/mep/mepagent/pkg/model"
 )
 
@@ -42,21 +39,18 @@ func GetConf(path string) (model.AppInstanceInfo, error) {
        return info, nil
 }
 
-// register to mep
-func RegisterToMep(param string, url string) (string, error) {
-       response, err := http.Post(url, "application/json", strings.NewReader(param))
+func GetAppConf(FilePath string) (model.AppConf, error) {
+       var AppInfo model.AppConf
+       yamlFile, err := ioutil.ReadFile(FilePath)
        if err != nil {
-               return "", err
+               return AppInfo, err
        }
 
-       if response.StatusCode != http.StatusCreated {
-               return "", errors.New("created failed")
-       }
-       defer response.Body.Close()
-       body, err2 := ioutil.ReadAll(response.Body)
-       if err2 != nil {
-               return "", err2
+       err1 := yaml.UnmarshalStrict(yamlFile, &AppInfo)
+       if err1 != nil {
+               return AppInfo, err
        }
 
-       return string(body), nil
+       return AppInfo, nil
+
 }