Skip to content

Commit

Permalink
fix httproute vhost issue
Browse files Browse the repository at this point in the history
  • Loading branch information
tharindu1st committed Feb 16, 2024
1 parent b56e34c commit afc4d49
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 86 deletions.
34 changes: 29 additions & 5 deletions apim-apk-agent/internal/eventhub/dataloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ import (
"time"

loggers "github.com/sirupsen/logrus"
dpv1alpha2 "github.com/wso2/apk/common-go-libs/apis/dp/v1alpha2"
"github.com/wso2/product-apim-tooling/apim-apk-agent/config"
internalk8sClient "github.com/wso2/product-apim-tooling/apim-apk-agent/internal/k8sClient"
internalutils "github.com/wso2/product-apim-tooling/apim-apk-agent/internal/utils"
"sigs.k8s.io/controller-runtime/pkg/client"

pkgAuth "github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/auth"
"github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/eventhub/types"
logger "github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/loggers"
"github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/tlsutils"
"github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/utils"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
Expand All @@ -50,8 +51,6 @@ const (
GatewayLabelParam string = "gatewayLabel"
// APIUUIDParam is required to call /apis endpoint
APIUUIDParam string = "apiId"
// ApisEndpoint is the resource path of /apis endpoint
ApisEndpoint string = "apis"
)

var (
Expand Down Expand Up @@ -232,5 +231,30 @@ func retrieveDataFromResponseChannel(response response) {
// FetchAPIsOnStartUp APIs from control plane during the server start up and push them
// to the router and enforcer components.
func FetchAPIsOnStartUp(conf *config.Config, k8sClient client.Client) {
internalutils.FetchAPIsOnEvent(conf, nil, k8sClient)
k8sAPIS, _, err := internalk8sClient.RetrieveAllAPISFromK8s(k8sClient, "")
if err != nil {
logger.LoggerSubscription.Errorf("Error occurred while fetching APIs from K8s %v", err)
}
apis, err := internalutils.FetchAPIsOnEvent(conf, nil, k8sClient)
if err != nil {
logger.LoggerSubscription.Errorf("Error occurred while fetching APIs from control plane %v", err)
}
removeApis := make([]dpv1alpha2.API, 0)
for _, k8sAPI := range k8sAPIS {
found := false
for _, api := range *apis {
if k8sAPI.Name == api {
found = true
break
}
}
if !found {
removeApis = append(removeApis, k8sAPI)
}
}
for _, removeAPI := range removeApis {
if !removeAPI.Spec.SystemAPI {
internalk8sClient.UndeployAPICR(removeAPI.Name, k8sClient)
}
}
}
77 changes: 36 additions & 41 deletions apim-apk-agent/internal/k8sClient/k8s_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ import (

dpv1alpha1 "github.com/wso2/apk/common-go-libs/apis/dp/v1alpha1"
dpv1alpha2 "github.com/wso2/apk/common-go-libs/apis/dp/v1alpha2"
"github.com/wso2/apk/common-go-libs/utils"
"github.com/wso2/product-apim-tooling/apim-apk-agent/config"
"github.com/wso2/product-apim-tooling/apim-apk-agent/internal/loggers"
"github.com/wso2/product-apim-tooling/apim-apk-agent/internal/logging"
eventhubTypes "github.com/wso2/product-apim-tooling/apim-apk-agent/pkg/eventhub/types"
corev1 "k8s.io/api/core/v1"
k8error "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
Expand Down Expand Up @@ -61,52 +64,19 @@ func DeployAPICR(api *dpv1alpha2.API, k8sClient client.Client) {

// UndeployAPICR removes the API Custom Resource from the Kubernetes cluster based on API ID label.
func UndeployAPICR(apiID string, k8sClient client.Client) {
// Define a list to hold API CRs with matching label
apiList := &dpv1alpha2.APIList{}

// Retrieve all API CRs from the Kubernetes cluster
if err := k8sClient.List(context.Background(), apiList); err != nil {
loggers.LoggerXds.Errorf("Unable to list API CRs: %v", err)
}

// Iterate over each API CR and check if it has the matching label
for _, api := range apiList.Items {
labels := api.GetLabels()
if labels["apiUUID"] == apiID {
// Found the API CR with the matching label, delete it
if err := k8sClient.Delete(context.Background(), &api); err != nil {
loggers.LoggerXds.Errorf("Unable to delete API CR: %v", err)
}
loggers.LoggerXds.Infof("Deleted API CR: %s", api.Name)
}
conf, errReadConfig := config.ReadConfigs()
if errReadConfig != nil {
loggers.LoggerXds.Errorf("Error reading configurations: %v", errReadConfig)
}
}

// UndeployAPICRs removes the API Custom Resources from the Kubernetes cluster
// that are not included in the provided apiUUID list.
func UndeployAPICRs(apiUUIDs []string, k8sClient client.Client) {
// Define a list to hold API CRs with matching label
apiList := &dpv1alpha2.APIList{}

api := &dpv1alpha2.API{}
// Retrieve all API CRs from the Kubernetes cluster
if err := k8sClient.List(context.Background(), apiList); err != nil {
if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: apiID, Namespace: conf.DataPlane.Namespace}, api); err != nil {
loggers.LoggerXds.Errorf("Unable to list API CRs: %v", err)
}

// Iterate over each API CR and check if it has a matching label
for _, api := range apiList.Items {
if !api.Spec.SystemAPI {
// Check if the API CR's UUID is not in the provided list
if !contains(apiUUIDs, api.GetLabels()["apiUUID"]) {
// Delete the API CR
if err := k8sClient.Delete(context.Background(), &api); err != nil {
loggers.LoggerXds.Errorf("Unable to delete API CR: %v", err)
} else {
loggers.LoggerXds.Infof("Deleted API CR: %s", api.Name)
}
}
}
if err := k8sClient.Delete(context.Background(), api); err != nil {
loggers.LoggerXds.Errorf("Unable to delete API CR: %v", err)
}
loggers.LoggerXds.Infof("Deleted API CR: %s", api.Name)
}

// contains checks if a string is present in a slice of strings
Expand Down Expand Up @@ -464,3 +434,28 @@ func getSha1Value(input string) string {
hashBytes := hasher.Sum(nil)
return hex.EncodeToString(hashBytes)
}

// RetrieveAllAPISFromK8s retrieves all the API CRs from the Kubernetes cluster
func RetrieveAllAPISFromK8s(k8sClient client.Client, nextToken string) ([]dpv1alpha2.API, string, error) {
apiList := dpv1alpha2.APIList{}
resolvedAPIList := make([]dpv1alpha2.API, 0)
var err error
if nextToken == "" {
err = k8sClient.List(context.Background(), &apiList, &client.ListOptions{Namespace: utils.GetOperatorPodNamespace()})
} else {
err = k8sClient.List(context.Background(), &apiList, &client.ListOptions{Namespace: utils.GetOperatorPodNamespace(), Continue: nextToken})
}
if err != nil {
loggers.LoggerSync.ErrorC(logging.PrintError(logging.Error1102, logging.CRITICAL, "Failed to get application from k8s %v", err.Error()))
return nil, "", err
}
resolvedAPIList = append(resolvedAPIList, apiList.Items...)
if apiList.Continue != "" {
tempAPIList, _, err := RetrieveAllAPISFromK8s(k8sClient, apiList.Continue)
if err != nil {
return nil, "", err
}
resolvedAPIList = append(resolvedAPIList, tempAPIList...)
}
return resolvedAPIList, apiList.Continue, nil
}
18 changes: 9 additions & 9 deletions apim-apk-agent/internal/mapper/cr_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,43 +42,43 @@ func MapAndCreateCR(k8sArtifact transformer.K8sArtifacts, k8sClient client.Clien
internalk8sClient.DeployAPICR(&k8sArtifact.API, k8sClient)
for _, apiPolicies := range k8sArtifact.APIPolicies {
apiPolicies.Namespace = namespace
internalk8sClient.DeployAPIPolicyCR(&apiPolicies, k8sClient)
internalk8sClient.DeployAPIPolicyCR(apiPolicies, k8sClient)
}
for _, httpRoutes := range k8sArtifact.HTTPRoutes {
httpRoutes.Namespace = namespace
internalk8sClient.DeployHTTPRouteCR(&httpRoutes, k8sClient)
internalk8sClient.DeployHTTPRouteCR(httpRoutes, k8sClient)
}
for _, backends := range k8sArtifact.Backends {
backends.Namespace = namespace
internalk8sClient.DeployBackendCR(&backends, k8sClient)
internalk8sClient.DeployBackendCR(backends, k8sClient)
}
for _, configMaps := range k8sArtifact.ConfigMaps {
configMaps.Namespace = namespace
internalk8sClient.DeployConfigMapCR(&configMaps, k8sClient)
internalk8sClient.DeployConfigMapCR(configMaps, k8sClient)
}
for _, authPolicies := range k8sArtifact.Authentication {
authPolicies.Namespace = namespace
internalk8sClient.DeployAuthenticationCR(&authPolicies, k8sClient)
internalk8sClient.DeployAuthenticationCR(authPolicies, k8sClient)
}
for _, interceptorServices := range k8sArtifact.InterceptorServices {
interceptorServices.Namespace = namespace
internalk8sClient.DeployInterceptorServicesCR(&interceptorServices, k8sClient)
internalk8sClient.DeployInterceptorServicesCR(interceptorServices, k8sClient)
}
if k8sArtifact.BackendJWT != nil {
k8sArtifact.BackendJWT.Namespace = namespace
internalk8sClient.DeployBackendJWTCR(k8sArtifact.BackendJWT, k8sClient)
}
for _, scopes := range k8sArtifact.Scopes {
scopes.Namespace = namespace
internalk8sClient.DeployScopeCR(&scopes, k8sClient)
internalk8sClient.DeployScopeCR(scopes, k8sClient)
}
for _, rateLimitPolicy := range k8sArtifact.RateLimitPolicies {
rateLimitPolicy.Namespace = namespace
internalk8sClient.DeployRateLimitPolicyCR(&rateLimitPolicy, k8sClient)
internalk8sClient.DeployRateLimitPolicyCR(rateLimitPolicy, k8sClient)
}
for _, secrets := range k8sArtifact.Secrets {
secrets.Namespace = namespace
internalk8sClient.DeploySecretCR(&secrets, k8sClient)
internalk8sClient.DeploySecretCR(secrets, k8sClient)
}
return nil
}
Expand Down
26 changes: 14 additions & 12 deletions apim-apk-agent/internal/utils/apis_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func init() {
}

// FetchAPIsOnEvent will fetch API from control plane during the API Notification Event
func FetchAPIsOnEvent(conf *config.Config, apiUUID *string, k8sClient client.Client) {
func FetchAPIsOnEvent(conf *config.Config, apiUUID *string, k8sClient client.Client) (*[]string, error) {
// Populate data from config.
apis := make([]string, 0)
envs := conf.ControlPlane.EnvironmentLabels

// Create a channel for the byte slice (response from the APIs from control plane)
Expand Down Expand Up @@ -84,22 +85,22 @@ func FetchAPIsOnEvent(conf *config.Config, apiUUID *string, k8sClient client.Cli

if err != nil {
logger.LoggerSync.Errorf("Error while reading zip: %v", err)
return
return nil, err
}
deploymentJSON, exists := apiFiles["deployments.json"]
if !exists {
logger.LoggerSync.Errorf("deployments.json not found")
return
return nil, err
}
deploymentJSONBytes, err := transformer.ReadContent(deploymentJSON)
if err != nil {
logger.LoggerSync.Errorf("Error while decoding the API Project Artifact: %v", err)
return
return nil, err
}
deploymentDescriptor, err := transformer.ProcessDeploymentDescriptor(deploymentJSONBytes)
if err != nil {
logger.LoggerSync.Errorf("Error while decoding the API Project Artifact: %v", err)
return
return nil, err
}
apiDeployments := deploymentDescriptor.Data.Deployments
if apiDeployments != nil {
Expand All @@ -109,38 +110,38 @@ func FetchAPIsOnEvent(conf *config.Config, apiUUID *string, k8sClient client.Cli
artifact, decodingError := transformer.DecodeAPIArtifact(apiZip)
if decodingError != nil {
logger.LoggerSync.Errorf("Error while decoding the API Project Artifact: %v", decodingError)
return
return nil, err
}
apkConf, apiUUID, revisionID, apkErr := transformer.GenerateAPKConf(artifact.APIJson, artifact.ClientCerts)
if apkErr != nil {
logger.LoggerSync.Errorf("Error while generating APK-Conf: %v", apkErr)
return
return nil, err
}
k8ResourceEndpoint := conf.DataPlane.K8ResourceEndpoint
crResponse, err := transformer.GenerateCRs(apkConf, artifact.Swagger, k8ResourceEndpoint)
if err != nil {
logger.LoggerSync.Errorf("Error occured in receiving the updated CRDs: %v", err)
return
return nil, err
}
transformer.UpdateCRS(crResponse, apiDeployment.Environments, apiDeployment.OrganizationID, apiUUID, fmt.Sprint(revisionID), "namespace")
mapperUtil.MapAndCreateCR(*crResponse, k8sClient)
apis = append(apis, apiUUID)
logger.LoggerMsg.Info("API applied successfully.\n")
}
}
return &apis, nil
}

} else if data.ErrorCode == 204 {
logger.LoggerMsg.Infof("No API Artifacts are available in the control plane for the envionments :%s",
strings.Join(envs, ", "))
//health.SetControlPlaneRestAPIStatus(true)
return &[]string{}, nil
} else if data.ErrorCode >= 400 && data.ErrorCode < 500 {
logger.LoggerMsg.ErrorC(logging.ErrorDetails{
Message: fmt.Sprintf("Error occurred when retrieving APIs from control plane(unrecoverable error): %v", data.Err.Error()),
Severity: logging.CRITICAL,
ErrorCode: 1106,
})
//isNoAPIArtifacts := data.ErrorCode == 404 && strings.Contains(data.Err.Error(), "No Api artifacts found")
//health.SetControlPlaneRestAPIStatus(isNoAPIArtifacts)
return nil, data.Err
} else {
// Keep the iteration still until all the envrionment response properly.
logger.LoggerMsg.ErrorC(logging.ErrorDetails{
Expand All @@ -152,6 +153,7 @@ func FetchAPIsOnEvent(conf *config.Config, apiUUID *string, k8sClient client.Cli
sync.RetryFetchingAPIs(c, data, sync.RuntimeArtifactEndpoint, true)
}
logger.LoggerMsg.Info("Fetching API for an event is completed...")
return nil, nil
}

// GetAPI function calls the FetchAPIs() with relevant environment labels defined in the config.
Expand Down
18 changes: 9 additions & 9 deletions apim-apk-agent/pkg/transformer/k8s_artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
// K8sArtifacts k8s artifact representation of API
type K8sArtifacts struct {
API dpv1alpha2.API
HTTPRoutes map[string]gwapiv1b1.HTTPRoute
Backends map[string]v1alpha1.Backend
Scopes map[string]v1alpha1.Scope
Authentication map[string]dpv1alpha2.Authentication
APIPolicies map[string]dpv1alpha2.APIPolicy
InterceptorServices map[string]v1alpha1.InterceptorService
ConfigMaps map[string]corev1.ConfigMap
Secrets map[string]corev1.Secret
HTTPRoutes map[string]*gwapiv1b1.HTTPRoute
Backends map[string]*v1alpha1.Backend
Scopes map[string]*v1alpha1.Scope
Authentication map[string]*dpv1alpha2.Authentication
APIPolicies map[string]*dpv1alpha2.APIPolicy
InterceptorServices map[string]*v1alpha1.InterceptorService
ConfigMaps map[string]*corev1.ConfigMap
Secrets map[string]*corev1.Secret
BackendJWT *v1alpha1.BackendJWT
RateLimitPolicies map[string]v1alpha1.RateLimitPolicy
RateLimitPolicies map[string]*v1alpha1.RateLimitPolicy
}
Loading

0 comments on commit afc4d49

Please sign in to comment.