Skip to content

Commit

Permalink
Implement NetworkInterfaceBinding resource
Browse files Browse the repository at this point in the history
* Add the `NetworkInterfaceBinding` type
* Implement validation & tests for that type
* Fix some copy-paste errors across `networking` types
  • Loading branch information
adracus committed Apr 27, 2022
1 parent 7c03f3a commit c5f98c6
Show file tree
Hide file tree
Showing 49 changed files with 2,701 additions and 353 deletions.
39 changes: 39 additions & 0 deletions apis/networking/networkinterfacebinding_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2022 OnMetal 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 (
commonv1alpha1 "github.com/onmetal/onmetal-api/apis/common/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NetworkInterfaceBinding is the Schema for the networkinterfacebindings API
type NetworkInterfaceBinding struct {
metav1.TypeMeta
metav1.ObjectMeta
IPs []commonv1alpha1.IP
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NetworkInterfaceBindingList contains a list of NetworkInterfaceBinding
type NetworkInterfaceBindingList struct {
metav1.TypeMeta
metav1.ListMeta
Items []NetworkInterfaceBinding
}
6 changes: 4 additions & 2 deletions apis/networking/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ func Resource(name string) schema.GroupResource {

func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&NetworkInterface{},
&NetworkInterfaceList{},
&Network{},
&NetworkList{},
&NetworkInterface{},
&NetworkInterfaceList{},
&NetworkInterfaceBinding{},
&NetworkInterfaceBindingList{},
&VirtualIP{},
&VirtualIPList{},
&VirtualIPRouting{},
Expand Down
39 changes: 39 additions & 0 deletions apis/networking/v1alpha1/networkinterfacebinding_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2022 OnMetal 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 (
commonv1alpha1 "github.com/onmetal/onmetal-api/apis/common/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NetworkInterfaceBinding is the Schema for the networkinterfacebindings API
type NetworkInterfaceBinding struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
IPs []commonv1alpha1.IP `json:"ips,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NetworkInterfaceBindingList contains a list of NetworkInterfaceBinding
type NetworkInterfaceBindingList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NetworkInterfaceBinding `json:"items"`
}
6 changes: 4 additions & 2 deletions apis/networking/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ func Resource(name string) schema.GroupResource {

func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&NetworkInterface{},
&NetworkInterfaceList{},
&Network{},
&NetworkList{},
&NetworkInterface{},
&NetworkInterfaceList{},
&NetworkInterfaceBinding{},
&NetworkInterfaceBindingList{},
&VirtualIP{},
&VirtualIPList{},
&VirtualIPRouting{},
Expand Down
64 changes: 64 additions & 0 deletions apis/networking/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions apis/networking/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions apis/networking/validation/networkinterfacebinding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2022 OnMetal 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 validation

import (
"fmt"

commonv1alpha1validation "github.com/onmetal/onmetal-api/apis/common/v1alpha1/validation"
"github.com/onmetal/onmetal-api/apis/networking"
corev1 "k8s.io/api/core/v1"
apivalidation "k8s.io/apimachinery/pkg/api/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
)

func ValidateNetworkInterfaceBinding(networkInterfaceBinding *networking.NetworkInterfaceBinding) field.ErrorList {
var allErrs field.ErrorList

allErrs = append(allErrs, apivalidation.ValidateObjectMetaAccessor(networkInterfaceBinding, true, apivalidation.NameIsDNSLabel, field.NewPath("metadata"))...)

seenIPFamilies := make(map[corev1.IPFamily]struct{})
for i, ip := range networkInterfaceBinding.IPs {
allErrs = append(allErrs, commonv1alpha1validation.ValidateIP(ip.Family(), ip, field.NewPath("ips").Index(i))...)

if _, ok := seenIPFamilies[ip.Family()]; ok {
allErrs = append(allErrs, field.Forbidden(field.NewPath("ips").Index(i), fmt.Sprintf("duplicate ip family %q", ip.Family())))
}
seenIPFamilies[ip.Family()] = struct{}{}
}

return allErrs
}

func ValidateNetworkInterfaceBindingUpdate(newNetworkInterfaceBinding, oldNetworkInterfaceBinding *networking.NetworkInterfaceBinding) field.ErrorList {
var allErrs field.ErrorList

allErrs = append(allErrs, apivalidation.ValidateObjectMetaAccessorUpdate(newNetworkInterfaceBinding, oldNetworkInterfaceBinding, field.NewPath("metadata"))...)
allErrs = append(allErrs, ValidateNetworkInterfaceBinding(newNetworkInterfaceBinding)...)

return allErrs
}
83 changes: 83 additions & 0 deletions apis/networking/validation/networkinterfacebinding_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2022 by the OnMetal 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 validation

import (
commonv1alpha1 "github.com/onmetal/onmetal-api/apis/common/v1alpha1"
"github.com/onmetal/onmetal-api/apis/networking"
. "github.com/onmetal/onmetal-api/testutils/validation"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("NetworkInterfaceBinding", func() {
DescribeTable("ValidateNetworkInterfaceBinding",
func(networkInterfaceBinding *networking.NetworkInterfaceBinding, match types.GomegaMatcher) {
errList := ValidateNetworkInterfaceBinding(networkInterfaceBinding)
Expect(errList).To(match)
},
Entry("missing name",
&networking.NetworkInterfaceBinding{},
ContainElement(RequiredField("metadata.name")),
),
Entry("missing namespace",
&networking.NetworkInterfaceBinding{ObjectMeta: metav1.ObjectMeta{Name: "foo"}},
ContainElement(RequiredField("metadata.namespace")),
),
Entry("bad name",
&networking.NetworkInterfaceBinding{ObjectMeta: metav1.ObjectMeta{Name: "foo*"}},
ContainElement(InvalidField("metadata.name")),
),
Entry("invalid ip",
&networking.NetworkInterfaceBinding{
IPs: []commonv1alpha1.IP{{}},
},
ContainElement(InvalidField("ips[0]")),
),
Entry("duplicate ip family",
&networking.NetworkInterfaceBinding{
IPs: []commonv1alpha1.IP{
commonv1alpha1.MustParseIP("10.0.0.1"),
commonv1alpha1.MustParseIP("10.0.0.2"),
},
},
ContainElement(ForbiddenField("ips[1]")),
),
Entry("valid network interface binding with two ips",
&networking.NetworkInterfaceBinding{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "foo",
},
IPs: []commonv1alpha1.IP{
commonv1alpha1.MustParseIP("10.0.0.1"),
commonv1alpha1.MustParseIP("beef::"),
},
},
BeEmpty(),
),
)

DescribeTable("ValidateNetworkInterfaceBindingUpdate",
func(newNetworkInterfaceBinding, oldNetworkInterfaceBinding *networking.NetworkInterfaceBinding, match types.GomegaMatcher) {
errList := ValidateNetworkInterfaceBindingUpdate(newNetworkInterfaceBinding, oldNetworkInterfaceBinding)
Expect(errList).To(match)
},
)
})
Loading

0 comments on commit c5f98c6

Please sign in to comment.