X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=inline;f=service-exposure%2Frapps-istio-mgr.go;h=fe68cb090c30b4c9e7ff3a38672a15ff08b88901;hb=805ac7cae6f73802179b105941ebb12183de91a7;hp=5a0761b61a4e31d69aab1b7eb5bdd33005dc267d;hpb=28fa9fbfee514da8c85171facbabe6747f499988;p=nonrtric.git diff --git a/service-exposure/rapps-istio-mgr.go b/service-exposure/rapps-istio-mgr.go index 5a0761b6..fe68cb09 100644 --- a/service-exposure/rapps-istio-mgr.go +++ b/service-exposure/rapps-istio-mgr.go @@ -1,29 +1,29 @@ // - -// ========================LICENSE_START================================= -// O-RAN-SC -// %% -// Copyright (C) 2022: Nordix Foundation -// %% -// 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 +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2022-2023: Nordix Foundation +// %% +// 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 // -// 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. -// ========================LICENSE_END=================================== +// 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. +// ========================LICENSE_END=================================== package main import ( "bytes" "context" "fmt" + netv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" netv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" secv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" versioned "istio.io/client-go/pkg/clientset/versioned" @@ -35,102 +35,30 @@ import ( "net/http" "os" "path/filepath" - "strings" + "text/template" ) const ( NAMESPACE = "istio-nonrtric" ) -var gatewayManifest = ` -apiVersion: networking.istio.io/v1beta1 -kind: Gateway -metadata: - name: nonrtric-istio-RAPP-NAME-gateway - namespace: RAPP-NS -spec: - selector: - istio: ingressgateway # use Istio gateway implementation - servers: - - port: - number: 80 - name: http - protocol: HTTP - hosts: - - "*" -` - -var virtualServiceManifest = ` -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -metadata: - name: nonrtric-istio-RAPP-NAME-vs - namespace: RAPP-NS -spec: - hosts: - - "*" - gateways: - - nonrtric-istio-RAPP-NAME-gateway - http: - - name: "RAPP-NAME-routes" - match: - - uri: - prefix: "/RAPP-NAME" - route: - - destination: - port: - number: 80 - host: RAPP-NAME.RAPP-NS.svc.cluster.local -` - -var requestAuthenticationManifest = ` -apiVersion: security.istio.io/v1beta1 -kind: RequestAuthentication -metadata: - name: "jwt-RAPP-NAME" - namespace: RAPP-NS -spec: - selector: - matchLabels: - app.kubernetes.io/instance: RAPP-NAME - jwtRules: - - issuer: "http://192.168.49.2:31560/auth/realms/REALM-NAME" - jwksUri: "http://192.168.49.2:31560/auth/realms/REALM-NAME/protocol/openid-connect/certs" - - issuer: "http://keycloak.default:8080/auth/realms/REALM-NAME" - jwksUri: "http://keycloak.default:8080/auth/realms/REALM-NAME/protocol/openid-connect/certs" - - issuer: "https://192.168.49.2:31561/auth/realms/REALM-NAME" - jwksUri: "https://192.168.49.2:31561/auth/realms/REALM-NAME/protocol/openid-connect/certs" - - issuer: "https://keycloak.default:8443/auth/realms/REALM-NAME" - jwksUri: "https://keycloak.default:8443/auth/realms/REALM-NAME/protocol/openid-connect/certs" - - issuer: "https://keycloak.est.tech:443/auth/realms/REALM-NAME" - jwksUri: "https://keycloak.default:8443/auth/realms/REALM-NAME/protocol/openid-connect/certs" - - issuer: "http://istio-ingressgateway.istio-system:80/auth/realms/REALM-NAME" - jwksUri: "http://keycloak.default:8080/auth/realms/REALM-NAME/protocol/openid-connect/certs" -` - -var authorizationPolicyManifest = ` -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "RAPP-NAME-policy" - namespace: RAPP-NS -spec: - selector: - matchLabels: - app.kubernetes.io/instance: RAPP-NAME - action: ALLOW - rules: - - from: - - source: - requestPrincipals: ["http://192.168.49.2:31560/auth/realms/REALM-NAME/", "http://keycloak.default:8080/auth/realms/REALM-NAME/", "https://192.168.49.2:31561/auth/realms/REALM-NAME/", "https://keycloak.default:8443/auth/realms/REALM-NAME/", "https://keycloak.est.tech:443/auth/realms/REALM-NAME/", "http://istio-ingressgateway.istio-system:80/auth/realms/REALM-NAME/"] - - to: - - operation: - methods: ["METHOD-NAME"] - paths: ["/RAPP-NAME"] - when: - - key: request.auth.claims[clientRole] - values: ["ROLE-NAME"] -` +type TemplateConfig struct { + Name string + Namespace string + Realm string + Client string + Authenticator string + Role string + Method string + TlsCrt string + TlsKey string + CaCrt string +} + +var inputs TemplateConfig +var appName string + +var config *template.Template func connectToK8s() *versioned.Clientset { config, err := rest.InClusterConfig() @@ -159,13 +87,17 @@ func connectToK8s() *versioned.Clientset { return ic } -func createGateway(clientset *versioned.Clientset, appName string) (string, error) { +func createGateway(clientset *versioned.Clientset) (string, error) { gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE) - manifest := strings.Replace(gatewayManifest, "RAPP-NAME", appName, -1) - manifest = strings.Replace(manifest, "RAPP-NS", NAMESPACE, -1) + config = template.Must(template.ParseFiles("./templates/Gateway-template.txt")) + var manifest bytes.Buffer + err := config.Execute(&manifest, inputs) + if err != nil { + return "", err + } gt := &netv1beta1.Gateway{} - dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest)), 1000) + dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000) if err := dec.Decode(>); err != nil { return "", err @@ -181,13 +113,17 @@ func createGateway(clientset *versioned.Clientset, appName string) (string, erro return result.GetName(), nil } -func createVirtualService(clientset *versioned.Clientset, appName string) (string, error) { +func createVirtualService(clientset *versioned.Clientset) (string, error) { vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE) - manifest := strings.Replace(virtualServiceManifest, "RAPP-NAME", appName, -1) - manifest = strings.Replace(manifest, "RAPP-NS", NAMESPACE, -1) + config = template.Must(template.ParseFiles("./templates/VirtualService-template.txt")) + var manifest bytes.Buffer + err := config.Execute(&manifest, inputs) + if err != nil { + return "", err + } vs := &netv1beta1.VirtualService{} - dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest)), 1000) + dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000) if err := dec.Decode(&vs); err != nil { return "", err @@ -203,14 +139,17 @@ func createVirtualService(clientset *versioned.Clientset, appName string) (strin return result.GetName(), nil } -func createRequestAuthentication(clientset *versioned.Clientset, appName, realmName string) (string, error) { +func createRequestAuthentication(clientset *versioned.Clientset) (string, error) { raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE) - manifest := strings.Replace(requestAuthenticationManifest, "RAPP-NAME", appName, -1) - manifest = strings.Replace(manifest, "REALM-NAME", realmName, -1) - manifest = strings.Replace(manifest, "RAPP-NS", NAMESPACE, -1) + config = template.Must(template.ParseFiles("./templates/RequestAuthentication-template.txt")) + var manifest bytes.Buffer + err := config.Execute(&manifest, inputs) + if err != nil { + return "", err + } ra := &secv1beta1.RequestAuthentication{} - dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest)), 1000) + dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000) if err := dec.Decode(&ra); err != nil { return "", err @@ -226,16 +165,17 @@ func createRequestAuthentication(clientset *versioned.Clientset, appName, realmN return result.GetName(), nil } -func createAuthorizationPolicy(clientset *versioned.Clientset, appName, realmName, roleName, methodName string) (string, error) { +func createAuthorizationPolicy(clientset *versioned.Clientset) (string, error) { apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE) - manifest := strings.Replace(authorizationPolicyManifest, "RAPP-NAME", appName, -1) - manifest = strings.Replace(manifest, "REALM-NAME", realmName, -1) - manifest = strings.Replace(manifest, "ROLE-NAME", roleName, -1) - manifest = strings.Replace(manifest, "METHOD-NAME", methodName, -1) - manifest = strings.Replace(manifest, "RAPP-NS", NAMESPACE, -1) + config = template.Must(template.ParseFiles("./templates/AuthorizationPolicy-template.txt")) + var manifest bytes.Buffer + err := config.Execute(&manifest, inputs) + if err != nil { + return "", err + } ap := &secv1beta1.AuthorizationPolicy{} - dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest)), 1000) + dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000) if err := dec.Decode(&ap); err != nil { return "", err @@ -251,7 +191,33 @@ func createAuthorizationPolicy(clientset *versioned.Clientset, appName, realmNam return result.GetName(), nil } -func removeGateway(clientset *versioned.Clientset, appName string) { +func createEnvoyFilter(clientset *versioned.Clientset) (string, error) { + efClient := clientset.NetworkingV1alpha3().EnvoyFilters(NAMESPACE) + config = template.Must(template.ParseFiles("./templates/EnvoyFilter-template.txt")) + var manifest bytes.Buffer + err := config.Execute(&manifest, inputs) + if err != nil { + return "", err + } + + ef := &netv1alpha3.EnvoyFilter{} + dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest.String())), 1000) + + if err = dec.Decode(&ef); err != nil { + return "", err + } + + result, err := efClient.Create(context.TODO(), ef, metav1.CreateOptions{}) + + if err != nil { + return "", err + } + + fmt.Printf("Create Envoy Filter %s \n", result.GetName()) + return result.GetName(), nil +} + +func removeGateway(clientset *versioned.Clientset) { gtClient := clientset.NetworkingV1beta1().Gateways(NAMESPACE) err := gtClient.Delete(context.TODO(), "nonrtric-istio-"+appName+"-gateway", metav1.DeleteOptions{}) if err != nil { @@ -261,7 +227,7 @@ func removeGateway(clientset *versioned.Clientset, appName string) { } } -func removeVirtualService(clientset *versioned.Clientset, appName string) { +func removeVirtualService(clientset *versioned.Clientset) { vsClient := clientset.NetworkingV1beta1().VirtualServices(NAMESPACE) err := vsClient.Delete(context.TODO(), "nonrtric-istio-"+appName+"-vs", metav1.DeleteOptions{}) if err != nil { @@ -271,7 +237,7 @@ func removeVirtualService(clientset *versioned.Clientset, appName string) { } } -func removeRequestAuthentication(clientset *versioned.Clientset, appName string) { +func removeRequestAuthentication(clientset *versioned.Clientset) { raClient := clientset.SecurityV1beta1().RequestAuthentications(NAMESPACE) err := raClient.Delete(context.TODO(), "jwt-"+appName, metav1.DeleteOptions{}) if err != nil { @@ -281,7 +247,7 @@ func removeRequestAuthentication(clientset *versioned.Clientset, appName string) } } -func removeAuthorizationPolicy(clientset *versioned.Clientset, appName string) { +func removeAuthorizationPolicy(clientset *versioned.Clientset) { apClient := clientset.SecurityV1beta1().AuthorizationPolicies(NAMESPACE) err := apClient.Delete(context.TODO(), appName+"-policy", metav1.DeleteOptions{}) if err != nil { @@ -291,30 +257,41 @@ func removeAuthorizationPolicy(clientset *versioned.Clientset, appName string) { } } +func removeEnvoyFilter(clientset *versioned.Clientset) { + efClient := clientset.NetworkingV1alpha3().EnvoyFilters(NAMESPACE) + err := efClient.Delete(context.TODO(), appName+"-outbound-filter", metav1.DeleteOptions{}) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("Deleted EnvoyFilter " + appName + "-outbound-filter") + } +} + func createIstioPolicy(res http.ResponseWriter, req *http.Request) { query := req.URL.Query() realmName := query.Get("realm") appName := query.Get("name") roleName := query.Get("role") methodName := query.Get("method") + inputs = TemplateConfig{Name: appName, Namespace: NAMESPACE, Realm: realmName, Role: roleName, Method: methodName} var msg string clientset := connectToK8s() - _, err := createGateway(clientset, appName) + _, err := createGateway(clientset) if err != nil { msg = err.Error() fmt.Println(err.Error()) } else { - _, err := createVirtualService(clientset, appName) + _, err := createVirtualService(clientset) if err != nil { msg = err.Error() fmt.Println(err.Error()) } else { - _, err := createRequestAuthentication(clientset, appName, realmName) + _, err := createRequestAuthentication(clientset) if err != nil { msg = err.Error() fmt.Println(err.Error()) } else { - _, err := createAuthorizationPolicy(clientset, appName, realmName, roleName, methodName) + _, err := createAuthorizationPolicy(clientset) if err != nil { msg = err.Error() fmt.Println(err.Error()) @@ -331,20 +308,55 @@ func createIstioPolicy(res http.ResponseWriter, req *http.Request) { res.Write(data) } -func removeIstioPolicy(res http.ResponseWriter, req *http.Request) { +func createIstioFilter(res http.ResponseWriter, req *http.Request) { query := req.URL.Query() + realmName := query.Get("realm") + clientId := query.Get("client") appName := query.Get("name") + authType := query.Get("authType") + tlsCrt := query.Get("tlsCrt") + tlsKey := query.Get("tlsKey") + caCrt := query.Get("caCrt") + inputs = TemplateConfig{Name: appName, Namespace: NAMESPACE, Realm: realmName, Client: clientId, + Authenticator: authType, TlsCrt: tlsCrt, TlsKey: tlsKey, CaCrt: caCrt} + var msg string + clientset := connectToK8s() + _, err := createEnvoyFilter(clientset) + if err != nil { + msg = err.Error() + fmt.Println(err.Error()) + } + // create response binary data + data := []byte(msg) // slice of bytes + // write `data` to response + res.Write(data) +} + +func removeIstioPolicy(res http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + appName = query.Get("name") + clientset := connectToK8s() + removeAuthorizationPolicy(clientset) + removeRequestAuthentication(clientset) + removeVirtualService(clientset) + removeGateway(clientset) +} + +func removeIstioFilter(res http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + appName = query.Get("name") clientset := connectToK8s() - removeAuthorizationPolicy(clientset, appName) - removeRequestAuthentication(clientset, appName) - removeVirtualService(clientset, appName) - removeGateway(clientset, appName) + removeEnvoyFilter(clientset) } func main() { - createIstioHandler := http.HandlerFunc(createIstioPolicy) - http.Handle("/create", createIstioHandler) - removeIstioHandler := http.HandlerFunc(removeIstioPolicy) - http.Handle("/remove", removeIstioHandler) + createIstioPolicyHandler := http.HandlerFunc(createIstioPolicy) + http.Handle("/create-policy", createIstioPolicyHandler) + removeIstioPolicyHandler := http.HandlerFunc(removeIstioPolicy) + http.Handle("/remove-policy", removeIstioPolicyHandler) + createIstioFilterHandler := http.HandlerFunc(createIstioFilter) + http.Handle("/create-filter", createIstioFilterHandler) + removeIstioFilterHandler := http.HandlerFunc(removeIstioFilter) + http.Handle("/remove-filter", removeIstioFilterHandler) http.ListenAndServe(":9000", nil) }