From 9e14fd21ffc22612b70f38ea4e3c16d07cb8511b Mon Sep 17 00:00:00 2001 From: Antonio Ojea Date: Sun, 29 Dec 2024 18:09:57 +0000 Subject: [PATCH] add kindnet network plugin Change-Id: Ica436d9debe1efb63a572cb8e8c68432ec2ffd35 --- cmd/kops/create_cluster.go | 3 +- cmd/kops/integration_test.go | 10 + docs/networking/kindnet.md | 26 + k8s/crds/kops.k8s.io_clusters.yaml | 30 + nodeup/pkg/model/networking/kindnet.go | 38 + pkg/apis/kops/networking.go | 25 + pkg/apis/kops/v1alpha2/networking.go | 21 +- .../kops/v1alpha2/zz_generated.conversion.go | 110 + .../kops/v1alpha2/zz_generated.deepcopy.go | 82 + pkg/apis/kops/v1alpha3/networking.go | 18 + .../kops/v1alpha3/zz_generated.conversion.go | 110 + .../kops/v1alpha3/zz_generated.deepcopy.go | 82 + pkg/apis/kops/validation/validation.go | 26 + pkg/apis/kops/validation/validation_test.go | 67 + pkg/apis/kops/zz_generated.deepcopy.go | 82 + pkg/apis/nodeup/config.go | 4 + pkg/model/components/kindnet.go | 59 + .../networking.kindnet/k8s-1.12.yaml.template | 2298 +++++++++++++++++ .../bootstrapchannelbuilder.go | 17 + upup/pkg/fi/cloudup/new_cluster.go | 2 + upup/pkg/fi/cloudup/new_cluster_test.go | 12 + upup/pkg/fi/cloudup/populate_cluster_spec.go | 1 + upup/pkg/fi/nodeup/command.go | 1 + 23 files changed, 3122 insertions(+), 2 deletions(-) create mode 100644 docs/networking/kindnet.md create mode 100644 nodeup/pkg/model/networking/kindnet.go create mode 100644 pkg/model/components/kindnet.go create mode 100644 upup/models/cloudup/resources/addons/networking.kindnet/k8s-1.12.yaml.template diff --git a/cmd/kops/create_cluster.go b/cmd/kops/create_cluster.go index 054e5a60e50fa..cbd2ca4498345 100644 --- a/cmd/kops/create_cluster.go +++ b/cmd/kops/create_cluster.go @@ -314,7 +314,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().StringVar(&options.EtcdStorageType, "etcd-storage-type", options.EtcdStorageType, "The default storage type for etcd members") cmd.RegisterFlagCompletionFunc("etcd-storage-type", completeStorageType) - cmd.Flags().StringVar(&options.Networking, "networking", options.Networking, "Networking mode. kubenet, external, flannel-vxlan (or flannel), flannel-udp, calico, canal, kube-router, amazonvpc, cilium, cilium-etcd, cni.") + cmd.Flags().StringVar(&options.Networking, "networking", options.Networking, "Networking mode. kubenet, external, flannel-vxlan (or flannel), flannel-udp, calico, canal, kube-router, amazonvpc, cilium, cilium-etcd, kindnet, cni.") cmd.RegisterFlagCompletionFunc("networking", completeNetworking(options)) cmd.Flags().StringVar(&options.DNSZone, "dns-zone", options.DNSZone, "DNS hosted zone (defaults to longest matching zone)") @@ -983,6 +983,7 @@ func completeNetworking(options *CreateClusterOptions) func(cmd *cobra.Command, "cilium", "cilium-eni", "cilium-etcd", + "kindnet", } if !options.IPv6 { diff --git a/cmd/kops/integration_test.go b/cmd/kops/integration_test.go index ca90a353f72a6..99fbb62efef02 100644 --- a/cmd/kops/integration_test.go +++ b/cmd/kops/integration_test.go @@ -228,6 +228,7 @@ const ( canalAddon = "networking.projectcalico.org.canal-k8s-1.25" ciliumAddon = "networking.cilium.io-k8s-1.16" flannelAddon = "networking.flannel-k8s-1.25" + kindnetAddon = "networking.kindnet-k8s-1.12" certManagerAddon = "certmanager.io-k8s-1.16" clusterAutoscalerAddon = "cluster-autoscaler.addons.k8s.io-k8s-1.15" @@ -642,6 +643,15 @@ func TestPrivateFlannel(t *testing.T) { runTestTerraformAWS(t) } +// TestPrivateKindnet runs the test on a configuration with private topology, flannel networking +func TestPrivateKindnet(t *testing.T) { + newIntegrationTest("privatekindnet.example.com", "privatekindnet"). + withPrivate(). + withDefaultAddons24(). + withAddons(kindnetAddon). + runTestTerraformAWS(t) +} + // TestPrivateCalico runs the test on a configuration with private topology, calico networking func TestPrivateCalico(t *testing.T) { newIntegrationTest("privatecalico.example.com", "privatecalico"). diff --git a/docs/networking/kindnet.md b/docs/networking/kindnet.md new file mode 100644 index 0000000000000..b85e2f4bd2c11 --- /dev/null +++ b/docs/networking/kindnet.md @@ -0,0 +1,26 @@ +# Kindnet + +* [kindnet](http://kindnet.es) + +Kindnet focuses on providing essential networking functionality without unnecessary complexity. + +## Installing + +To install [kindnet](https://github.com/aojea/kindnet) - use `--networking kindnet`. + +```sh +export ZONES=mylistofzone +kops create cluster \ + --zones $ZONES \ + --networking kindnet \ + --yes \ + --name myclustername.mydns.io +``` + +## Getting help + +For problems with kindnet please post an issue to Github: + +- [Kindnet Issues](https://github.com/aojea/kindnet/issues) + +You can learn more about the different configurations options in https://kindnet.es/ diff --git a/k8s/crds/kops.k8s.io_clusters.yaml b/k8s/crds/kops.k8s.io_clusters.yaml index 782ee35692309..f7c35e9cc289a 100644 --- a/k8s/crds/kops.k8s.io_clusters.yaml +++ b/k8s/crds/kops.k8s.io_clusters.yaml @@ -5773,6 +5773,36 @@ spec: description: GCPNetworkingSpec is the specification of GCP's native networking mode, using IP aliases. type: object + kindnet: + description: KindnetNetworkingSpec configures Kindnet settings. + properties: + adminNetworkPolicies: + type: boolean + baselineAdminNetworkPolicies: + type: boolean + dnsCaching: + type: boolean + fastPathThreshold: + format: int32 + type: integer + masquerade: + description: KindnetMasqueradeSpec configures Kindnet masquerading + settings. + properties: + enabled: + type: boolean + nonMasqueradeCIDRs: + items: + type: string + type: array + type: object + nat64: + type: boolean + networkPolicies: + type: boolean + version: + type: string + type: object kopeio: description: KopeioNetworkingSpec declares that we want Kopeio networking diff --git a/nodeup/pkg/model/networking/kindnet.go b/nodeup/pkg/model/networking/kindnet.go new file mode 100644 index 0000000000000..c13f2cd9eafc4 --- /dev/null +++ b/nodeup/pkg/model/networking/kindnet.go @@ -0,0 +1,38 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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. +*/ + +package networking + +import ( + "k8s.io/kops/nodeup/pkg/model" + "k8s.io/kops/upup/pkg/fi" +) + +// KindnetBuilder configures the etcd TLS support for Calico +type KindnetBuilder struct { + *model.NodeupModelContext +} + +var _ fi.NodeupModelBuilder = &KindnetBuilder{} + +// Build is responsible for performing setup for Kindnet. +func (b *KindnetBuilder) Build(c *fi.NodeupModelBuilderContext) error { + if b.NodeupConfig.Networking.Kindnet == nil { + return nil + } + + return nil +} diff --git a/pkg/apis/kops/networking.go b/pkg/apis/kops/networking.go index 3edb9b2c20eac..1882d226d70b2 100644 --- a/pkg/apis/kops/networking.go +++ b/pkg/apis/kops/networking.go @@ -78,6 +78,7 @@ type NetworkingSpec struct { Cilium *CiliumNetworkingSpec `json:"cilium,omitempty"` LyftVPC *LyftVPCNetworkingSpec `json:"lyftvpc,omitempty"` GCP *GCPNetworkingSpec `json:"gcp,omitempty"` + Kindnet *KindnetNetworkingSpec `json:"kindnet,omitempty"` } // UsesKubenet returns true if our networking is derived from kubenet @@ -553,3 +554,27 @@ type LyftVPCNetworkingSpec struct { // GCPNetworkingSpec is the specification of GCP's native networking mode, using IP aliases. type GCPNetworkingSpec struct{} + +// KindnetNetworkingSpec configures Kindnet settings. +type KindnetNetworkingSpec struct { + // Version is the version of the kindnet agent. + // Default: stable + Version string `json:"version,omitempty"` + // Enable network policies + NetworkPolicies *bool `json:"networkPolicies,omitempty"` + AdminNetworkPolicies *bool `json:"adminNetworkPolicies,omitempty"` + BaselineAdminNetworkPolicies *bool `json:"baselineAdminNetworkPolicies,omitempty"` + // enable dns caching + DNSCaching *bool `json:"dnsCaching,omitempty"` + // enable nat64 on ipv6 clusters + NAT64 *bool `json:"nat64,omitempty"` + // number of packets in a connection to offload it to the fast path + FastPathThreshold *int32 `json:"fastPathThreshold,omitempty"` + // node agent masquerading rules + Masquerade *KindnetMasqueradeSpec `json:"masquerade,omitempty"` +} + +type KindnetMasqueradeSpec struct { + Enabled *bool `json:"enabled,omitempty"` + NonMasqueradeCIDRs []string `json:"nonMasqueradeCIDRs,omitempty"` +} diff --git a/pkg/apis/kops/v1alpha2/networking.go b/pkg/apis/kops/v1alpha2/networking.go index 09af2790af39a..8b131363eb6be 100644 --- a/pkg/apis/kops/v1alpha2/networking.go +++ b/pkg/apis/kops/v1alpha2/networking.go @@ -49,12 +49,13 @@ type NetworkingSpec struct { Cilium *CiliumNetworkingSpec `json:"cilium,omitempty"` LyftVPC *LyftVPCNetworkingSpec `json:"lyftvpc,omitempty"` GCP *GCPNetworkingSpec `json:"gce,omitempty"` + Kindnet *KindnetNetworkingSpec `json:"kindnet,omitempty"` } func (s *NetworkingSpec) IsEmpty() bool { return s.Classic == nil && s.Kubenet == nil && s.External == nil && s.CNI == nil && s.Kopeio == nil && s.Weave == nil && s.Flannel == nil && s.Calico == nil && s.Canal == nil && s.KubeRouter == nil && - s.Romana == nil && s.AmazonVPC == nil && s.Cilium == nil && s.LyftVPC == nil && s.GCP == nil + s.Romana == nil && s.AmazonVPC == nil && s.Cilium == nil && s.LyftVPC == nil && s.GCP == nil && s.Kindnet == nil } // ClassicNetworkingSpec is the specification of classic networking mode, integrated into kubernetes. @@ -674,3 +675,21 @@ type LyftVPCNetworkingSpec struct { // GCPNetworkingSpec is the specification of GCP's native networking mode, using IP aliases. type GCPNetworkingSpec struct{} + +// KindnetNetworkingSpec configures Kindnet settings. +type KindnetNetworkingSpec struct { + Version string `json:"version,omitempty"` + NetworkPolicies *bool `json:"networkPolicies,omitempty"` + AdminNetworkPolicies *bool `json:"adminNetworkPolicies,omitempty"` + BaselineAdminNetworkPolicies *bool `json:"baselineAdminNetworkPolicies,omitempty"` + DNSCaching *bool `json:"dnsCaching,omitempty"` + NAT64 *bool `json:"nat64,omitempty"` + FastPathThreshold *int32 `json:"fastPathThreshold,omitempty"` + Masquerade *KindnetMasqueradeSpec `json:"masquerade,omitempty"` +} + +// KindnetMasqueradeSpec configures Kindnet masquerading settings. +type KindnetMasqueradeSpec struct { + Enabled *bool `json:"enabled,omitempty"` + NonMasqueradeCIDRs []string `json:"nonMasqueradeCIDRs,omitempty"` +} diff --git a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go index 898c243e04dc0..c727a01955ff1 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go @@ -624,6 +624,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*KindnetMasqueradeSpec)(nil), (*kops.KindnetMasqueradeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(a.(*KindnetMasqueradeSpec), b.(*kops.KindnetMasqueradeSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.KindnetMasqueradeSpec)(nil), (*KindnetMasqueradeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec(a.(*kops.KindnetMasqueradeSpec), b.(*KindnetMasqueradeSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KindnetNetworkingSpec)(nil), (*kops.KindnetNetworkingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(a.(*KindnetNetworkingSpec), b.(*kops.KindnetNetworkingSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.KindnetNetworkingSpec)(nil), (*KindnetNetworkingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec(a.(*kops.KindnetNetworkingSpec), b.(*KindnetNetworkingSpec), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*KopeioAuthenticationSpec)(nil), (*kops.KopeioAuthenticationSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_KopeioAuthenticationSpec_To_kops_KopeioAuthenticationSpec(a.(*KopeioAuthenticationSpec), b.(*kops.KopeioAuthenticationSpec), scope) }); err != nil { @@ -4831,6 +4851,78 @@ func Convert_kops_KeysetSpec_To_v1alpha2_KeysetSpec(in *kops.KeysetSpec, out *Ke return autoConvert_kops_KeysetSpec_To_v1alpha2_KeysetSpec(in, out, s) } +func autoConvert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in *KindnetMasqueradeSpec, out *kops.KindnetMasqueradeSpec, s conversion.Scope) error { + out.Enabled = in.Enabled + out.NonMasqueradeCIDRs = in.NonMasqueradeCIDRs + return nil +} + +// Convert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec is an autogenerated conversion function. +func Convert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in *KindnetMasqueradeSpec, out *kops.KindnetMasqueradeSpec, s conversion.Scope) error { + return autoConvert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in, out, s) +} + +func autoConvert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec(in *kops.KindnetMasqueradeSpec, out *KindnetMasqueradeSpec, s conversion.Scope) error { + out.Enabled = in.Enabled + out.NonMasqueradeCIDRs = in.NonMasqueradeCIDRs + return nil +} + +// Convert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec is an autogenerated conversion function. +func Convert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec(in *kops.KindnetMasqueradeSpec, out *KindnetMasqueradeSpec, s conversion.Scope) error { + return autoConvert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec(in, out, s) +} + +func autoConvert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in *KindnetNetworkingSpec, out *kops.KindnetNetworkingSpec, s conversion.Scope) error { + out.Version = in.Version + out.NetworkPolicies = in.NetworkPolicies + out.AdminNetworkPolicies = in.AdminNetworkPolicies + out.BaselineAdminNetworkPolicies = in.BaselineAdminNetworkPolicies + out.DNSCaching = in.DNSCaching + out.NAT64 = in.NAT64 + out.FastPathThreshold = in.FastPathThreshold + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(kops.KindnetMasqueradeSpec) + if err := Convert_v1alpha2_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Masquerade = nil + } + return nil +} + +// Convert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec is an autogenerated conversion function. +func Convert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in *KindnetNetworkingSpec, out *kops.KindnetNetworkingSpec, s conversion.Scope) error { + return autoConvert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in, out, s) +} + +func autoConvert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec(in *kops.KindnetNetworkingSpec, out *KindnetNetworkingSpec, s conversion.Scope) error { + out.Version = in.Version + out.NetworkPolicies = in.NetworkPolicies + out.AdminNetworkPolicies = in.AdminNetworkPolicies + out.BaselineAdminNetworkPolicies = in.BaselineAdminNetworkPolicies + out.DNSCaching = in.DNSCaching + out.NAT64 = in.NAT64 + out.FastPathThreshold = in.FastPathThreshold + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(KindnetMasqueradeSpec) + if err := Convert_kops_KindnetMasqueradeSpec_To_v1alpha2_KindnetMasqueradeSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Masquerade = nil + } + return nil +} + +// Convert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec is an autogenerated conversion function. +func Convert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec(in *kops.KindnetNetworkingSpec, out *KindnetNetworkingSpec, s conversion.Scope) error { + return autoConvert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec(in, out, s) +} + func autoConvert_v1alpha2_KopeioAuthenticationSpec_To_kops_KopeioAuthenticationSpec(in *KopeioAuthenticationSpec, out *kops.KopeioAuthenticationSpec, s conversion.Scope) error { return nil } @@ -6224,6 +6316,15 @@ func autoConvert_v1alpha2_NetworkingSpec_To_kops_NetworkingSpec(in *NetworkingSp } else { out.GCP = nil } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(kops.KindnetNetworkingSpec) + if err := Convert_v1alpha2_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Kindnet = nil + } return nil } @@ -6405,6 +6506,15 @@ func autoConvert_kops_NetworkingSpec_To_v1alpha2_NetworkingSpec(in *kops.Network } else { out.GCP = nil } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(KindnetNetworkingSpec) + if err := Convert_kops_KindnetNetworkingSpec_To_v1alpha2_KindnetNetworkingSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Kindnet = nil + } return nil } diff --git a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go index 99f85e64b9a70..0933bf01c6d87 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go @@ -3011,6 +3011,83 @@ func (in *KeysetSpec) DeepCopy() *KeysetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetMasqueradeSpec) DeepCopyInto(out *KindnetMasqueradeSpec) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.NonMasqueradeCIDRs != nil { + in, out := &in.NonMasqueradeCIDRs, &out.NonMasqueradeCIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetMasqueradeSpec. +func (in *KindnetMasqueradeSpec) DeepCopy() *KindnetMasqueradeSpec { + if in == nil { + return nil + } + out := new(KindnetMasqueradeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetNetworkingSpec) DeepCopyInto(out *KindnetNetworkingSpec) { + *out = *in + if in.NetworkPolicies != nil { + in, out := &in.NetworkPolicies, &out.NetworkPolicies + *out = new(bool) + **out = **in + } + if in.AdminNetworkPolicies != nil { + in, out := &in.AdminNetworkPolicies, &out.AdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.BaselineAdminNetworkPolicies != nil { + in, out := &in.BaselineAdminNetworkPolicies, &out.BaselineAdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.DNSCaching != nil { + in, out := &in.DNSCaching, &out.DNSCaching + *out = new(bool) + **out = **in + } + if in.NAT64 != nil { + in, out := &in.NAT64, &out.NAT64 + *out = new(bool) + **out = **in + } + if in.FastPathThreshold != nil { + in, out := &in.FastPathThreshold, &out.FastPathThreshold + *out = new(int32) + **out = **in + } + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(KindnetMasqueradeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetNetworkingSpec. +func (in *KindnetNetworkingSpec) DeepCopy() *KindnetNetworkingSpec { + if in == nil { + return nil + } + out := new(KindnetNetworkingSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KopeioAuthenticationSpec) DeepCopyInto(out *KopeioAuthenticationSpec) { *out = *in @@ -4783,6 +4860,11 @@ func (in *NetworkingSpec) DeepCopyInto(out *NetworkingSpec) { *out = new(GCPNetworkingSpec) **out = **in } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(KindnetNetworkingSpec) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/kops/v1alpha3/networking.go b/pkg/apis/kops/v1alpha3/networking.go index 2ccb675bf445f..7d871dde748e9 100644 --- a/pkg/apis/kops/v1alpha3/networking.go +++ b/pkg/apis/kops/v1alpha3/networking.go @@ -82,6 +82,7 @@ type NetworkingSpec struct { Cilium *CiliumNetworkingSpec `json:"cilium,omitempty"` LyftVPC *kops.LyftVPCNetworkingSpec `json:"-"` GCP *GCPNetworkingSpec `json:"gcp,omitempty"` + Kindnet *KindnetNetworkingSpec `json:"kindnet,omitempty"` } // KubenetNetworkingSpec is the specification for kubenet networking, largely integrated but intended to replace classic @@ -510,3 +511,20 @@ type HubbleSpec struct { // GCPNetworkingSpec is the specification of GCP's native networking mode, using IP aliases. type GCPNetworkingSpec struct{} + +// KindnetNetworkingSpec configures Kindnet settings. +type KindnetNetworkingSpec struct { + Version string `json:"version,omitempty"` + NetworkPolicies *bool `json:"networkPolicies,omitempty"` + AdminNetworkPolicies *bool `json:"adminNetworkPolicies,omitempty"` + BaselineAdminNetworkPolicies *bool `json:"baselineAdminNetworkPolicies,omitempty"` + DNSCaching *bool `json:"dnsCaching,omitempty"` + NAT64 *bool `json:"nat64,omitempty"` + FastPathThreshold *int32 `json:"fastPathThreshold,omitempty"` + Masquerade *KindnetMasqueradeSpec `json:"masquerade,omitempty"` +} + +type KindnetMasqueradeSpec struct { + Enabled *bool `json:"enabled,omitempty"` + NonMasqueradeCIDRs []string `json:"nonMasqueradeCIDRs,omitempty"` +} diff --git a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go index b979e1e79ae7b..89a220bc33369 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go @@ -744,6 +744,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*KindnetMasqueradeSpec)(nil), (*kops.KindnetMasqueradeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(a.(*KindnetMasqueradeSpec), b.(*kops.KindnetMasqueradeSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.KindnetMasqueradeSpec)(nil), (*KindnetMasqueradeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec(a.(*kops.KindnetMasqueradeSpec), b.(*KindnetMasqueradeSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KindnetNetworkingSpec)(nil), (*kops.KindnetNetworkingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(a.(*KindnetNetworkingSpec), b.(*kops.KindnetNetworkingSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.KindnetNetworkingSpec)(nil), (*KindnetNetworkingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec(a.(*kops.KindnetNetworkingSpec), b.(*KindnetNetworkingSpec), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*KopeioAuthenticationSpec)(nil), (*kops.KopeioAuthenticationSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_KopeioAuthenticationSpec_To_kops_KopeioAuthenticationSpec(a.(*KopeioAuthenticationSpec), b.(*kops.KopeioAuthenticationSpec), scope) }); err != nil { @@ -5227,6 +5247,78 @@ func Convert_kops_KeysetSpec_To_v1alpha3_KeysetSpec(in *kops.KeysetSpec, out *Ke return autoConvert_kops_KeysetSpec_To_v1alpha3_KeysetSpec(in, out, s) } +func autoConvert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in *KindnetMasqueradeSpec, out *kops.KindnetMasqueradeSpec, s conversion.Scope) error { + out.Enabled = in.Enabled + out.NonMasqueradeCIDRs = in.NonMasqueradeCIDRs + return nil +} + +// Convert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec is an autogenerated conversion function. +func Convert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in *KindnetMasqueradeSpec, out *kops.KindnetMasqueradeSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(in, out, s) +} + +func autoConvert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec(in *kops.KindnetMasqueradeSpec, out *KindnetMasqueradeSpec, s conversion.Scope) error { + out.Enabled = in.Enabled + out.NonMasqueradeCIDRs = in.NonMasqueradeCIDRs + return nil +} + +// Convert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec is an autogenerated conversion function. +func Convert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec(in *kops.KindnetMasqueradeSpec, out *KindnetMasqueradeSpec, s conversion.Scope) error { + return autoConvert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec(in, out, s) +} + +func autoConvert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in *KindnetNetworkingSpec, out *kops.KindnetNetworkingSpec, s conversion.Scope) error { + out.Version = in.Version + out.NetworkPolicies = in.NetworkPolicies + out.AdminNetworkPolicies = in.AdminNetworkPolicies + out.BaselineAdminNetworkPolicies = in.BaselineAdminNetworkPolicies + out.DNSCaching = in.DNSCaching + out.NAT64 = in.NAT64 + out.FastPathThreshold = in.FastPathThreshold + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(kops.KindnetMasqueradeSpec) + if err := Convert_v1alpha3_KindnetMasqueradeSpec_To_kops_KindnetMasqueradeSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Masquerade = nil + } + return nil +} + +// Convert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec is an autogenerated conversion function. +func Convert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in *KindnetNetworkingSpec, out *kops.KindnetNetworkingSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(in, out, s) +} + +func autoConvert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec(in *kops.KindnetNetworkingSpec, out *KindnetNetworkingSpec, s conversion.Scope) error { + out.Version = in.Version + out.NetworkPolicies = in.NetworkPolicies + out.AdminNetworkPolicies = in.AdminNetworkPolicies + out.BaselineAdminNetworkPolicies = in.BaselineAdminNetworkPolicies + out.DNSCaching = in.DNSCaching + out.NAT64 = in.NAT64 + out.FastPathThreshold = in.FastPathThreshold + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(KindnetMasqueradeSpec) + if err := Convert_kops_KindnetMasqueradeSpec_To_v1alpha3_KindnetMasqueradeSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Masquerade = nil + } + return nil +} + +// Convert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec is an autogenerated conversion function. +func Convert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec(in *kops.KindnetNetworkingSpec, out *KindnetNetworkingSpec, s conversion.Scope) error { + return autoConvert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec(in, out, s) +} + func autoConvert_v1alpha3_KopeioAuthenticationSpec_To_kops_KopeioAuthenticationSpec(in *KopeioAuthenticationSpec, out *kops.KopeioAuthenticationSpec, s conversion.Scope) error { return nil } @@ -6574,6 +6666,15 @@ func autoConvert_v1alpha3_NetworkingSpec_To_kops_NetworkingSpec(in *NetworkingSp } else { out.GCP = nil } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(kops.KindnetNetworkingSpec) + if err := Convert_v1alpha3_KindnetNetworkingSpec_To_kops_KindnetNetworkingSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Kindnet = nil + } return nil } @@ -6731,6 +6832,15 @@ func autoConvert_kops_NetworkingSpec_To_v1alpha3_NetworkingSpec(in *kops.Network } else { out.GCP = nil } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(KindnetNetworkingSpec) + if err := Convert_kops_KindnetNetworkingSpec_To_v1alpha3_KindnetNetworkingSpec(*in, *out, s); err != nil { + return err + } + } else { + out.Kindnet = nil + } return nil } diff --git a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go index 0a84da4d2adec..3a7efd7fa1793 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go @@ -2985,6 +2985,83 @@ func (in *KeysetSpec) DeepCopy() *KeysetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetMasqueradeSpec) DeepCopyInto(out *KindnetMasqueradeSpec) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.NonMasqueradeCIDRs != nil { + in, out := &in.NonMasqueradeCIDRs, &out.NonMasqueradeCIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetMasqueradeSpec. +func (in *KindnetMasqueradeSpec) DeepCopy() *KindnetMasqueradeSpec { + if in == nil { + return nil + } + out := new(KindnetMasqueradeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetNetworkingSpec) DeepCopyInto(out *KindnetNetworkingSpec) { + *out = *in + if in.NetworkPolicies != nil { + in, out := &in.NetworkPolicies, &out.NetworkPolicies + *out = new(bool) + **out = **in + } + if in.AdminNetworkPolicies != nil { + in, out := &in.AdminNetworkPolicies, &out.AdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.BaselineAdminNetworkPolicies != nil { + in, out := &in.BaselineAdminNetworkPolicies, &out.BaselineAdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.DNSCaching != nil { + in, out := &in.DNSCaching, &out.DNSCaching + *out = new(bool) + **out = **in + } + if in.NAT64 != nil { + in, out := &in.NAT64, &out.NAT64 + *out = new(bool) + **out = **in + } + if in.FastPathThreshold != nil { + in, out := &in.FastPathThreshold, &out.FastPathThreshold + *out = new(int32) + **out = **in + } + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(KindnetMasqueradeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetNetworkingSpec. +func (in *KindnetNetworkingSpec) DeepCopy() *KindnetNetworkingSpec { + if in == nil { + return nil + } + out := new(KindnetNetworkingSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KopeioAuthenticationSpec) DeepCopyInto(out *KopeioAuthenticationSpec) { *out = *in @@ -4734,6 +4811,11 @@ func (in *NetworkingSpec) DeepCopyInto(out *NetworkingSpec) { *out = new(GCPNetworkingSpec) **out = **in } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(KindnetNetworkingSpec) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/kops/validation/validation.go b/pkg/apis/kops/validation/validation.go index a3b303b7edf85..76685ed7b6883 100644 --- a/pkg/apis/kops/validation/validation.go +++ b/pkg/apis/kops/validation/validation.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "net" + "net/netip" "net/url" "path/filepath" "regexp" @@ -1226,6 +1227,14 @@ func validateNetworking(cluster *kops.Cluster, v *kops.NetworkingSpec, fldPath * allErrs = append(allErrs, validateNetworkingGCP(cluster, v.GCP, fldPath.Child("gcp"))...) } + if v.Kindnet != nil { + if optionTaken { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("kindnet"), "only one networking option permitted")) + } + + allErrs = append(allErrs, validateNetworkingKindnet(cluster, v.Kindnet, fldPath.Child("kindnet"))...) + } + return allErrs } @@ -1403,6 +1412,23 @@ func validateNetworkingGCP(cluster *kops.Cluster, v *kops.GCPNetworkingSpec, fld return allErrs } +func validateNetworkingKindnet(cluster *kops.Cluster, v *kops.KindnetNetworkingSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if v.Masquerade != nil && v.Masquerade.Enabled != nil && *v.Masquerade.Enabled { + for _, cidr := range v.Masquerade.NonMasqueradeCIDRs { + if cidr == "" { + continue + } + _, err := netip.ParsePrefix(cidr) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, cidr, err.Error())) + } + } + } + return allErrs +} + func validateAdditionalPolicy(role string, policy string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} diff --git a/pkg/apis/kops/validation/validation_test.go b/pkg/apis/kops/validation/validation_test.go index da2136c5c9db4..1c6b072f2b0ba 100644 --- a/pkg/apis/kops/validation/validation_test.go +++ b/pkg/apis/kops/validation/validation_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/upup/pkg/fi" + "k8s.io/utils/ptr" ) func Test_Validate_DNS(t *testing.T) { @@ -458,6 +459,72 @@ func Test_Validate_Networking_Flannel(t *testing.T) { } } +func Test_Validate_Networking_Kindnet(t *testing.T) { + grid := []struct { + Input kops.KindnetNetworkingSpec + ExpectedErrors []string + }{ + { + Input: kops.KindnetNetworkingSpec{ + Masquerade: &kops.KindnetMasqueradeSpec{ + Enabled: ptr.To(true), + }, + }, + }, + { + Input: kops.KindnetNetworkingSpec{ + Masquerade: &kops.KindnetMasqueradeSpec{ + Enabled: ptr.To(true), + NonMasqueradeCIDRs: []string{"10.0.0.0/24", "2001:db8::/64"}, + }, + }, + }, + { + Input: kops.KindnetNetworkingSpec{ + Masquerade: &kops.KindnetMasqueradeSpec{ + Enabled: ptr.To(true), + NonMasqueradeCIDRs: []string{"a.b.c.d/24", "2001:db8::/64"}, + }, + }, + ExpectedErrors: []string{"Invalid value::networking.kindnet"}, + }, + { + Input: kops.KindnetNetworkingSpec{ + Masquerade: &kops.KindnetMasqueradeSpec{ + Enabled: ptr.To(false), + NonMasqueradeCIDRs: []string{"a.b.c.d/24", "2001:db8::/64"}, + }, + }, + ExpectedErrors: []string{}, + }, + } + + for _, g := range grid { + cluster := &kops.Cluster{ + Spec: kops.ClusterSpec{ + KubernetesVersion: "1.27.0", + Networking: kops.NetworkingSpec{ + NetworkCIDR: "10.0.0.0/8", + NonMasqueradeCIDR: "100.64.0.0/10", + PodCIDR: "100.96.0.0/11", + ServiceClusterIPRange: "100.64.0.0/13", + Subnets: []kops.ClusterSubnetSpec{ + { + Name: "sg-test", + CIDR: "10.11.0.0/16", + Type: "Public", + }, + }, + Kindnet: &g.Input, + }, + }, + } + + errs := validateNetworking(cluster, &cluster.Spec.Networking, field.NewPath("networking"), true, &cloudProviderConstraints{}) + testErrors(t, g.Input, errs, g.ExpectedErrors) + } +} + func Test_Validate_Networking_OverlappingCIDR(t *testing.T) { grid := []struct { Name string diff --git a/pkg/apis/kops/zz_generated.deepcopy.go b/pkg/apis/kops/zz_generated.deepcopy.go index 87ef7670a9792..5ba62bd94eebd 100644 --- a/pkg/apis/kops/zz_generated.deepcopy.go +++ b/pkg/apis/kops/zz_generated.deepcopy.go @@ -3072,6 +3072,83 @@ func (in *KeysetSpec) DeepCopy() *KeysetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetMasqueradeSpec) DeepCopyInto(out *KindnetMasqueradeSpec) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.NonMasqueradeCIDRs != nil { + in, out := &in.NonMasqueradeCIDRs, &out.NonMasqueradeCIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetMasqueradeSpec. +func (in *KindnetMasqueradeSpec) DeepCopy() *KindnetMasqueradeSpec { + if in == nil { + return nil + } + out := new(KindnetMasqueradeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KindnetNetworkingSpec) DeepCopyInto(out *KindnetNetworkingSpec) { + *out = *in + if in.NetworkPolicies != nil { + in, out := &in.NetworkPolicies, &out.NetworkPolicies + *out = new(bool) + **out = **in + } + if in.AdminNetworkPolicies != nil { + in, out := &in.AdminNetworkPolicies, &out.AdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.BaselineAdminNetworkPolicies != nil { + in, out := &in.BaselineAdminNetworkPolicies, &out.BaselineAdminNetworkPolicies + *out = new(bool) + **out = **in + } + if in.DNSCaching != nil { + in, out := &in.DNSCaching, &out.DNSCaching + *out = new(bool) + **out = **in + } + if in.NAT64 != nil { + in, out := &in.NAT64, &out.NAT64 + *out = new(bool) + **out = **in + } + if in.FastPathThreshold != nil { + in, out := &in.FastPathThreshold, &out.FastPathThreshold + *out = new(int32) + **out = **in + } + if in.Masquerade != nil { + in, out := &in.Masquerade, &out.Masquerade + *out = new(KindnetMasqueradeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KindnetNetworkingSpec. +func (in *KindnetNetworkingSpec) DeepCopy() *KindnetNetworkingSpec { + if in == nil { + return nil + } + out := new(KindnetNetworkingSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KopeioAuthenticationSpec) DeepCopyInto(out *KopeioAuthenticationSpec) { *out = *in @@ -4876,6 +4953,11 @@ func (in *NetworkingSpec) DeepCopyInto(out *NetworkingSpec) { *out = new(GCPNetworkingSpec) **out = **in } + if in.Kindnet != nil { + in, out := &in.Kindnet, &out.Kindnet + *out = new(KindnetNetworkingSpec) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/nodeup/config.go b/pkg/apis/nodeup/config.go index 1386e8028410d..7c6ccb8b7a10c 100644 --- a/pkg/apis/nodeup/config.go +++ b/pkg/apis/nodeup/config.go @@ -328,6 +328,10 @@ func NewConfig(cluster *kops.Cluster, instanceGroup *kops.InstanceGroup) (*Confi config.Networking.KubeRouter = &kops.KuberouterNetworkingSpec{} } + if cluster.Spec.Networking.Kindnet != nil { + config.Networking.Kindnet = &kops.KindnetNetworkingSpec{} + } + if instanceGroup.Spec.Kubelet != nil { config.KubeletConfig = *instanceGroup.Spec.Kubelet } diff --git a/pkg/model/components/kindnet.go b/pkg/model/components/kindnet.go new file mode 100644 index 0000000000000..da72dcc94ec86 --- /dev/null +++ b/pkg/model/components/kindnet.go @@ -0,0 +1,59 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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. +*/ + +package components + +import ( + "k8s.io/kops/pkg/apis/kops" + "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/upup/pkg/fi/loader" +) + +// KindnetOptionsBuilder adds options for kindnet to the model +type KindnetOptionsBuilder struct { + Context *OptionsContext +} + +var _ loader.ClusterOptionsBuilder = &KindnetOptionsBuilder{} + +func (b *KindnetOptionsBuilder) BuildOptions(o *kops.Cluster) error { + clusterSpec := &o.Spec + c := clusterSpec.Networking.Kindnet + if c == nil { + return nil + } + + if c.Version == "" { + c.Version = "stable" + } + + if c.Masquerade == nil { + c.Masquerade = &kops.KindnetMasqueradeSpec{ + Enabled: fi.PtrTo(true), + } + if clusterSpec.Networking.NetworkCIDR != "" { + c.Masquerade.NonMasqueradeCIDRs = append(c.Masquerade.NonMasqueradeCIDRs, clusterSpec.Networking.NetworkCIDR) + } + if clusterSpec.Networking.PodCIDR != "" { + c.Masquerade.NonMasqueradeCIDRs = append(c.Masquerade.NonMasqueradeCIDRs, clusterSpec.Networking.PodCIDR) + } + if clusterSpec.Networking.ServiceClusterIPRange != "" { + c.Masquerade.NonMasqueradeCIDRs = append(c.Masquerade.NonMasqueradeCIDRs, clusterSpec.Networking.ServiceClusterIPRange) + } + } + + return nil +} diff --git a/upup/models/cloudup/resources/addons/networking.kindnet/k8s-1.12.yaml.template b/upup/models/cloudup/resources/addons/networking.kindnet/k8s-1.12.yaml.template new file mode 100644 index 0000000000000..76ecaee4118f7 --- /dev/null +++ b/upup/models/cloudup/resources/addons/networking.kindnet/k8s-1.12.yaml.template @@ -0,0 +1,2298 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet +rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch + - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - apiGroups: + - "" + resources: + - pods + - namespaces + verbs: + - list + - watch + - apiGroups: + - "networking.k8s.io" + resources: + - networkpolicies + verbs: + - list + - watch +{{- if or .Networking.Kindnet.AdminNetworkPolicies Networking.Kindnet.BaselineAdminNetworkPolicies}} + - apiGroups: + - "policy.networking.k8s.io" + resources: + {{- if .Networking.Kindnet.AdminNetworkPolicies }} + - adminnetworkpolicies + {{- end }} + {{- if .Networking.Kindnet.BaselineAdminNetworkPolicies }} + - baselineadminnetworkpolicies + {{- end }} + verbs: + - list + - watch +{{- end }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kindnet +subjects: +- kind: ServiceAccount + name: kindnet + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kindnet + namespace: kube-system +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kindnet + namespace: kube-system + labels: + tier: node + app: kindnet + k8s-app: kindnet +spec: + selector: + matchLabels: + app: kindnet + template: + metadata: + labels: + tier: node + app: kindnet + k8s-app: kindnet + spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: kindnet + initContainers: + - name: install-cni-bin + image: "ghcr.io/aojea/kindnetd:{{ .Version }}" + command: ['sh', '-c', 'cat /opt/cni/bin/cni-kindnet > /cni/cni-kindnet ; chmod +x /cni/cni-kindnet'] + volumeMounts: + - name: cni-bin + mountPath: /cni + containers: + - name: kindnet-cni + image: "ghcr.io/aojea/kindnetd:{{ .Version }}" + args: + - /bin/kindnetd + - --hostname-override=$(NODE_NAME) + - --v=2 + {{- if .NetworkPolicies }} + - --network-policy={{ .NetworkPolicies }} + {{- end }} + {{- if .AdminNetworkPolicies }} + - --admin-network-policy={{ .AdminNetworkPolicies }} + {{- end }} + {{- if .BaselineAdminNetworkPolicies }} + - --admin-network-policy={{ .BaselineAdminNetworkPolicies }} + {{- end }} + {{- if .DNSCaching }} + - --dns-caching={{ .DNSCaching }} + {{- end }} + {{- if .NAT64 }} + - --nat64={{ .NAT64 }} + {{- end }} + {{- if .FastPathThreshold }} + - --fastpath-threshold={{ .FastPathThreshold }} + {{- end }} + {{- if .Masquerade.Enabled }} + - --masquerading=={{ ..Masquerade.Enabled }} + {{- if .Masquerade.NonMasqueradeCIDRs }} + - --no-masquerade-cidr=={{ range $index, $element := .Items}}{{if $index}},{{end}}{{$element}}{{end}} + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: cni-cfg + mountPath: /etc/cni/net.d + - name: var-lib-kindnet + mountPath: /var/lib/cni-kindnet + resources: + requests: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_RAW", "NET_ADMIN"] + volumes: + - name: cni-bin + hostPath: + path: /opt/cni/bin + type: DirectoryOrCreate + - name: cni-cfg + hostPath: + path: /etc/cni/net.d + type: DirectoryOrCreate + - name: var-lib-kindnet + hostPath: + path: /var/lib/cni-kindnet + type: DirectoryOrCreate +{{- if .Networking.Kindnet.AdminNetworkPolicies }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: experimental + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + Support: Extended + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + domainNames: + description: |- + DomainNames provides a way to specify domain names as peers. + + DomainNames is only supported for ALLOW rules. In order to control + access, DomainNames ALLOW rules should be used with a lower priority + egress deny -- this allows the admin to maintain an explicit "allowlist" + of reachable domains. + + DomainNames can have up to 25 domain names specified in one rule. + + Support: Extended + + + items: + description: |- + DomainName describes one or more domain names to be used as a peer. + + DomainName can be an exact match, or use the wildcard specifier '*' to match + one or more labels. + + '*', the wildcard specifier, matches one or more entire labels. It does not + support partial matches. '*' may only be specified as a prefix. + + Examples: + - `kubernetes.io` matches only `kubernetes.io`. + It does not match "www.kubernetes.io", "blog.kubernetes.io", + "my-kubernetes.io", or "wikipedia.org". + - `blog.kubernetes.io` matches only "blog.kubernetes.io". + It does not match "www.kubernetes.io" or "kubernetes.io". + - `*.kubernetes.io` matches subdomains of kubernetes.io. + "www.kubernetes.io", "blog.kubernetes.io", and + "latest.blog.kubernetes.io" match, however "kubernetes.io", and + "wikipedia.org" do not. + pattern: ^(\*\.)?([a-zA-z0-9]([-a-zA-Z0-9_]*[a-zA-Z0-9])?\.)+[a-zA-z0-9]([-a-zA-Z0-9_]*[a-zA-Z0-9])?\.?$ + type: string + maxItems: 25 + minItems: 1 + type: array + x-kubernetes-list-type: set + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + networks: + description: |- + Networks defines a way to select peers via CIDR blocks. + This is intended for representing entities that live outside the cluster, + which can't be selected by pods, namespaces and nodes peers, but note + that cluster-internal traffic will be checked against the rule as + well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow + or deny all IPv4 pod-to-pod traffic as well. If you don't want that, + add a rule that Passes all pod traffic before the Networks rule. + + Each item in Networks should be provided in the CIDR format and should be + IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8". + + Networks can have upto 25 CIDRs specified. + + Support: Extended + + + items: + description: CIDR is an IP address range in CIDR notation + (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + type: string + x-kubernetes-validations: + - message: Invalid CIDR format provided + rule: isCIDR(self) + maxItems: 25 + minItems: 1 + type: array + x-kubernetes-list-type: set + nodes: + description: |- + Nodes defines a way to select a set of nodes in + the cluster (based on the node's labels). It selects + the nodeIPs as the peer type by matching on the IPs + present in the node.Status.Addresses field of the node. + This field follows standard label selector + semantics; if present but empty, it selects all Nodes. + + Support: Extended + + + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + x-kubernetes-validations: + - message: networks/nodes peer cannot be set with namedPorts since + there are no namedPorts for networks/nodes + rule: '!(self.to.exists(peer, has(peer.networks) || has(peer.nodes)) + && has(self.ports) && self.ports.exists(port, has(port.namedPort)))' + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + Support: Extended + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Policies with lower priority values have + higher precedence, and are checked before policies with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + Every AdminNetworkPolicy should have a unique priority value; if two (or more) + policies with the same priority could both match a connection, then the + implementation can apply any of the matching policies to the connection, and + there is no way for the user to reliably determine which one it will choose. + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} +{{- if .Networking.Kindnet.BaselineAdminNetworkPolicies }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: experimental + creationTimestamp: null + name: baselineadminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: BaselineAdminNetworkPolicy + listKind: BaselineAdminNetworkPolicyList + plural: baselineadminnetworkpolicies + shortNames: + - banp + singular: baselineadminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + BaselineAdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of BaselineAdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods if + they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Egress rules will be allowed in each BANP instance. + The relative precedence of egress rules within a single BANP object + will be determined by the order in which the rule is written. + Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + BANPs with no egress rules do not affect egress traffic. + + Support: Core + items: + description: |- + BaselineAdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a BaselineAdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic + Deny: denies the selected traffic + + Support: Core + enum: + - Allow + - Deny + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + BaselineAdminNetworkPolicies. + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + Support: Extended + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + to: + description: |- + To is the list of destinations whose traffic this rule applies to. + If any BaselineAdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + Support: Core + items: + description: |- + BaselineAdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + networks: + description: |- + Networks defines a way to select peers via CIDR blocks. + This is intended for representing entities that live outside the cluster, + which can't be selected by pods, namespaces and nodes peers, but note + that cluster-internal traffic will be checked against the rule as + well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow + or deny all IPv4 pod-to-pod traffic as well. If you don't want that, + add a rule that Passes all pod traffic before the Networks rule. + + Each item in Networks should be provided in the CIDR format and should be + IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8". + + Networks can have upto 25 CIDRs specified. + + Support: Extended + + + items: + description: CIDR is an IP address range in CIDR notation + (for example, "10.0.0.0/8" or "fd00::/8"). + maxLength: 43 + type: string + x-kubernetes-validations: + - message: Invalid CIDR format provided + rule: isCIDR(self) + maxItems: 25 + minItems: 1 + type: array + x-kubernetes-list-type: set + nodes: + description: |- + Nodes defines a way to select a set of nodes in + the cluster (based on the node's labels). It selects + the nodeIPs as the peer type by matching on the IPs + present in the node.Status.Addresses field of the node. + This field follows standard label selector + semantics; if present but empty, it selects all Nodes. + + Support: Extended + + + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + x-kubernetes-validations: + - message: networks/nodes peer cannot be set with namedPorts since + there are no namedPorts for networks/nodes + rule: '!(self.to.exists(peer, has(peer.networks) || has(peer.nodes)) + && has(self.ports) && self.ports.exists(port, has(port.namedPort)))' + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods + if they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Ingress rules will be allowed in each BANP instance. + The relative precedence of ingress rules within a single BANP object + will be determined by the order in which the rule is written. + Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + BANPs with no ingress rules do not affect ingress traffic. + + Support: Core + items: + description: |- + BaselineAdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by a BaselineAdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic + Deny: denies the selected traffic + + Support: Core + enum: + - Allow + - Deny + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + BaselineAdminNetworkPolicies. + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + namedPort: + description: |- + NamedPort selects a port on a pod(s) based on name. + + Support: Extended + + + type: string + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + subject: + description: |- + Subject defines the pods to which this BaselineAdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + x-kubernetes-validations: + - message: Only one baseline admin network policy with metadata.name="default" + can be created in the cluster + rule: self.metadata.name == 'default' + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} \ No newline at end of file diff --git a/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go b/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go index 0d758aced79e5..ee009f47af066 100644 --- a/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go +++ b/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go @@ -1070,6 +1070,23 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.CloudupModelBuilderContext) } } + if b.Cluster.Spec.Networking.Kindnet != nil { + key := "networking.kindnet" + + { + id := "k8s-1.12" + location := key + "/" + id + ".yaml" + + addons.Add(&channelsapi.AddonSpec{ + Name: fi.PtrTo(key), + Selector: networkingSelector(), + Manifest: fi.PtrTo(location), + Id: id, + NeedsRollingUpdate: channelsapi.NeedsRollingUpdateAll, + }) + } + } + err := addCiliumAddon(b, addons) if err != nil { return nil, nil, fmt.Errorf("failed to add cilium addon: %w", err) diff --git a/upup/pkg/fi/cloudup/new_cluster.go b/upup/pkg/fi/cloudup/new_cluster.go index e028b63f82cee..38b1f2a0f83f7 100644 --- a/upup/pkg/fi/cloudup/new_cluster.go +++ b/upup/pkg/fi/cloudup/new_cluster.go @@ -1262,6 +1262,8 @@ func setupNetworking(opt *NewClusterOptions, cluster *api.Cluster) error { cluster.Spec.Networking.Cilium.IPAM = "eni" case "gcp", "gce": cluster.Spec.Networking.GCP = &api.GCPNetworkingSpec{} + case "kindnet": + cluster.Spec.Networking.Kindnet = &api.KindnetNetworkingSpec{} default: return fmt.Errorf("unknown networking mode %q", opt.Networking) } diff --git a/upup/pkg/fi/cloudup/new_cluster_test.go b/upup/pkg/fi/cloudup/new_cluster_test.go index 20c3351ab0ae1..c2d1bdd16b41c 100644 --- a/upup/pkg/fi/cloudup/new_cluster_test.go +++ b/upup/pkg/fi/cloudup/new_cluster_test.go @@ -313,6 +313,18 @@ func TestSetupNetworking(t *testing.T) { }, }, }, + { + options: NewClusterOptions{ + Networking: "kindnet", + }, + expected: api.Cluster{ + Spec: api.ClusterSpec{ + Networking: api.NetworkingSpec{ + Kindnet: &api.KindnetNetworkingSpec{}, + }, + }, + }, + }, } for _, test := range tests { diff --git a/upup/pkg/fi/cloudup/populate_cluster_spec.go b/upup/pkg/fi/cloudup/populate_cluster_spec.go index c56608600e28f..2bc88ac846efc 100644 --- a/upup/pkg/fi/cloudup/populate_cluster_spec.go +++ b/upup/pkg/fi/cloudup/populate_cluster_spec.go @@ -318,6 +318,7 @@ func (c *populateClusterSpec) run(ctx context.Context, clientset simple.Clientse codeModels = append(codeModels, &components.CloudConfigurationOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.CalicoOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.CiliumOptionsBuilder{Context: optionsContext}) + codeModels = append(codeModels, &components.KindnetOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.OpenStackOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.DiscoveryOptionsBuilder{OptionsContext: optionsContext}) codeModels = append(codeModels, &components.ClusterAutoscalerOptionsBuilder{OptionsContext: optionsContext}) diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 5590166776e69..9bde31d6affb8 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -322,6 +322,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error { loader.Builders = append(loader.Builders, &networking.CommonBuilder{NodeupModelContext: modelContext}) loader.Builders = append(loader.Builders, &networking.CalicoBuilder{NodeupModelContext: modelContext}) loader.Builders = append(loader.Builders, &networking.CiliumBuilder{NodeupModelContext: modelContext}) + loader.Builders = append(loader.Builders, &networking.KindnetBuilder{NodeupModelContext: modelContext}) loader.Builders = append(loader.Builders, &networking.AmazonVPCRoutedENIBuilder{NodeupModelContext: modelContext}) loader.Builders = append(loader.Builders, &networking.KuberouterBuilder{NodeupModelContext: modelContext})