NONRTRIC-946: Add support for Kong routes
[nonrtric/plt/sme.git] / servicemanager / internal / kongclear / kongclear.go
diff --git a/servicemanager/internal/kongclear/kongclear.go b/servicemanager/internal/kongclear/kongclear.go
new file mode 100644 (file)
index 0000000..068cd7d
--- /dev/null
@@ -0,0 +1,194 @@
+// -\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