Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2alpha1 AuthorizationPolicy processor #1211

Merged
merged 16 commits into from
Aug 6, 2024
Merged
55 changes: 26 additions & 29 deletions apis/gateway/v2alpha1/gateway_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,43 @@
package v2alpha1_test

import (
"fmt"
"os"
"github.com/kyma-project/api-gateway/apis/gateway/v2alpha1"
"github.com/kyma-project/api-gateway/tests"
rulev1alpha1 "github.com/ory/oathkeeper-maester/api/v1alpha1"
networkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
securityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"

. "github.com/onsi/ginkgo/v2"
"github.com/onsi/ginkgo/v2/reporters"
"github.com/onsi/ginkgo/v2/types"
. "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

func TestGatewayv2alpha1(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Gateway v2alpha1 Suite")
}

const reportFilename = "junit-gateway-v2alpha1.xml"

var _ = ReportAfterSuite("custom reporter", func(report types.Report) {
logger := zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter))

if key, ok := os.LookupEnv("ARTIFACTS"); ok {
reportsPath := fmt.Sprintf("%s/%s", key, reportFilename)
logger.Info("Generating reports at", "location", reportsPath)
err := reporters.GenerateJUnitReport(report, reportsPath)

if err != nil {
logger.Error(err, "Junit Report Generation Error")
}
} else {
if err := os.MkdirAll("../../reports", 0755); err != nil {
logger.Error(err, "could not create directory")
}

reportsPath := fmt.Sprintf("%s/%s", "../../reports", reportFilename)
logger.Info("Generating reports at", "location", reportsPath)
err := reporters.GenerateJUnitReport(report, reportsPath)

if err != nil {
logger.Error(err, "Junit Report Generation Error")
}
}
tests.GenerateGinkgoJunitReport("gateway-v2alpha1", report)
})

func createFakeClient(objs ...client.Object) client.Client {
scheme := runtime.NewScheme()
err := networkingv1beta1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())
err = rulev1alpha1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())
err = securityv1beta1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())
err = v2alpha1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())
err = corev1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

return fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
}
84 changes: 84 additions & 0 deletions apis/gateway/v2alpha1/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package v2alpha1

import (
"context"
"fmt"
apiv1beta1 "istio.io/api/type/v1beta1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func FindServiceNamespace(apiRule *APIRule, rule Rule) (string, error) {
// Fallback direction for the upstream service namespace: Rule.Service > Spec.Service > APIRule
if rule.Service != nil && rule.Service.Namespace != nil {
return *rule.Service.Namespace, nil
}

if apiRule == nil {
return "", fmt.Errorf("apiRule is nil")
}

if apiRule.Spec.Service != nil && apiRule.Spec.Service.Namespace != nil {
return *apiRule.Spec.Service.Namespace, nil
}

return apiRule.Namespace, nil
}

// PodSelector represents a service workload selector for a pod and the namespace of the service.
// +k8s:deepcopy-gen=false
type PodSelector struct {
Selector *apiv1beta1.WorkloadSelector
Namespace string
}

func GetSelectorFromService(ctx context.Context, client client.Client, apiRule *APIRule, rule Rule) (PodSelector, error) {

var service *Service
if rule.Service != nil {
service = rule.Service
} else {
service = apiRule.Spec.Service
}

if service == nil || service.Name == nil {
return PodSelector{}, fmt.Errorf("service name is required but missing")
}
serviceNamespacedName := types.NamespacedName{Name: *service.Name}
if service.Namespace != nil {
serviceNamespacedName.Namespace = *service.Namespace
} else {
ns, err := FindServiceNamespace(apiRule, rule)
if err != nil {
return PodSelector{}, fmt.Errorf("finding service namespace: %w", err)
}

serviceNamespacedName.Namespace = ns
}

if serviceNamespacedName.Namespace == "" {
serviceNamespacedName.Namespace = "default"
}

svc := &corev1.Service{}
err := client.Get(ctx, serviceNamespacedName, svc)
if err != nil {
return PodSelector{}, err
}

if len(svc.Spec.Selector) == 0 {
return PodSelector{}, nil
}

workloadSelector := apiv1beta1.WorkloadSelector{}
workloadSelector.MatchLabels = map[string]string{}
for label, value := range svc.Spec.Selector {
workloadSelector.MatchLabels[label] = value
}

return PodSelector{
Selector: &workloadSelector,
Namespace: serviceNamespacedName.Namespace,
}, nil
}
Loading