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

Add AdminNetworkPolicy #9206

Merged
merged 21 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ image:
# using a local kind cluster.
###############################################################################
E2E_FOCUS ?= "sig-network.*Conformance"
ADMINPOLICY_UNSUPPORTED_FEATURES ?= "BaselineAdminNetworkPolicy"
e2e-test:
$(MAKE) -C e2e build
$(MAKE) -C node kind-k8st-setup
KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/e2e.test -ginkgo.focus=$(E2E_FOCUS)
KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/k8s/e2e.test -ginkgo.focus=$(E2E_FOCUS)
KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/adminpolicy/e2e.test -exempt-features=$(ADMINPOLICY_UNSUPPORTED_FEATURES)

###############################################################################
# Release logic below
Expand Down
3 changes: 2 additions & 1 deletion api/pkg/apis/projectcalico/v3/tier.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ type Tier struct {
}

const (
DefaultTierOrder = float64(1_000_000) // 1 Million
DefaultTierOrder = float64(1_000_000) // 1Million
AdminNetworkPolicyTierOrder = float64(1_000) // 1K
)

// TierSpec contains the specification for a security policy tier resource.
Expand Down
8 changes: 4 additions & 4 deletions apiserver/pkg/storage/calico/policy_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (

v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"

"github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion"
"github.com/projectcalico/calico/libcalico-go/lib/clientv3"
cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors"
"github.com/projectcalico/calico/libcalico-go/lib/names"
"github.com/projectcalico/calico/libcalico-go/lib/options"
"github.com/projectcalico/calico/libcalico-go/lib/watch"
)
Expand All @@ -27,7 +27,7 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory
createFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) {
oso := opts.(options.SetOptions)
res := obj.(*v3.NetworkPolicy)
if strings.HasPrefix(res.Name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(res.Name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "create or apply",
Identifier: obj,
Expand All @@ -39,7 +39,7 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory
updateFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) {
oso := opts.(options.SetOptions)
res := obj.(*v3.NetworkPolicy)
if strings.HasPrefix(res.Name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(res.Name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "update or apply",
Identifier: obj,
Expand All @@ -54,7 +54,7 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory
}
deleteFn := func(ctx context.Context, c clientv3.Interface, ns string, name string, opts clientOpts) (resourceObject, error) {
odo := opts.(options.DeleteOptions)
if strings.HasPrefix(name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "delete",
Identifier: name,
Expand Down
11 changes: 9 additions & 2 deletions apiserver/pkg/storage/calico/tier_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

"github.com/projectcalico/calico/libcalico-go/lib/apiconfig"
"github.com/projectcalico/calico/libcalico-go/lib/clientv3"
"github.com/projectcalico/calico/libcalico-go/lib/names"
"github.com/projectcalico/calico/libcalico-go/lib/options"

v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
Expand Down Expand Up @@ -522,13 +523,19 @@ func TestTierList(t *testing.T) {
}
}

defaultTier := makeTier("", "", v3.DefaultTierOrder)
opts := storage.GetOptions{IgnoreNotFound: false}
defaultTier := makeTier(names.DefaultTierName, "", v3.DefaultTierOrder)
err := store.Get(ctx, "projectcalico.org/tiers/default", opts, defaultTier)
if err != nil {
t.Fatalf("Get failed: %v", err)
}

anpTier := makeTier(names.AdminNetworkPolicyTierName, "", v3.AdminNetworkPolicyTierOrder)
err = store.Get(ctx, "projectcalico.org/tiers/adminnetworkpolicy", opts, anpTier)
if err != nil {
t.Fatalf("Get failed: %v", err)
}

tests := []struct {
prefix string
pred storage.SelectionPredicate
Expand All @@ -547,7 +554,7 @@ func TestTierList(t *testing.T) {
return nil, fields.Set{"metadata.name": tier.Name}, nil
},
},
expectedOut: []*v3.Tier{preset[1].storedObj, defaultTier},
expectedOut: []*v3.Tier{anpTier, preset[1].storedObj, defaultTier},
}}

for i, tt := range tests {
Expand Down
5 changes: 2 additions & 3 deletions calicoctl/calicoctl/commands/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/projectcalico/calico/calicoctl/calicoctl/commands/resourceloader"
"github.com/projectcalico/calico/calicoctl/calicoctl/util"
"github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned"
"github.com/projectcalico/calico/libcalico-go/lib/names"

cconversion "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion"
"github.com/projectcalico/calico/libcalico-go/lib/upgrade/converters"
Expand Down Expand Up @@ -217,10 +218,8 @@ func convertK8sResource(convResource unversioned.Resource) (converters.Resource,

// Trim K8sNetworkPolicyNamePrefix from the policy name (the K8sNetworkPolicyToCalico
// function adds it for when it is used for coexisting calico/k8s policies).
k8snp.Name = strings.TrimPrefix(k8snp.Name, cconversion.K8sNetworkPolicyNamePrefix)

k8snp.Name = strings.TrimPrefix(k8snp.Name, names.K8sNetworkPolicyNamePrefix)
res = k8snp

default:
return nil, fmt.Errorf("conversion for the k8s resource type '%s' is not supported", k8sResKind)
}
Expand Down
31 changes: 28 additions & 3 deletions calicoctl/calicoctl/commands/datastore/migrate/export.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,7 +36,7 @@ import (
"github.com/projectcalico/calico/calicoctl/calicoctl/util"
"github.com/projectcalico/calico/libcalico-go/lib/apiconfig"
libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3"
"github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion"
"github.com/projectcalico/calico/libcalico-go/lib/names"
)

var title = cases.Title(language.English)
Expand Down Expand Up @@ -221,7 +221,7 @@ Description:
if !ok {
return fmt.Errorf("Unable to convert Calico network policy for inspection")
}
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), conversion.K8sNetworkPolicyNamePrefix) {
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sNetworkPolicyNamePrefix) {
filtered = append(filtered, obj)
}
}
Expand All @@ -233,6 +233,31 @@ Description:
results.Resources[i] = resource
}

// Skip exporting Kubernetes admin network policies.
if r == "globalnetworkpolicies" {
objs, err := meta.ExtractList(resource)
if err != nil {
return fmt.Errorf("Error extracting global network policies for inspection before exporting: %s", err)
}

filtered := []runtime.Object{}
for _, obj := range objs {
metaObj, ok := obj.(v1.ObjectMetaAccessor)
if !ok {
return fmt.Errorf("Unable to convert Calico gloabal network policy for inspection")
}
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sAdminNetworkPolicyNamePrefix) {
filtered = append(filtered, obj)
}
}

err = meta.SetList(resource, filtered)
if err != nil {
return fmt.Errorf("Unable to remove Kubernetes admin network policies for export: %s", err)
}
results.Resources[i] = resource
}

// Nodes need to also be modified to move the Orchestrator reference to the name field.
if r == "nodes" {
err := meta.EachListItem(resource, func(obj runtime.Object) error {
Expand Down
24 changes: 21 additions & 3 deletions calicoctl/calicoctl/commands/datastore/migrate/import.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -40,10 +40,10 @@ import (
"github.com/projectcalico/calico/libcalico-go/lib/apiconfig"
libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3"
"github.com/projectcalico/calico/libcalico-go/lib/backend/k8s"
"github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion"
"github.com/projectcalico/calico/libcalico-go/lib/backend/model"
client "github.com/projectcalico/calico/libcalico-go/lib/clientv3"
calicoErrors "github.com/projectcalico/calico/libcalico-go/lib/errors"
"github.com/projectcalico/calico/libcalico-go/lib/names"
"github.com/projectcalico/calico/libcalico-go/lib/options"
)

Expand Down Expand Up @@ -246,7 +246,25 @@ func checkCalicoResourcesNotExist(args map[string]interface{}, c client.Interfac
}

// Make sure that the network policy is a K8s network policy
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), conversion.K8sNetworkPolicyNamePrefix) {
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sNetworkPolicyNamePrefix) {
return fmt.Errorf("Found existing Calico %s resource", results.SingleKind)
}
}
} else if r == "globalnetworkpolicies" {
// For globalnetworkpolicies, having K8s admin network policies should not throw an error
objs, err := meta.ExtractList(resource)
if err != nil {
return fmt.Errorf("Error extracting global network policies for inspection: %s", err)
}

for _, obj := range objs {
metaObj, ok := obj.(v1.ObjectMetaAccessor)
if !ok {
return fmt.Errorf("Unable to convert Calico global network policy for inspection")
}

// Make sure that the global network policy is a K8s admin network policy
if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sAdminNetworkPolicyNamePrefix) {
return fmt.Errorf("Found existing Calico %s resource", results.SingleKind)
}
}
Expand Down
24 changes: 24 additions & 0 deletions calicoctl/calicoctl/resourcemgr/globalnetworkpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ package resourcemgr

import (
"context"
"strings"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

api "github.com/projectcalico/api/pkg/apis/projectcalico/v3"

client "github.com/projectcalico/calico/libcalico-go/lib/clientv3"
cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors"
"github.com/projectcalico/calico/libcalico-go/lib/names"
"github.com/projectcalico/calico/libcalico-go/lib/options"
)

Expand All @@ -41,14 +44,35 @@ func init() {
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.GlobalNetworkPolicy)
if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "create or apply",
Identifier: resource,
Reason: "kubernetes admin network policies must be managed through the kubernetes API",
}
}
return client.GlobalNetworkPolicies().Create(ctx, r, options.SetOptions{})
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.GlobalNetworkPolicy)
if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "create or apply",
Identifier: resource,
Reason: "kubernetes admin network policies must be managed through the kubernetes API",
}
}
return client.GlobalNetworkPolicies().Update(ctx, r, options.SetOptions{})
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.GlobalNetworkPolicy)
if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "create or apply",
Identifier: resource,
Reason: "kubernetes admin network policies must be managed through the kubernetes API",
}
}
return client.GlobalNetworkPolicies().Delete(ctx, r.Name, options.DeleteOptions{ResourceVersion: r.ResourceVersion})
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
Expand Down
8 changes: 4 additions & 4 deletions calicoctl/calicoctl/resourcemgr/networkpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
api "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion"
client "github.com/projectcalico/calico/libcalico-go/lib/clientv3"
cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors"
"github.com/projectcalico/calico/libcalico-go/lib/names"
"github.com/projectcalico/calico/libcalico-go/lib/options"
)

Expand All @@ -45,7 +45,7 @@ func init() {
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.NetworkPolicy)
if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "create or apply",
Identifier: resource,
Expand All @@ -56,7 +56,7 @@ func init() {
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.NetworkPolicy)
if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "apply or replace",
Identifier: resource,
Expand All @@ -67,7 +67,7 @@ func init() {
},
func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) {
r := resource.(*api.NetworkPolicy)
if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) {
if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) {
return nil, cerrors.ErrorOperationNotSupported{
Operation: "delete",
Identifier: resource,
Expand Down
8 changes: 5 additions & 3 deletions calicoctl/tests/st/calicoctl/test_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -1127,10 +1127,12 @@ def test_tier_list_order(self):
rc.assert_no_error()
tierList = rc.decoded

# Validate the tiers are ordered correctly. Default should have a value of nil and should be placed last.
# Validate the tiers are ordered correctly. Default should have a value of 1M and should be placed last.
# adminnetworkpolicy has a value of 1K, and should be second one.
self.assertEqual(tierList['items'][0]['metadata']['name'], name(tier_name2_rev1))
self.assertEqual(tierList['items'][1]['metadata']['name'], name(tier_name1_rev1))
self.assertEqual(tierList['items'][2]['metadata']['name'], 'default')
self.assertEqual(tierList['items'][1]['metadata']['name'], 'adminnetworkpolicy')
self.assertEqual(tierList['items'][2]['metadata']['name'], name(tier_name1_rev1))
self.assertEqual(tierList['items'][3]['metadata']['name'], 'default')

# Delete the resources
rc = calicoctl("delete", data=resources)
Expand Down
2 changes: 1 addition & 1 deletion calicoctl/tests/st/utils/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@
'name': 'admin',
},
'spec': {
'Order': 1000,
'Order': 10000,
},
}

Expand Down
7 changes: 7 additions & 0 deletions charts/calico/templates/calico-node-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ rules:
verbs:
- watch
- list
# Watch for changes to Kubernetes AdminNetworkPolicies.
- apiGroups: ["policy.networking.k8s.io"]
resources:
- adminnetworkpolicies
verbs:
- watch
- list
# Used by Calico for policy information.
- apiGroups: [""]
resources:
Expand Down
10 changes: 7 additions & 3 deletions e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ include ../metadata.mk
PACKAGE_NAME=github.com/projectcalico/calico/e2e
include ../lib.Makefile

build: bin/e2e.test
bin/e2e.test: $(SRC_FILES)
build: bin/k8s/e2e.test bin/adminpolicy/e2e.test
bin/k8s/e2e.test: $(SRC_FILES)
mkdir -p bin
$(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd -c -o $@
$(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd/k8s -c -o $@

bin/adminpolicy/e2e.test: $(SRC_FILES)
mkdir -p bin
$(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd/adminpolicy -c -o $@

clean:
rm -rf bin/
Loading
Loading