Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Track delay caused by controllers Downtime #119

Open
wants to merge 5 commits into
base: add-kos
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions staging/kos/glide.lock

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

63 changes: 63 additions & 0 deletions staging/kos/pkg/apis/network/helper/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Copyright 2020 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 helper contains helper functions for the internal version of the
// network API types.
package helper

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"

"k8s.io/examples/staging/kos/pkg/apis/network"
)

// ValidateExtendedObjectMeta returns a list of errors carrying information on
// why `eom` is invalid, or an empty list if `eom` is valid.
func ValidateExtendedObjectMeta(eom network.ExtendedObjectMeta) field.ErrorList {
errs := field.ErrorList{}
if err := ValidateClientWrite(eom.LastClientWrite); err != nil {
path := field.NewPath("extendedObjectMeta").Child("lastClientWrite")
errs = append(errs, field.Invalid(path, eom.LastClientWrite, err.Error()))
}
if err := ValidateControllerStart(eom.LastControllerStart); err != nil {
path := field.NewPath("extendedObjectMeta").Child("lastControllerStart")
errs = append(errs, field.Invalid(path, eom.LastControllerStart, err.Error()))
}
return errs
}

// ValidateClientWrite checks whether `cw` fields are consistent.
func ValidateClientWrite(cw network.ClientWrite) error {
return validateTimedField(cw.Time, cw.Name, "name")
}

// ValidateControllerStart checks whether `cs` fields are consistent.
func ValidateControllerStart(cs network.ControllerStart) error {
return validateTimedField(cs.ControllerTime, cs.Controller, "controller")
}

func validateTimedField(time metav1.MicroTime, fieldVal, fieldName string) error {
if (time == metav1.MicroTime{} && fieldVal != "") {
return fmt.Errorf("both %s and time must be set, but only %s is set", fieldName, fieldName)
}
if (time != metav1.MicroTime{} && fieldVal == "") {
return fmt.Errorf("both %s and time must be set, but only time is set", fieldName)
}
return nil
}
46 changes: 41 additions & 5 deletions staging/kos/pkg/apis/network/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ type ExtendedObjectMeta struct {
// +listMapKey=section
// +optional
Writes WriteSet

// LastClientWrite identifies the latest client write among those needed to
// implement the API object. Unlike `Writes`, it might describe a write on
// an API object other than the owning API object.
// +optional
LastClientWrite ClientWrite
matte21 marked this conversation as resolved.
Show resolved Hide resolved

// LastControllerStart identifies the relevant controller that started last.
// Relevant controllers are those directly or indirectly responsible for
// implementing the API object.
// +optional
LastControllerStart ControllerStart
}

// WriteSet represents a map from section to time
Expand Down Expand Up @@ -161,6 +173,35 @@ func Now() metav1.MicroTime {
return metav1.NowMicro()
}

// ClientWrite models a write by a client. A "client" is any entity that is not
// part of the KOS control plane.
type ClientWrite struct {
// Name identifies the client write.
Name string

// The time at which the client write happened.
Time metav1.MicroTime
}

// ControllerStart carries information on the start of a KOS controller.
type ControllerStart struct {
// Controller is the name of the controller which started.
Controller string

// ControllerTime is the time at which the controller started, as recorded
// by the controller itself.
ControllerTime metav1.MicroTime
}

const (
SubnetClientWrite = "subnet"
NAClientWrite = "na"

SubnetValidator = "subnet_validator"
IPAMController = "ipam_controller"
LocalConnectionAgent = "local_connection_agent"
)

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

// NetworkAttachmentList is a list of NetworkAttachment objects.
Expand Down Expand Up @@ -221,11 +262,6 @@ type NetworkAttachmentStatus struct {
// +optional
Errors NetworkAttachmentErrors

// SubnetCreationTime is the API server write time of the SubnetSectionSpec
// of the subnet identified by NetworkAttachmentSpec.Subnet.
// +optional
SubnetCreationTime metav1.MicroTime

// AddressContention indicates whether the address assignment was
// delayed due to not enough addresses being available at first.
AddressContention bool
Expand Down
68 changes: 52 additions & 16 deletions staging/kos/pkg/apis/network/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ type ExtendedObjectMeta struct {
// +listMapKey=section
// +optional
Writes WriteSet `json:"writes" protobuf:"bytes,1,name=writes"`

// LastClientWrite identifies the latest client write among those needed to
// implement the API object. Unlike `Writes`, it might describe a write on
// an API object other than the owning API object.
// +optional
LastClientWrite ClientWrite `json:"lastClientWrite,omitempty" protobuf:"bytes,2,opt,name=lastClientWrite"`

// LastControllerStart identifies the relevant controller that started last.
// Relevant controllers are those directly or indirectly responsible for
// implementing the API object.
// +optional
LastControllerStart ControllerStart `json:"lastControllerStart,omitempty" protobuf:"bytes,3,opt,name=lastControllerStart"`
}

// WriteSet represents a map from section to time
Expand Down Expand Up @@ -161,6 +173,35 @@ func Now() metav1.MicroTime {
return metav1.NowMicro()
}

// ClientWrite models a write by a client. A "client" is any entity that is not
// part of the KOS control plane.
type ClientWrite struct {
// Name identifies the client write.
Name string `json:"name" protobuf:"bytes,1,name=name"`

// The time at which the client write happened.
Time metav1.MicroTime `json:"time" protobuf:"bytes,2,name=time"`
}

// ControllerStart carries information on the start of a KOS controller.
type ControllerStart struct {
// Controller is the name of the controller which started.
Controller string `json:"controller" protobuf:"bytes,1,name=controller"`

// ControllerTime is the time at which the controller started, as recorded
// by the controller itself.
ControllerTime metav1.MicroTime `json:"controllerTime" protobuf:"bytes,2,name=controllerTime"`
}

const (
SubnetClientWrite = "subnet"
NAClientWrite = "na"

SubnetValidator = "subnet_validator"
IPAMController = "ipam_controller"
LocalConnectionAgent = "local_connection_agent"
)

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

// NetworkAttachmentList is a list of NetworkAttachment objects.
Expand Down Expand Up @@ -221,44 +262,39 @@ type NetworkAttachmentStatus struct {
// +optional
Errors NetworkAttachmentErrors `json:"errors,omitempty" protobuf:"bytes,1,opt,name=errors"`

// SubnetCreationTime is the API server write time of the SubnetSectionSpec
// of the subnet identified by NetworkAttachmentSpec.Subnet.
// +optional
SubnetCreationTime metav1.MicroTime `json:"subnetCreationTime,omitempty" protobuf:"bytes,2,opt,name=subnetCreationTime"`

// AddressContention indicates whether the address assignment was
// delayed due to not enough addresses being available at first.
AddressContention bool `json:"addressContention,omitempty" protobuf:"bytes,3,opt,name=addressContention"`
AddressContention bool `json:"addressContention,omitempty" protobuf:"bytes,2,opt,name=addressContention"`

// LockUID is the UID of the IPLock object holding this attachment's
// IP address, or the empty string when there is no address.
// This field is a private detail of the implementation, not really
// part of the public API.
// +optional
LockUID string `json:"lockUID,omitempty" protobuf:"bytes,4,opt,name=lockUID"`
LockUID string `json:"lockUID,omitempty" protobuf:"bytes,3,opt,name=lockUID"`

// AddressVNI is the VNI associated with this attachment's
// IP address assignment, or the empty string when there is no address.
// +optional
AddressVNI uint32 `json:"addressVNI,omitempty" protobuf:"bytes,5,opt,name=addressVNI"`
AddressVNI uint32 `json:"addressVNI,omitempty" protobuf:"bytes,4,opt,name=addressVNI"`

// IPv4 is non-empty when an address has been assigned.
// +optional
IPv4 string `json:"ipv4,omitempty" protobuf:"bytes,6,opt,name=ipv4"`
IPv4 string `json:"ipv4,omitempty" protobuf:"bytes,5,opt,name=ipv4"`

// MACAddress is non-empty while there is a corresponding Linux
// network interface on the host.
// +optional
MACAddress string `json:"macAddress,omitempty" protobuf:"bytes,7,opt,name=macAddress"`
MACAddress string `json:"macAddress,omitempty" protobuf:"bytes,6,opt,name=macAddress"`

// IfcName is the name of the network interface that implements this
// attachment on its node, or the empty string to indicate no
// implementation.
// +optional
IfcName string `json:"ifcName,omitempty" protobuf:"bytes,8,opt,name=ifcname"`
IfcName string `json:"ifcName,omitempty" protobuf:"bytes,7,opt,name=ifcname"`
// HostIP is the IP address of the node the attachment is bound to.
// +optional
HostIP string `json:"hostIP,omitempty" protobuf:"bytes,9,opt,name=hostIP"`
HostIP string `json:"hostIP,omitempty" protobuf:"bytes,8,opt,name=hostIP"`

// PostCreateExecReport, if non-nil, reports on the run of the
// PostCreateExec that was launched when the Linux network
Expand All @@ -271,7 +307,7 @@ type NetworkAttachmentStatus struct {
// PostCreateExec of the attachment for whom the Linux network
// interface was first created.
// +optional
PostCreateExecReport *ExecReport `json:"postCreateExecReport,omitempty" protobuf:"bytes,10,opt,name=postCreateExecReport"`
PostCreateExecReport *ExecReport `json:"postCreateExecReport,omitempty" protobuf:"bytes,9,opt,name=postCreateExecReport"`
}

type NetworkAttachmentErrors struct {
Expand Down Expand Up @@ -409,12 +445,12 @@ type Subnet struct {

// `extendedMetadata` adds non-standard object metadata
// +optional
ExtendedObjectMeta `json:"extendedMetadata,omitempty" protobuf:"bytes,4,opt,name=extendedMetadata"`
ExtendedObjectMeta `json:"extendedMetadata,omitempty" protobuf:"bytes,2,opt,name=extendedMetadata"`

Spec SubnetSpec `json:"spec" protobuf:"bytes,2,name=spec"`
Spec SubnetSpec `json:"spec" protobuf:"bytes,3,name=spec"`

// +optional
Status SubnetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
Status SubnetStatus `json:"status,omitempty" protobuf:"bytes,4,opt,name=status"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
78 changes: 76 additions & 2 deletions staging/kos/pkg/apis/network/v1alpha1/zz_generated.conversion.go

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

Loading