From ee49b4a131a219cc4951abe7c7ecb5914addd3dc Mon Sep 17 00:00:00 2001 From: khemendra kumar Date: Thu, 16 Jul 2020 08:07:52 +0530 Subject: [PATCH] https support for mepagent support both http and https, support mep GW interface. Signed-off-by: khemendra kumar Change-Id: I407261eba7fb6d1f1af1fb447ceaf2d0bedc55b3 --- mep/mepagent/SampleApp/conf/app_info.yaml | 18 +++ mep/mepagent/SampleApp/conf/app_instance_info.yaml | 6 +- mep/mepagent/SampleApp/docker-build.sh | 18 +++ mep/mepagent/SampleApp/{ => docker}/Dockerfile | 0 mep/mepagent/SampleApp/mepagent.yaml | 46 +++--- mep/mepagent/SampleApp/src/main/main.go | 7 + mep/mepagent/pkg/model/appconf.go | 21 +++ mep/mepagent/pkg/model/instance.go | 6 +- mep/mepagent/pkg/service/register.go | 22 ++- mep/mepagent/pkg/service/request.go | 158 +++++++++++++++++++++ mep/mepagent/pkg/service/util.go | 24 ++-- 11 files changed, 285 insertions(+), 41 deletions(-) create mode 100644 mep/mepagent/SampleApp/conf/app_info.yaml create mode 100755 mep/mepagent/SampleApp/docker-build.sh rename mep/mepagent/SampleApp/{ => docker}/Dockerfile (100%) mode change 100644 => 100755 mep/mepagent/SampleApp/mepagent.yaml create mode 100644 mep/mepagent/pkg/model/appconf.go create mode 100644 mep/mepagent/pkg/service/request.go diff --git a/mep/mepagent/SampleApp/conf/app_info.yaml b/mep/mepagent/SampleApp/conf/app_info.yaml new file mode 100644 index 0000000..ad6a655 --- /dev/null +++ b/mep/mepagent/SampleApp/conf/app_info.yaml @@ -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 diff --git a/mep/mepagent/SampleApp/conf/app_instance_info.yaml b/mep/mepagent/SampleApp/conf/app_instance_info.yaml index 37f764c..01be19c 100644 --- a/mep/mepagent/SampleApp/conf/app_instance_info.yaml +++ b/mep/mepagent/SampleApp/conf/app_instance_info.yaml @@ -14,8 +14,10 @@ --- 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 index 0000000..55376ae --- /dev/null +++ b/mep/mepagent/SampleApp/docker-build.sh @@ -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} diff --git a/mep/mepagent/SampleApp/Dockerfile b/mep/mepagent/SampleApp/docker/Dockerfile similarity index 100% rename from mep/mepagent/SampleApp/Dockerfile rename to mep/mepagent/SampleApp/docker/Dockerfile diff --git a/mep/mepagent/SampleApp/mepagent.yaml b/mep/mepagent/SampleApp/mepagent.yaml old mode 100644 new mode 100755 index 79b7ef6..d450817 --- a/mep/mepagent/SampleApp/mepagent.yaml +++ b/mep/mepagent/SampleApp/mepagent.yaml @@ -12,27 +12,35 @@ # 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 diff --git a/mep/mepagent/SampleApp/src/main/main.go b/mep/mepagent/SampleApp/src/main/main.go index 6c6fcee..9f536e5 100644 --- a/mep/mepagent/SampleApp/src/main/main.go +++ b/mep/mepagent/SampleApp/src/main/main.go @@ -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 index 0000000..b5fd5e2 --- /dev/null +++ b/mep/mepagent/pkg/model/appconf.go @@ -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"` +} diff --git a/mep/mepagent/pkg/model/instance.go b/mep/mepagent/pkg/model/instance.go index 66f4202..d51009d 100644 --- a/mep/mepagent/pkg/model/instance.go +++ b/mep/mepagent/pkg/model/instance.go @@ -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"` } diff --git a/mep/mepagent/pkg/service/register.go b/mep/mepagent/pkg/service/register.go index 9341574..5dd6dc3 100644 --- a/mep/mepagent/pkg/service/register.go +++ b/mep/mepagent/pkg/service/register.go @@ -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 index 0000000..1d40c40 --- /dev/null +++ b/mep/mepagent/pkg/service/request.go @@ -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 +} diff --git a/mep/mepagent/pkg/service/util.go b/mep/mepagent/pkg/service/util.go index 49313f4..9cfe217 100644 --- a/mep/mepagent/pkg/service/util.go +++ b/mep/mepagent/pkg/service/util.go @@ -17,11 +17,8 @@ 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 + } -- 2.16.6