-// -\r
-// ========================LICENSE_START=================================\r
-// O-RAN-SC\r
-// %%\r
-// Copyright (C) 2024: OpenInfra Foundation Europe\r
-// %%\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-// http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-// ========================LICENSE_END===================================\r
-//\r
-\r
-package kongclear\r
-\r
-import (\r
- "encoding/json"\r
- "fmt"\r
- "net/http"\r
-\r
- log "github.com/sirupsen/logrus"\r
- resty "github.com/go-resty/resty/v2"\r
-)\r
-\r
-// Service represents the structure for Kong service creation\r
-type KongService struct {\r
- ID string `json:"id"`\r
- Name string `json:"name"`\r
- URL string `json:"url"`\r
-}\r
-\r
-type KongServiceResponse struct {\r
- ID string `json:"id"`\r
-}\r
-\r
-type ServiceResponse struct {\r
- Data []KongService `json:"data"`\r
-}\r
-\r
-type KongRoute struct {\r
- ID string `json:"id"`\r
- Name string `json:"name"`\r
- Paths []string `json:"paths"`\r
- Service Service `json:"service"`\r
- StripPath bool `json:"strip_path"`\r
-}\r
-\r
-type RouteResponse struct {\r
- Data []KongRoute `json:"data"`\r
-}\r
-\r
-type Service struct {\r
- ID string `json:"id"`\r
-}\r
-\r
-func KongClear(myEnv map[string]string, myPorts map[string]int) error {\r
- log.Info("attempting to delete all Kong routes and services")\r
-\r
- kongAdminApiUrl := fmt.Sprintf("%s://%s:%d/", myEnv["KONG_PROTOCOL"], myEnv["KONG_IPV4"], myPorts["KONG_CONTROL_PLANE_PORT"])\r
-\r
- err := deleteAllRoutes(kongAdminApiUrl)\r
- if err != nil {\r
- log.Fatalf("error deleting routes %v", err)\r
- return err\r
- }\r
-\r
- err = deleteAllServices(kongAdminApiUrl)\r
- if err != nil {\r
- log.Fatalf("error deleting services %v", err)\r
- return err\r
- }\r
-\r
- log.Info("all Kong routes and services deleted successfully")\r
- return err\r
-}\r
-\r
-\r
-func deleteAllRoutes(kongAdminApiUrl string) error {\r
- routes, err := listRoutes(kongAdminApiUrl)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- for _, route := range routes {\r
- if err := deleteRoute(kongAdminApiUrl, route.ID); err != nil {\r
- return err\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func deleteAllServices(kongAdminApiUrl string) error {\r
- services, err := listServices(kongAdminApiUrl)\r
- if err != nil {\r
- return err\r
- }\r
-\r
- for _, service := range services {\r
- if err := deleteService(kongAdminApiUrl, service.ID); err != nil {\r
- return err\r
- }\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func listServices(kongAdminApiUrl string) ([]KongService, error) {\r
- client := resty.New()\r
- resp, err := client.R().Get(kongAdminApiUrl + "services")\r
-\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- if resp.StatusCode() != http.StatusOK {\r
- err := fmt.Errorf("failed to list services, status code %d", resp.StatusCode())\r
- return nil, err\r
- }\r
-\r
- var serviceResponse ServiceResponse\r
- err = json.Unmarshal(resp.Body(), &serviceResponse)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- log.Infof("kong services %v", serviceResponse.Data)\r
- return serviceResponse.Data, nil\r
-}\r
-\r
-func listRoutes(kongAdminApiUrl string) ([]KongRoute, error) {\r
- client := resty.New()\r
- resp, err := client.R().\r
- Get(kongAdminApiUrl + "routes")\r
-\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- if resp.StatusCode() != http.StatusOK {\r
- err := fmt.Errorf("failed to list routes, status code %d", resp.StatusCode())\r
- return nil, err\r
- }\r
-\r
- var routeResponse RouteResponse\r
- err = json.Unmarshal(resp.Body(), &routeResponse)\r
- if err != nil {\r
- return nil, err\r
- }\r
-\r
- log.Infof("kong routes %v", routeResponse.Data)\r
- return routeResponse.Data, nil\r
-}\r
-\r
-func deleteService(kongAdminApiUrl string, serviceID string) error {\r
- log.Tracef("entering deleteService service ID %v", serviceID)\r
- client := resty.New()\r
- resp, err := client.R().Delete(kongAdminApiUrl + "services/" + serviceID)\r
-\r
- if err != nil {\r
- return err\r
- }\r
-\r
- if resp.StatusCode() != http.StatusNoContent {\r
- err := fmt.Errorf("failed to delete service %s, status code %d", serviceID, resp.StatusCode())\r
- return err\r
- }\r
-\r
- return nil\r
-}\r
-\r
-func deleteRoute(kongAdminApiUrl string, routeID string) error {\r
- log.Infof("kong route id %v", routeID)\r
- client := resty.New()\r
- resp, err := client.R().Delete(kongAdminApiUrl + "routes/" + routeID)\r
-\r
- if err != nil {\r
- return err\r
- }\r
-\r
- if resp.StatusCode() != http.StatusNoContent {\r
- err := fmt.Errorf("failed to delete route %s, status code %d", routeID, resp.StatusCode())\r
- return err\r
- }\r
-\r
- return nil\r
-}
\ No newline at end of file
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2024: OpenInfra Foundation Europe
+// %%
+// 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.
+// ========================LICENSE_END===================================
+//
+
+package kongclear
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+
+ resty "github.com/go-resty/resty/v2"
+ log "github.com/sirupsen/logrus"
+)
+
+// Service represents the structure for Kong service creation
+type KongService struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ URL string `json:"url"`
+ Tags []string `json:"tags"`
+}
+
+type KongServiceResponse struct {
+ ID string `json:"id"`
+}
+
+type ServiceResponse struct {
+ Data []KongService `json:"data"`
+}
+
+type KongRoute struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Paths []string `json:"paths"`
+ Service Service `json:"service"`
+ StripPath bool `json:"strip_path"`
+ Tags []string `json:"tags"`
+}
+
+type RouteResponse struct {
+ Data []KongRoute `json:"data"`
+}
+
+type Service struct {
+ ID string `json:"id"`
+}
+
+func KongClear(myEnv map[string]string, myPorts map[string]int) error {
+ log.Info("delete only ServiceManager Kong routes and services")
+
+ kongAdminApiUrl := fmt.Sprintf("%s://%s:%d/", myEnv["KONG_PROTOCOL"], myEnv["KONG_IPV4"], myPorts["KONG_CONTROL_PLANE_PORT"])
+
+ err := deleteRoutes(kongAdminApiUrl)
+ if err != nil {
+ log.Fatalf("error deleting routes %v", err)
+ return err
+ }
+
+ err = deleteServices(kongAdminApiUrl)
+ if err != nil {
+ log.Fatalf("error deleting services %v", err)
+ return err
+ }
+
+ log.Info("finished deleting only ServiceManger Kong routes and services")
+ return err
+}
+
+func deleteRoutes(kongAdminApiUrl string) error {
+ routes, err := listRoutes(kongAdminApiUrl)
+ if err != nil {
+ return err
+ }
+
+ for _, route := range routes {
+ if areServiceManagerTags(route.Tags) {
+ if err := deleteRoute(kongAdminApiUrl, route.ID); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func deleteServices(kongAdminApiUrl string) error {
+ services, err := listServices(kongAdminApiUrl)
+ if err != nil {
+ return err
+ }
+
+ for _, service := range services {
+ if areServiceManagerTags(service.Tags) {
+ if err := deleteService(kongAdminApiUrl, service.ID); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func listRoutes(kongAdminApiUrl string) ([]KongRoute, error) {
+ client := resty.New()
+ resp, err := client.R().
+ Get(kongAdminApiUrl + "routes")
+
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode() != http.StatusOK {
+ err := fmt.Errorf("failed to list routes, status code %d", resp.StatusCode())
+ return nil, err
+ }
+
+ var routeResponse RouteResponse
+ err = json.Unmarshal(resp.Body(), &routeResponse)
+ if err != nil {
+ return nil, err
+ }
+
+ log.Infof("kong routes %v", routeResponse.Data)
+ return routeResponse.Data, nil
+}
+
+func listServices(kongAdminApiUrl string) ([]KongService, error) {
+ client := resty.New()
+ resp, err := client.R().Get(kongAdminApiUrl + "services")
+
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode() != http.StatusOK {
+ err := fmt.Errorf("failed to list services, status code %d", resp.StatusCode())
+ return nil, err
+ }
+
+ var serviceResponse ServiceResponse
+ err = json.Unmarshal(resp.Body(), &serviceResponse)
+ if err != nil {
+ return nil, err
+ }
+
+ log.Infof("kong services %v", serviceResponse.Data)
+ return serviceResponse.Data, nil
+}
+
+func areServiceManagerTags(tags []string) bool {
+ tagMap := make(map[string]string)
+
+ for _, tag := range tags {
+ log.Debugf("found tag %s", tag)
+ tagSlice := strings.Split(tag, ":")
+ log.Debugf("tag slice %v", tagSlice)
+ if (len(tagSlice) > 0) && (tagSlice[0] != "") {
+ if (len(tagSlice) > 1) {
+ tagMap[tagSlice[0]] = tagSlice[1]
+ } else {
+ tagMap[tagSlice[0]] = ""
+ }
+ }
+ }
+
+ if tagMap["apfId"] == "" {
+ log.Debug("did NOT find apfId")
+ return false
+ }
+ log.Debugf("found valid apfId %s", tagMap["apfId"])
+
+ if tagMap["aefId"] == "" {
+ log.Debug("did NOT find aefId")
+ return false
+ }
+ log.Debugf("found valid aefId %s", tagMap["aefId"])
+
+ if tagMap["apiId"] == "" {
+ log.Debug("did NOT find apiId")
+ return false
+ }
+ log.Debugf("found valid apiId %s", tagMap["apiId"])
+
+ return true
+}
+
+func deleteRoute(kongAdminApiUrl string, routeID string) error {
+ log.Infof("delete kong route id %s", routeID)
+ client := resty.New()
+ resp, err := client.R().Delete(kongAdminApiUrl + "routes/" + routeID)
+
+ if err != nil {
+ return err
+ }
+
+ if resp.StatusCode() != http.StatusNoContent {
+ err := fmt.Errorf("failed to delete route %s, status code %d", routeID, resp.StatusCode())
+ return err
+ }
+
+ return nil
+}
+
+func deleteService(kongAdminApiUrl string, serviceID string) error {
+ log.Infof("delete kong service id %s", serviceID)
+ client := resty.New()
+ resp, err := client.R().Delete(kongAdminApiUrl + "services/" + serviceID)
+
+ if err != nil {
+ return err
+ }
+
+ if resp.StatusCode() != http.StatusNoContent {
+ err := fmt.Errorf("failed to delete service %s, status code %d", serviceID, resp.StatusCode())
+ return err
+ }
+
+ return nil
+}
sd.ApiId = &apiName
}
-func (sd *ServiceAPIDescription) RegisterKong(kongDomain string, kongProtocol string, kongIPv4 common29122.Ipv4Addr, kongDataPlanePort common29122.Port, kongControlPlanePort common29122.Port) (int, error) {
+func (sd *ServiceAPIDescription) RegisterKong(kongDomain string,
+ kongProtocol string,
+ kongIPv4 common29122.Ipv4Addr,
+ kongDataPlanePort common29122.Port,
+ kongControlPlanePort common29122.Port,
+ apfId string) (int, error) {
+
log.Trace("entering RegisterKong")
var (
statusCode int
)
kongControlPlaneURL := fmt.Sprintf("%s://%s:%d", kongProtocol, kongIPv4, kongControlPlanePort)
- statusCode, err = sd.createKongRoutes(kongControlPlaneURL)
+ statusCode, err = sd.createKongRoutes(kongControlPlaneURL, apfId)
if (err != nil) || (statusCode != http.StatusCreated) {
return statusCode, err
}
return statusCode, nil
}
-func (sd *ServiceAPIDescription) createKongRoutes(kongControlPlaneURL string) (int, error) {
+func (sd *ServiceAPIDescription) createKongRoutes(kongControlPlaneURL string, apfId string) (int, error) {
log.Trace("entering createKongRoutes")
var (
statusCode int
for _, version := range profile.Versions {
log.Debugf("createKongRoutes, apiVersion \"%s\"", version.ApiVersion)
for _, resource := range *version.Resources {
- statusCode, err = sd.createKongRoute(kongControlPlaneURL, client, resource, profile.AefId, version.ApiVersion)
+ statusCode, err = sd.createKongRoute(kongControlPlaneURL, client, resource, apfId, profile.AefId, version.ApiVersion)
if (err != nil) || (statusCode != http.StatusCreated) {
return statusCode, err
}
return statusCode, nil
}
-func (sd *ServiceAPIDescription) createKongRoute(kongControlPlaneURL string, client *resty.Client, resource Resource, aefId string, apiVersion string) (int, error) {
+func (sd *ServiceAPIDescription) createKongRoute(
+ kongControlPlaneURL string,
+ client *resty.Client,
+ resource Resource,
+ apfId string,
+ aefId string,
+ apiVersion string ) (int, error) {
log.Trace("entering createKongRoute")
- uri := resource.Uri
- if apiVersion != "" {
- if apiVersion[0] != '/' {
- apiVersion = "/" + apiVersion
- }
- if apiVersion[len(apiVersion)-1] != '/' && resource.Uri[0] != '/' {
- apiVersion = apiVersion + "/"
- }
- uri = apiVersion + resource.Uri
- }
+ resourceName := resource.ResourceName
+ apiId := *sd.ApiId
- log.Debugf("createKongRoute, uri %s", uri)
+ tags := buildTags(apfId, aefId, apiId, apiVersion, resourceName)
+ log.Debugf("createKongRoute, tags %s", tags)
+
+ serviceName := apiId + "_" + resourceName
+ routeName := serviceName
- serviceName := *sd.ApiId + "_" + resource.ResourceName
log.Debugf("createKongRoute, serviceName %s", serviceName)
+ log.Debugf("createKongRoute, routeName %s", routeName)
log.Debugf("createKongRoute, aefId %s", aefId)
- statusCode, err := sd.createKongService(kongControlPlaneURL, serviceName, uri, aefId)
+ uri := buildUriWithVersion(apiVersion, resource.Uri)
+ log.Debugf("createKongRoute, uri %s", uri)
+
+ statusCode, err := sd.createKongService(kongControlPlaneURL, serviceName, uri, tags)
if (err != nil) || (statusCode != http.StatusCreated) {
return statusCode, err
}
- routeName := serviceName
kongRoutesURL := kongControlPlaneURL + "/services/" + serviceName + "/routes"
// Define the route information for Kong
"name": routeName,
"paths": []string{uri},
"methods": resource.Operations,
- "tags": []string{aefId},
+ "tags": tags,
"strip_path": true,
}
return resp.StatusCode(), nil
}
-func (sd *ServiceAPIDescription) createKongService(kongControlPlaneURL string, kongServiceName string, kongServiceUri string, aefId string) (int, error) {
+func buildUriWithVersion(apiVersion string, uri string) string {
+ if apiVersion != "" {
+ if apiVersion[0] != '/' {
+ apiVersion = "/" + apiVersion
+ }
+ if apiVersion[len(apiVersion)-1] != '/' && uri[0] != '/' {
+ apiVersion = apiVersion + "/"
+ }
+ uri = apiVersion + uri
+ }
+ return uri
+}
+
+func buildTags(apfId string, aefId string, apiId string, apiVersion string, resourceName string) []string {
+ tagsMap := map[string]string{
+ "apfId": apfId,
+ "aefId": aefId,
+ "apiId": apiId,
+ "apiVersion": apiVersion,
+ "resourceName": resourceName,
+ }
+
+ // Convert the map to a slice of strings
+ var tagsSlice []string
+ for key, value := range tagsMap {
+ str := fmt.Sprintf("%s: %s", key, value)
+ tagsSlice = append(tagsSlice, str)
+ }
+
+ return tagsSlice
+}
+
+func (sd *ServiceAPIDescription) createKongService(kongControlPlaneURL string, kongServiceName string, kongServiceUri string, tags []string) (int, error) {
log.Tracef("entering createKongService")
log.Tracef("createKongService, kongServiceName %s", kongServiceName)
"port": firstAEFProfilePort,
"protocol": kongControlPlaneURLParsed.Scheme,
"path": kongServiceUri,
- "tags": []string{aefId},
+ "tags": tags,
}
// Kong admin API endpoint for creating a service