// -
-// ========================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"
"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()
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
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
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
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
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 {
}
}
-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 {
}
}
-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 {
}
}
-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 {
}
}
+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())
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)
}