implement ippool

1. support vlan ippool management
2. support calico ippool management

Signed-off-by: Duan Jiong <djduanjiong@gmail.com>
This commit is contained in:
Duan Jiong
2020-04-20 19:01:34 +08:00
parent a7d31930f8
commit 43d1d6f243
91 changed files with 7837 additions and 29 deletions

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 calicov3
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type BlockAffinity struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec v3.BlockAffinitySpec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BlockAffinityList contains a list of BlockAffinity resources.
type BlockAffinityList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []BlockAffinity `json:"items"`
}

View File

@@ -0,0 +1,4 @@
// API Schema definitions for configuring the installation of Calico and Calico Enterprise
// +k8s:deepcopy-gen=package,register
// +groupName=crd.projectcalico.org
package calicov3

View File

@@ -0,0 +1,85 @@
// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 calicov3
import (
v3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
cnet "github.com/projectcalico/libcalico-go/lib/net"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strings"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type IPAMBlock struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec v3.IPAMBlockSpec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IPAMBlockList contains a list of IPAMBlock resources.
type IPAMBlockList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []IPAMBlock `json:"items"`
}
func (b *IPAMBlock) NumReservedAddresses() int {
sum := 0
for _, attrIdx := range b.Spec.Allocations {
if attrIdx == nil {
continue
}
attrs := b.Spec.Attributes[*attrIdx]
if attrs.AttrPrimary == nil || strings.ToLower(*attrs.AttrPrimary) == WindowsReservedHandle {
sum += 1
}
}
return sum
}
// Get number of addresses covered by the block
func (b *IPAMBlock) NumAddresses() int {
_, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR)
ones, size := cidr.Mask.Size()
numAddresses := 1 << uint(size-ones)
return numAddresses
}
func (b *IPAMBlock) NumFreeAddresses() int {
return len(b.Spec.Unallocated)
}
// windwowsReservedHandle is the handle used to reserve addresses required for Windows
// networking so that workloads do not get assigned these addresses.
const WindowsReservedHandle = "windows-reserved-ipam-handle"
func (b *IPAMBlock) Empty() bool {
for _, attrIdx := range b.Spec.Allocations {
if attrIdx == nil {
continue
}
attrs := b.Spec.Attributes[*attrIdx]
if attrs.AttrPrimary == nil || strings.ToLower(*attrs.AttrPrimary) != WindowsReservedHandle {
return false
}
}
return true
}

View File

@@ -0,0 +1,49 @@
// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 calicov3
import (
cnet "github.com/projectcalico/libcalico-go/lib/net"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type IPPool struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec v3.IPPoolSpec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IPPoolList contains a list of IPPool resources.
type IPPoolList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []IPPool `json:"items"`
}
func (p IPPool) NumAddresses() int {
_, cidr, _ := cnet.ParseCIDR(p.Spec.CIDR)
ones, size := cidr.Mask.Size()
numAddresses := 1 << uint(size-ones)
return numAddresses
}

View File

@@ -0,0 +1,42 @@
// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 calicov3
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "crd.projectcalico.org", Version: "v1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme is required by pkg/client/...
AddToScheme = SchemeBuilder.AddToScheme
)
func init() {
SchemeBuilder.Register(&BlockAffinity{}, &BlockAffinityList{})
SchemeBuilder.Register(&IPAMBlock{}, &IPAMBlockList{})
SchemeBuilder.Register(&IPPool{}, &IPPoolList{})
}
// Resource is required by pkg/client/listers/...
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

View File

@@ -0,0 +1,205 @@
// +build !ignore_autogenerated
/*
Copyright 2020 The KubeSphere 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package calicov3
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BlockAffinity) DeepCopyInto(out *BlockAffinity) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlockAffinity.
func (in *BlockAffinity) DeepCopy() *BlockAffinity {
if in == nil {
return nil
}
out := new(BlockAffinity)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BlockAffinity) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BlockAffinityList) DeepCopyInto(out *BlockAffinityList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]BlockAffinity, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlockAffinityList.
func (in *BlockAffinityList) DeepCopy() *BlockAffinityList {
if in == nil {
return nil
}
out := new(BlockAffinityList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BlockAffinityList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMBlock) DeepCopyInto(out *IPAMBlock) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMBlock.
func (in *IPAMBlock) DeepCopy() *IPAMBlock {
if in == nil {
return nil
}
out := new(IPAMBlock)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMBlock) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMBlockList) DeepCopyInto(out *IPAMBlockList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IPAMBlock, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMBlockList.
func (in *IPAMBlockList) DeepCopy() *IPAMBlockList {
if in == nil {
return nil
}
out := new(IPAMBlockList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMBlockList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPool) DeepCopyInto(out *IPPool) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPool.
func (in *IPPool) DeepCopy() *IPPool {
if in == nil {
return nil
}
out := new(IPPool)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPPool) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPoolList) DeepCopyInto(out *IPPoolList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IPPool, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolList.
func (in *IPPoolList) DeepCopy() *IPPoolList {
if in == nil {
return nil
}
out := new(IPPoolList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPPoolList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@@ -0,0 +1,341 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
"fmt"
"github.com/projectcalico/libcalico-go/lib/names"
"math/big"
"reflect"
"strings"
cnet "github.com/projectcalico/libcalico-go/lib/net"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
ResourceKindIPAMBlock = "IPAMBlock"
ResourceSingularIPAMBlock = "ipamblock"
ResourcePluralIPAMBlock = "ipamblocks"
IPAMBlockAttributePod = "pod"
IPAMBlockAttributeVm = "vm"
IPAMBlockAttributeWorkloadType = "workload-type"
IPAMBlockAttributeNamespace = "namespace"
IPAMBlockAttributeWorkspace = "workspace"
IPAMBlockAttributeNode = "node"
IPAMBlockAttributePool = "pool-name"
IPAMBlockAttributeType = "pool-type"
ReservedHandle = "kubesphere-reserved-handle"
ReservedNote = "kubesphere reserved"
)
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type IPAMBlock struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
metav1.ObjectMeta `json:"metadata,omitempty"`
// Specification of the IPAMBlock.
Spec IPAMBlockSpec `json:"spec,omitempty"`
}
// IPAMBlockSpec contains the specification for an IPAMBlock resource.
type IPAMBlockSpec struct {
ID uint32 `json:"id"`
CIDR string `json:"cidr"`
Allocations []*int `json:"allocations"`
Unallocated []int `json:"unallocated"`
Attributes []AllocationAttribute `json:"attributes"`
Deleted bool `json:"deleted"`
}
type AllocationAttribute struct {
AttrPrimary string `json:"handle_id,omitempty"`
AttrSecondary map[string]string `json:"secondary,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
type IPAMBlockList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []IPAMBlock `json:"items"`
}
// The caller needs to check that the returned slice length is correct.
func (b *IPAMBlock) AutoAssign(
num int, handleID string, attrs map[string]string) []cnet.IPNet {
// Walk the allocations until we find enough addresses.
ordinals := []int{}
for len(b.Spec.Unallocated) > 0 && len(ordinals) < num {
ordinals = append(ordinals, b.Spec.Unallocated[0])
b.Spec.Unallocated = b.Spec.Unallocated[1:]
}
// Create slice of IPs and perform the allocations.
ips := []cnet.IPNet{}
ip, mask, _ := cnet.ParseCIDR(b.Spec.CIDR)
for _, o := range ordinals {
attrIndex := b.findOrAddAttribute(handleID, attrs)
b.Spec.Allocations[o] = &attrIndex
ipNets := cnet.IPNet(*mask)
ipNets.IP = cnet.IncrementIP(*ip, big.NewInt(int64(o))).IP
ips = append(ips, ipNets)
}
return ips
}
func (b *IPAMBlock) String() string {
return fmt.Sprintf("%d-%s", b.Spec.ID, b.Spec.CIDR)
}
func (b *IPAMBlock) ID() uint32 {
return b.Spec.ID
}
func (b *IPAMBlock) BlockName() string {
_, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR)
return fmt.Sprintf("%d-%s", b.ID(), names.CIDRToName(*cidr))
}
// Get number of addresses covered by the block
func (b *IPAMBlock) NumAddresses() int {
_, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR)
ones, size := cidr.Mask.Size()
numAddresses := 1 << uint(size-ones)
return numAddresses
}
// Find the ordinal (i.e. how far into the block) a given IP lies. Returns an error if the IP is outside the block.
func (b *IPAMBlock) IPToOrdinal(ip cnet.IP) (int, error) {
netIP, _, _ := cnet.ParseCIDR(b.Spec.CIDR)
ipAsInt := cnet.IPToBigInt(ip)
baseInt := cnet.IPToBigInt(*netIP)
ord := big.NewInt(0).Sub(ipAsInt, baseInt).Int64()
if ord < 0 || ord >= int64(b.NumAddresses()) {
return 0, fmt.Errorf("IP %s not in block %d-%s", ip, b.Spec.ID, b.Spec.CIDR)
}
return int(ord), nil
}
func (b *IPAMBlock) NumFreeAddresses() int {
return len(b.Spec.Unallocated)
}
// empty returns true if the block has released all of its assignable addresses,
// and returns false if any assignable addresses are in use.
func (b *IPAMBlock) Empty() bool {
return b.containsOnlyReservedIPs()
}
func (b *IPAMBlock) MarkDeleted() {
b.Spec.Deleted = true
}
func (b *IPAMBlock) IsDeleted() bool {
return b.Spec.Deleted
}
// containsOnlyReservedIPs returns true if the block is empty excepted for
// expected "reserved" IP addresses.
func (b *IPAMBlock) containsOnlyReservedIPs() bool {
for _, attrIdx := range b.Spec.Allocations {
if attrIdx == nil {
continue
}
attrs := b.Spec.Attributes[*attrIdx]
if strings.ToLower(attrs.AttrPrimary) != ReservedHandle {
return false
}
}
return true
}
func (b *IPAMBlock) NumReservedAddresses() int {
sum := 0
for _, attrIdx := range b.Spec.Allocations {
if attrIdx == nil {
continue
}
attrs := b.Spec.Attributes[*attrIdx]
if strings.ToLower(attrs.AttrPrimary) == ReservedHandle {
sum += 1
}
}
return sum
}
func (b IPAMBlock) attributeIndexesByHandle(handleID string) []int {
indexes := []int{}
for i, attr := range b.Spec.Attributes {
if attr.AttrPrimary == handleID {
indexes = append(indexes, i)
}
}
return indexes
}
func (b *IPAMBlock) deleteAttributes(delIndexes, ordinals []int) {
newIndexes := make([]*int, len(b.Spec.Attributes))
newAttrs := []AllocationAttribute{}
y := 0 // Next free slot in the new attributes list.
for x := range b.Spec.Attributes {
if !intInSlice(x, delIndexes) {
// Attribute at x is not being deleted. Build a mapping
// of old attribute index (x) to new attribute index (y).
newIndex := y
newIndexes[x] = &newIndex
y += 1
newAttrs = append(newAttrs, b.Spec.Attributes[x])
}
}
b.Spec.Attributes = newAttrs
// Update attribute indexes for all allocations in this block.
for i := 0; i < b.NumAddresses(); i++ {
if b.Spec.Allocations[i] != nil {
// Get the new index that corresponds to the old index
// and update the allocation.
newIndex := newIndexes[*b.Spec.Allocations[i]]
b.Spec.Allocations[i] = newIndex
}
}
}
func (b *IPAMBlock) ReleaseByHandle(handleID string) int {
attrIndexes := b.attributeIndexesByHandle(handleID)
if len(attrIndexes) == 0 {
// Nothing to release.
return 0
}
// There are addresses to release.
ordinals := []int{}
var o int
for o = 0; o < b.NumAddresses(); o++ {
// Only check allocated ordinals.
if b.Spec.Allocations[o] != nil && intInSlice(*b.Spec.Allocations[o], attrIndexes) {
// Release this ordinal.
ordinals = append(ordinals, o)
}
}
// Clean and reorder attributes.
b.deleteAttributes(attrIndexes, ordinals)
// Release the addresses.
for _, o := range ordinals {
b.Spec.Allocations[o] = nil
b.Spec.Unallocated = append(b.Spec.Unallocated, o)
}
return len(ordinals)
}
func (b *IPAMBlock) findOrAddAttribute(handleID string, attrs map[string]string) int {
attr := AllocationAttribute{handleID, attrs}
for idx, existing := range b.Spec.Attributes {
if reflect.DeepEqual(attr, existing) {
return idx
}
}
// Does not exist - add it.
attrIndex := len(b.Spec.Attributes)
b.Spec.Attributes = append(b.Spec.Attributes, attr)
return attrIndex
}
func intInSlice(searchInt int, slice []int) bool {
for _, v := range slice {
if v == searchInt {
return true
}
}
return false
}
//This just initializes the data structure and does not call the api to create
func NewBlock(pool *IPPool, cidr cnet.IPNet, rsvdAttr *ReservedAttr) *IPAMBlock {
b := IPAMBlock{}
b.Labels = map[string]string{
IPPoolNameLabel: pool.Name,
}
b.Spec.CIDR = cidr.String()
b.Spec.ID = pool.ID()
b.Name = b.BlockName()
numAddresses := b.NumAddresses()
b.Spec.Allocations = make([]*int, numAddresses)
b.Spec.Unallocated = make([]int, numAddresses)
// Initialize unallocated ordinals.
for i := 0; i < numAddresses; i++ {
b.Spec.Unallocated[i] = i
}
if rsvdAttr != nil {
// Reserve IPs based on host reserved attributes.
// For example, with windows OS, the following IP addresses of the block are
// reserved. This is done by pre-allocating them during initialization
// time only.
// IPs : x.0, x.1, x.2 and x.bcastAddr (e.g. x.255 for /24 subnet)
// nil attributes
attrs := make(map[string]string)
attrs["note"] = rsvdAttr.Note
handleID := rsvdAttr.Handle
b.Spec.Unallocated = b.Spec.Unallocated[rsvdAttr.StartOfBlock : numAddresses-rsvdAttr.EndOfBlock]
attrIndex := len(b.Spec.Attributes)
for i := 0; i < rsvdAttr.StartOfBlock; i++ {
b.Spec.Allocations[i] = &attrIndex
}
for i := 1; i <= rsvdAttr.EndOfBlock; i++ {
b.Spec.Allocations[numAddresses-i] = &attrIndex
}
// Create slice of IPs and perform the allocations.
attr := AllocationAttribute{
AttrPrimary: handleID,
AttrSecondary: attrs,
}
b.Spec.Attributes = append(b.Spec.Attributes, attr)
}
return &b
}
type ReservedAttr struct {
// Number of addresses reserved from start of the block.
StartOfBlock int
// Number of addresses reserved from end of the block.
EndOfBlock int
// Handle for reserved addresses.
Handle string
// A description about the reserves.
Note string
}

View File

@@ -0,0 +1,85 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
cnet "github.com/projectcalico/libcalico-go/lib/net"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)
func TestIPAMBlock(t *testing.T) {
pool := &IPPool{
ObjectMeta: v1.ObjectMeta{
Name: "testippool",
},
Spec: IPPoolSpec{
Type: VLAN,
CIDR: "192.168.0.0/24",
RangeEnd: "192.168.0.250",
RangeStart: "192.168.0.10",
},
}
handleID := "testhandle"
_, cidr, _ := cnet.ParseCIDR("192.168.0.0/24")
block := NewBlock(pool, *cidr, &ReservedAttr{
StartOfBlock: 10,
EndOfBlock: 10,
Handle: ReservedHandle,
Note: ReservedNote,
})
reserved := block.NumReservedAddresses()
if reserved != 20 {
t.Fail()
}
total := block.NumAddresses()
free := block.NumFreeAddresses()
if free != total-reserved {
t.Fail()
}
t.Log("Allocate 10 addresses from block")
ips := block.AutoAssign(10, handleID, nil)
if len(ips) != 10 {
t.Fail()
}
free = block.NumFreeAddresses()
if free != total-reserved-10 {
t.Fail()
}
t.Log("Allocate 1000 addresses from block")
ips = block.AutoAssign(1000, handleID, nil)
if len(ips) != free {
t.Fail()
}
free = block.NumFreeAddresses()
if free != 0 {
t.Fail()
}
t.Log("Free address from block")
if block.ReleaseByHandle(handleID) != total-reserved {
t.Fail()
}
}

View File

@@ -0,0 +1,110 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
"fmt"
"github.com/projectcalico/libcalico-go/lib/names"
cnet "github.com/projectcalico/libcalico-go/lib/net"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strconv"
"strings"
)
const (
ResourceKindIPAMHandle = "IPAMHandle"
ResourceSingularIPAMHandle = "ipamhandle"
ResourcePluralIPAMHandle = "ipamhandles"
)
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type IPAMHandle struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
metav1.ObjectMeta `json:"metadata,omitempty"`
// Specification of the IPAMHandle.
Spec IPAMHandleSpec `json:"spec,omitempty"`
}
// IPAMHandleSpec contains the specification for an IPAMHandle resource.
type IPAMHandleSpec struct {
HandleID string `json:"handleID"`
Block map[string]int `json:"block"`
Deleted bool `json:"deleted"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
type IPAMHandleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []IPAMHandle `json:"items"`
}
func (h *IPAMHandle) IncrementBlock(block *IPAMBlock, num int) int {
newNum := num
if val, ok := h.Spec.Block[block.String()]; ok {
// An entry exists for this block, increment the number
// of allocations.
newNum = val + num
}
h.Spec.Block[block.String()] = newNum
return newNum
}
func (h *IPAMHandle) Empty() bool {
return len(h.Spec.Block) == 0
}
func (h *IPAMHandle) MarkDeleted() {
h.Spec.Deleted = true
}
func (h *IPAMHandle) IsDeleted() bool {
return h.Spec.Deleted
}
func (h *IPAMHandle) DecrementBlock(block *IPAMBlock, num int) (*int, error) {
if current, ok := h.Spec.Block[block.String()]; !ok {
// This entry doesn't exist.
return nil, fmt.Errorf("Tried to decrement block %s by %v but it isn't linked to handle %s", block.BlockName(), num, h.Spec.HandleID)
} else {
newNum := current - num
if newNum < 0 {
return nil, fmt.Errorf("Tried to decrement block %s by %v but it only has %v addresses on handle %s", block.BlockName(), num, current, h.Spec.HandleID)
}
if newNum == 0 {
delete(h.Spec.Block, block.String())
} else {
h.Spec.Block[block.String()] = newNum
}
return &newNum, nil
}
}
func ConvertToBlockName(k string) string {
strs := strings.SplitN(k, "-", 2)
id, _ := strconv.Atoi(strs[0])
_, blockCIDR, _ := cnet.ParseCIDR(strs[1])
return fmt.Sprintf("%d-%s", id, names.CIDRToName(*blockCIDR))
}

View File

@@ -0,0 +1,62 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)
func TestIPAMHandle(t *testing.T) {
block := &IPAMBlock{
Spec: IPAMBlockSpec{
ID: 3,
CIDR: "192.168.0.0/24",
},
}
block.Name = block.BlockName()
handle := IPAMHandle{
TypeMeta: v1.TypeMeta{},
ObjectMeta: v1.ObjectMeta{
Name: "testhandle",
},
Spec: IPAMHandleSpec{
HandleID: "testhandle",
Block: map[string]int{
block.String(): 10,
},
},
}
t.Log("incrementBlock with 10")
if handle.IncrementBlock(block, 10) != 20 {
t.FailNow()
}
t.Log("DecrementBlock with 20")
num, _ := handle.DecrementBlock(block, 20)
if *num != 0 {
t.FailNow()
}
t.Log("DecrementBlock with 1")
_, err := handle.DecrementBlock(block, 1)
if err == nil {
t.FailNow()
}
}

View File

@@ -0,0 +1,203 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
"fmt"
"math/big"
cnet "github.com/projectcalico/libcalico-go/lib/net"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
ResourceKindIPPool = "IPPool"
ResourceSingularIPPool = "ippool"
ResourcePluralIPPool = "ippools"
// scope type > id > name
// id used to detect cidr overlap
IPPoolTypeLabel = "ippool.network.kubesphere.io/type"
IPPoolNameLabel = "ippool.network.kubesphere.io/name"
IPPoolIDLabel = "ippool.network.kubesphere.io/id"
)
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster
type IPPool struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Spec IPPoolSpec `json:"spec,omitempty"`
// +optional
Status IPPoolStatus `json:"status,omitempty"`
}
type VLANConfig struct {
VlanId uint32 `json:"vlanId"`
Master string `json:"master"`
}
type Route struct {
Dst string `json:"dst,omitempty"`
GW string `json:"gateway,omitempty"`
}
// DNS contains values interesting for DNS resolvers
type DNS struct {
Nameservers []string `json:"nameservers,omitempty"`
Domain string `json:"domain,omitempty"`
Search []string `json:"search,omitempty"`
Options []string `json:"options,omitempty"`
}
type IPPoolStatus struct {
Unallocated int `json:"unallocated,omitempty"`
Allocations int `json:"allocations,omitempty"`
Capacity int `json:"capacity,omitempty"`
Reserved int `json:"reserved,omitempty"`
Synced bool `json:"synced,omitempty"`
}
type IPPoolSpec struct {
Type string `json:"type"`
// The pool CIDR.
CIDR string `json:"cidr"`
// The first ip, inclusive
RangeStart string `json:"rangeStart,omitempty"`
// The last ip, inclusive
RangeEnd string `json:"rangeEnd,omitempty"`
// When disabled is true, IPAM will not assign addresses from this pool.
Disabled bool `json:"disabled,omitempty"`
// The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 112 for IPv6.
BlockSize int `json:"blockSize,omitempty"`
VLAN VLANConfig `json:"vlanConfig,omitempty"`
Gateway string `json:"gateway,omitempty"`
Routes []Route `json:"routes,omitempty"`
DNS DNS `json:"dns,omitempty"`
Workspace string `json:"workspace,omitempty"`
Namespace string `json:"namespace,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
type IPPoolList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []IPPool `json:"items"`
}
const (
VLAN = "vlan"
Calico = "calico"
Porter = "porter"
Pod = "pod"
VLANIDStart = 1
VLANIDEnd = 4097
PorterID = 4098
CalicoID = 4099
PodID = 0
)
// Find the ordinal (i.e. how far into the block) a given IP lies. Returns an error if the IP is outside the block.
func (b IPPool) IPToOrdinal(ip cnet.IP) (int, error) {
netIP, _, _ := cnet.ParseCIDR(b.Spec.CIDR)
ipAsInt := cnet.IPToBigInt(ip)
baseInt := cnet.IPToBigInt(*netIP)
ord := big.NewInt(0).Sub(ipAsInt, baseInt).Int64()
if ord < 0 || ord >= int64(b.NumAddresses()) {
return 0, fmt.Errorf("IP %s not in pool %s", ip, b.Spec.CIDR)
}
return int(ord), nil
}
// Get number of addresses covered by the block
func (b IPPool) NumAddresses() int {
_, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR)
ones, size := cidr.Mask.Size()
numAddresses := 1 << uint(size-ones)
return numAddresses
}
func (b IPPool) NumReservedAddresses() int {
return b.StartReservedAddressed() + b.EndReservedAddressed()
}
func (b IPPool) StartReservedAddressed() int {
if b.Spec.RangeStart == "" {
return 0
}
start, _ := b.IPToOrdinal(*cnet.ParseIP(b.Spec.RangeStart))
return start
}
func (b IPPool) EndReservedAddressed() int {
if b.Spec.RangeEnd == "" {
return 0
}
total := b.NumAddresses()
end, _ := b.IPToOrdinal(*cnet.ParseIP(b.Spec.RangeEnd))
return total - end - 1
}
func (pool IPPool) ID() uint32 {
switch pool.Spec.Type {
case VLAN:
return pool.Spec.VLAN.VlanId + VLANIDStart
case Porter:
return PorterID
case Calico:
return CalicoID
}
return PodID
}
func (p IPPool) TypeInvalid() bool {
typeStr := p.Spec.Type
if typeStr == VLAN || typeStr == Porter || typeStr == Pod {
return false
}
return true
}
func (p IPPool) Disabled() bool {
return p.Spec.Disabled
}
func (p IPPool) V4() bool {
ip, _, _ := cnet.ParseCIDR(p.Spec.CIDR)
if ip.To4() != nil {
return true
}
return false
}
const IPPoolFinalizer = "finalizers.network.kubesphere.io/ippool"

View File

@@ -0,0 +1,65 @@
/*
Copyright 2020 The KubeSphere 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 v1alpha1
import (
"testing"
cnet "github.com/projectcalico/libcalico-go/lib/net"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestIPPool(t *testing.T) {
pool := &IPPool{
ObjectMeta: v1.ObjectMeta{
Name: "testippool",
},
Spec: IPPoolSpec{
Type: VLAN,
CIDR: "192.168.0.0/24",
RangeEnd: "192.168.0.250",
RangeStart: "192.168.0.10",
},
}
input := cnet.ParseIP("192.168.0.1")
offset, _ := pool.IPToOrdinal(*input)
if offset != 1 {
t.Fail()
}
input = cnet.ParseIP("192.168.1.1")
_, err := pool.IPToOrdinal(*input)
if err == nil {
t.Fail()
}
if pool.NumAddresses() != 256 {
t.Fail()
}
if pool.StartReservedAddressed() != 10 {
t.Fail()
}
if pool.EndReservedAddressed() != 5 {
t.Fail()
}
if pool.NumReservedAddresses() != 15 {
t.Fail()
}
}

View File

@@ -148,7 +148,3 @@ type NamespaceNetworkPolicyList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []NamespaceNetworkPolicy `json:"items"`
}
func init() {
SchemeBuilder.Register(&NamespaceNetworkPolicy{}, &NamespaceNetworkPolicyList{})
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 The KubeSphere authors.
Copyright 2020 The KubeSphere authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -40,6 +40,13 @@ var (
AddToScheme = SchemeBuilder.AddToScheme
)
func init() {
SchemeBuilder.Register(&IPAMHandle{}, &IPAMHandleList{})
SchemeBuilder.Register(&IPAMBlock{}, &IPAMBlockList{})
SchemeBuilder.Register(&IPPool{}, &IPPoolList{})
SchemeBuilder.Register(&NamespaceNetworkPolicy{}, &NamespaceNetworkPolicyList{})
}
// Resource is required by pkg/client/listers/...
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()

View File

@@ -16,22 +16,345 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha1
import (
v1 "k8s.io/api/networking/v1"
"k8s.io/api/networking/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AllocationAttribute) DeepCopyInto(out *AllocationAttribute) {
*out = *in
if in.AttrSecondary != nil {
in, out := &in.AttrSecondary, &out.AttrSecondary
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllocationAttribute.
func (in *AllocationAttribute) DeepCopy() *AllocationAttribute {
if in == nil {
return nil
}
out := new(AllocationAttribute)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DNS) DeepCopyInto(out *DNS) {
*out = *in
if in.Nameservers != nil {
in, out := &in.Nameservers, &out.Nameservers
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Search != nil {
in, out := &in.Search, &out.Search
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Options != nil {
in, out := &in.Options, &out.Options
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNS.
func (in *DNS) DeepCopy() *DNS {
if in == nil {
return nil
}
out := new(DNS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMBlock) DeepCopyInto(out *IPAMBlock) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMBlock.
func (in *IPAMBlock) DeepCopy() *IPAMBlock {
if in == nil {
return nil
}
out := new(IPAMBlock)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMBlock) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMBlockList) DeepCopyInto(out *IPAMBlockList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IPAMBlock, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMBlockList.
func (in *IPAMBlockList) DeepCopy() *IPAMBlockList {
if in == nil {
return nil
}
out := new(IPAMBlockList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMBlockList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMBlockSpec) DeepCopyInto(out *IPAMBlockSpec) {
*out = *in
if in.Allocations != nil {
in, out := &in.Allocations, &out.Allocations
*out = make([]*int, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(int)
**out = **in
}
}
}
if in.Unallocated != nil {
in, out := &in.Unallocated, &out.Unallocated
*out = make([]int, len(*in))
copy(*out, *in)
}
if in.Attributes != nil {
in, out := &in.Attributes, &out.Attributes
*out = make([]AllocationAttribute, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMBlockSpec.
func (in *IPAMBlockSpec) DeepCopy() *IPAMBlockSpec {
if in == nil {
return nil
}
out := new(IPAMBlockSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMHandle) DeepCopyInto(out *IPAMHandle) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMHandle.
func (in *IPAMHandle) DeepCopy() *IPAMHandle {
if in == nil {
return nil
}
out := new(IPAMHandle)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMHandle) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMHandleList) DeepCopyInto(out *IPAMHandleList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IPAMHandle, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMHandleList.
func (in *IPAMHandleList) DeepCopy() *IPAMHandleList {
if in == nil {
return nil
}
out := new(IPAMHandleList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPAMHandleList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPAMHandleSpec) DeepCopyInto(out *IPAMHandleSpec) {
*out = *in
if in.Block != nil {
in, out := &in.Block, &out.Block
*out = make(map[string]int, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAMHandleSpec.
func (in *IPAMHandleSpec) DeepCopy() *IPAMHandleSpec {
if in == nil {
return nil
}
out := new(IPAMHandleSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPool) DeepCopyInto(out *IPPool) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPool.
func (in *IPPool) DeepCopy() *IPPool {
if in == nil {
return nil
}
out := new(IPPool)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPPool) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPoolList) DeepCopyInto(out *IPPoolList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IPPool, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolList.
func (in *IPPoolList) DeepCopy() *IPPoolList {
if in == nil {
return nil
}
out := new(IPPoolList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IPPoolList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPoolSpec) DeepCopyInto(out *IPPoolSpec) {
*out = *in
out.VLAN = in.VLAN
if in.Routes != nil {
in, out := &in.Routes, &out.Routes
*out = make([]Route, len(*in))
copy(*out, *in)
}
in.DNS.DeepCopyInto(&out.DNS)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolSpec.
func (in *IPPoolSpec) DeepCopy() *IPPoolSpec {
if in == nil {
return nil
}
out := new(IPPoolSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPPoolStatus) DeepCopyInto(out *IPPoolStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPoolStatus.
func (in *IPPoolStatus) DeepCopy() *IPPoolStatus {
if in == nil {
return nil
}
out := new(IPPoolStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NamespaceNetworkPolicy) DeepCopyInto(out *NamespaceNetworkPolicy) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicy.
@@ -64,7 +387,6 @@ func (in *NamespaceNetworkPolicyList) DeepCopyInto(out *NamespaceNetworkPolicyLi
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicyList.
@@ -107,7 +429,6 @@ func (in *NamespaceNetworkPolicySpec) DeepCopyInto(out *NamespaceNetworkPolicySp
*out = make([]v1.PolicyType, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicySpec.
@@ -123,7 +444,6 @@ func (in *NamespaceNetworkPolicySpec) DeepCopy() *NamespaceNetworkPolicySpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NamespaceSelector) DeepCopyInto(out *NamespaceSelector) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceSelector.
@@ -153,7 +473,6 @@ func (in *NetworkPolicyEgressRule) DeepCopyInto(out *NetworkPolicyEgressRule) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyEgressRule.
@@ -183,7 +502,6 @@ func (in *NetworkPolicyIngressRule) DeepCopyInto(out *NetworkPolicyIngressRule)
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyIngressRule.
@@ -214,7 +532,6 @@ func (in *NetworkPolicyPeer) DeepCopyInto(out *NetworkPolicyPeer) {
*out = new(ServiceSelector)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyPeer.
@@ -227,10 +544,39 @@ func (in *NetworkPolicyPeer) DeepCopy() *NetworkPolicyPeer {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ReservedAttr) DeepCopyInto(out *ReservedAttr) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReservedAttr.
func (in *ReservedAttr) DeepCopy() *ReservedAttr {
if in == nil {
return nil
}
out := new(ReservedAttr)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Route) DeepCopyInto(out *Route) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route.
func (in *Route) DeepCopy() *Route {
if in == nil {
return nil
}
out := new(Route)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceSelector) DeepCopyInto(out *ServiceSelector) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSelector.
@@ -242,3 +588,18 @@ func (in *ServiceSelector) DeepCopy() *ServiceSelector {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VLANConfig) DeepCopyInto(out *VLANConfig) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VLANConfig.
func (in *VLANConfig) DeepCopy() *VLANConfig {
if in == nil {
return nil
}
out := new(VLANConfig)
in.DeepCopyInto(out)
return out
}