Add provider method to pass node configuration (#680)
This eliminates all the one-off calls to for specific things like `Capacity` and other things. Instead we configure defaults in the CLI and then pass the full node object to the provider to change as needed. This makes sure the provider can change whatever they need to without having to add tons of methods to the provider interface.
This commit is contained in:
@@ -25,6 +25,8 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const osLabel = "beta.kubernetes.io/os"
|
||||||
|
|
||||||
// NodeFromProvider builds a kubernetes node object from a provider
|
// NodeFromProvider builds a kubernetes node object from a provider
|
||||||
// This is a temporary solution until node stuff actually split off from the provider interface itself.
|
// This is a temporary solution until node stuff actually split off from the provider interface itself.
|
||||||
func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p providers.Provider, version string) *v1.Node {
|
func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p providers.Provider, version string) *v1.Node {
|
||||||
@@ -40,9 +42,7 @@ func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p provi
|
|||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"type": "virtual-kubelet",
|
"type": "virtual-kubelet",
|
||||||
"kubernetes.io/role": "agent",
|
"kubernetes.io/role": "agent",
|
||||||
"beta.kubernetes.io/os": strings.ToLower(p.OperatingSystem()),
|
|
||||||
"kubernetes.io/hostname": name,
|
"kubernetes.io/hostname": name,
|
||||||
"alpha.service-controller.kubernetes.io/exclude-balancer": "true",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Spec: v1.NodeSpec{
|
Spec: v1.NodeSpec{
|
||||||
@@ -50,17 +50,16 @@ func NodeFromProvider(ctx context.Context, name string, taint *v1.Taint, p provi
|
|||||||
},
|
},
|
||||||
Status: v1.NodeStatus{
|
Status: v1.NodeStatus{
|
||||||
NodeInfo: v1.NodeSystemInfo{
|
NodeInfo: v1.NodeSystemInfo{
|
||||||
OperatingSystem: p.OperatingSystem(),
|
Architecture: "amd64",
|
||||||
Architecture: "amd64",
|
KubeletVersion: version,
|
||||||
KubeletVersion: version,
|
|
||||||
},
|
},
|
||||||
Capacity: p.Capacity(ctx),
|
|
||||||
Allocatable: p.Capacity(ctx),
|
|
||||||
Conditions: p.NodeConditions(ctx),
|
|
||||||
Addresses: p.NodeAddresses(ctx),
|
|
||||||
DaemonEndpoints: *p.NodeDaemonEndpoints(ctx),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.ConfigureNode(ctx, node)
|
||||||
|
if _, ok := node.ObjectMeta.Labels[osLabel]; !ok {
|
||||||
|
node.ObjectMeta.Labels[osLabel] = strings.ToLower(node.Status.NodeInfo.OperatingSystem)
|
||||||
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -312,12 +312,6 @@ func (p *MockV0Provider) GetContainerLogs(ctx context.Context, namespace, podNam
|
|||||||
return ioutil.NopCloser(strings.NewReader("")), nil
|
return ioutil.NopCloser(strings.NewReader("")), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get full pod name as defined in the provider context
|
|
||||||
// TODO: Implementation
|
|
||||||
func (p *MockV0Provider) GetPodFullName(namespace string, pod string) string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunInContainer executes a command in a container in the pod, copying data
|
// RunInContainer executes a command in a container in the pod, copying data
|
||||||
// between in/out/err and the container's stdin/stdout/stderr.
|
// between in/out/err and the container's stdin/stdout/stderr.
|
||||||
func (p *MockV0Provider) RunInContainer(ctx context.Context, namespace, name, container string, cmd []string, attach api.AttachIO) error {
|
func (p *MockV0Provider) RunInContainer(ctx context.Context, namespace, name, container string, cmd []string, attach api.AttachIO) error {
|
||||||
@@ -360,11 +354,26 @@ func (p *MockV0Provider) GetPods(ctx context.Context) ([]*v1.Pod, error) {
|
|||||||
return pods, nil
|
return pods, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capacity returns a resource list containing the capacity limits.
|
func (p *MockV0Provider) ConfigureNode(ctx context.Context, n *v1.Node) {
|
||||||
func (p *MockV0Provider) Capacity(ctx context.Context) v1.ResourceList {
|
ctx, span := trace.StartSpan(ctx, "mock.ConfigureNode")
|
||||||
ctx, span := trace.StartSpan(ctx, "Capacity")
|
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
n.Status.Capacity = p.capacity()
|
||||||
|
n.Status.Allocatable = p.capacity()
|
||||||
|
n.Status.Conditions = p.nodeConditions()
|
||||||
|
n.Status.Addresses = p.nodeAddresses()
|
||||||
|
n.Status.DaemonEndpoints = p.nodeDaemonEndpoints()
|
||||||
|
os := p.operatingSystem
|
||||||
|
if os == "" {
|
||||||
|
os = "Linux"
|
||||||
|
}
|
||||||
|
n.Status.NodeInfo.OperatingSystem = os
|
||||||
|
n.Status.NodeInfo.Architecture = "amd64"
|
||||||
|
n.ObjectMeta.Labels["alpha.service-controller.kubernetes.io/exclude-balancer"] = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capacity returns a resource list containing the capacity limits.
|
||||||
|
func (p *MockV0Provider) capacity() v1.ResourceList {
|
||||||
return v1.ResourceList{
|
return v1.ResourceList{
|
||||||
"cpu": resource.MustParse(p.config.CPU),
|
"cpu": resource.MustParse(p.config.CPU),
|
||||||
"memory": resource.MustParse(p.config.Memory),
|
"memory": resource.MustParse(p.config.Memory),
|
||||||
@@ -374,10 +383,7 @@ func (p *MockV0Provider) Capacity(ctx context.Context) v1.ResourceList {
|
|||||||
|
|
||||||
// NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), for updates to the node status
|
// NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), for updates to the node status
|
||||||
// within Kubernetes.
|
// within Kubernetes.
|
||||||
func (p *MockV0Provider) NodeConditions(ctx context.Context) []v1.NodeCondition {
|
func (p *MockV0Provider) nodeConditions() []v1.NodeCondition {
|
||||||
ctx, span := trace.StartSpan(ctx, "NodeConditions")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
return []v1.NodeCondition{
|
return []v1.NodeCondition{
|
||||||
{
|
{
|
||||||
@@ -426,10 +432,7 @@ func (p *MockV0Provider) NodeConditions(ctx context.Context) []v1.NodeCondition
|
|||||||
|
|
||||||
// NodeAddresses returns a list of addresses for the node status
|
// NodeAddresses returns a list of addresses for the node status
|
||||||
// within Kubernetes.
|
// within Kubernetes.
|
||||||
func (p *MockV0Provider) NodeAddresses(ctx context.Context) []v1.NodeAddress {
|
func (p *MockV0Provider) nodeAddresses() []v1.NodeAddress {
|
||||||
ctx, span := trace.StartSpan(ctx, "NodeAddresses")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return []v1.NodeAddress{
|
return []v1.NodeAddress{
|
||||||
{
|
{
|
||||||
Type: "InternalIP",
|
Type: "InternalIP",
|
||||||
@@ -440,25 +443,14 @@ func (p *MockV0Provider) NodeAddresses(ctx context.Context) []v1.NodeAddress {
|
|||||||
|
|
||||||
// NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status
|
// NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status
|
||||||
// within Kubernetes.
|
// within Kubernetes.
|
||||||
func (p *MockV0Provider) NodeDaemonEndpoints(ctx context.Context) *v1.NodeDaemonEndpoints {
|
func (p *MockV0Provider) nodeDaemonEndpoints() v1.NodeDaemonEndpoints {
|
||||||
ctx, span := trace.StartSpan(ctx, "NodeDaemonEndpoints")
|
return v1.NodeDaemonEndpoints{
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return &v1.NodeDaemonEndpoints{
|
|
||||||
KubeletEndpoint: v1.DaemonEndpoint{
|
KubeletEndpoint: v1.DaemonEndpoint{
|
||||||
Port: p.daemonEndpointPort,
|
Port: p.daemonEndpointPort,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OperatingSystem returns the operating system for this provider.
|
|
||||||
// This is a noop to default to Linux for now.
|
|
||||||
|
|
||||||
func (p *MockV0Provider) OperatingSystem() string {
|
|
||||||
// This is harcoded due to: https://github.com/virtual-kubelet/virtual-kubelet/issues/632
|
|
||||||
return "Linux"
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStatsSummary returns dummy stats for all pods known by this provider.
|
// GetStatsSummary returns dummy stats for all pods known by this provider.
|
||||||
func (p *MockV0Provider) GetStatsSummary(ctx context.Context) (*stats.Summary, error) {
|
func (p *MockV0Provider) GetStatsSummary(ctx context.Context) (*stats.Summary, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "GetStatsSummary")
|
ctx, span := trace.StartSpan(ctx, "GetStatsSummary")
|
||||||
|
|||||||
@@ -25,23 +25,9 @@ type Provider interface {
|
|||||||
// between in/out/err and the container's stdin/stdout/stderr.
|
// between in/out/err and the container's stdin/stdout/stderr.
|
||||||
RunInContainer(ctx context.Context, namespace, podName, containerName string, cmd []string, attach api.AttachIO) error
|
RunInContainer(ctx context.Context, namespace, podName, containerName string, cmd []string, attach api.AttachIO) error
|
||||||
|
|
||||||
// Capacity returns a resource list with the capacity constraints of the provider.
|
// ConfigureNode enables a provider to configure the node object that
|
||||||
Capacity(context.Context) v1.ResourceList
|
// will be used for Kubernetes.
|
||||||
|
ConfigureNode(context.Context, *v1.Node)
|
||||||
// NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), which is
|
|
||||||
// polled periodically to update the node status within Kubernetes.
|
|
||||||
NodeConditions(context.Context) []v1.NodeCondition
|
|
||||||
|
|
||||||
// NodeAddresses returns a list of addresses for the node status
|
|
||||||
// within Kubernetes.
|
|
||||||
NodeAddresses(context.Context) []v1.NodeAddress
|
|
||||||
|
|
||||||
// NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status
|
|
||||||
// within Kubernetes.
|
|
||||||
NodeDaemonEndpoints(context.Context) *v1.NodeDaemonEndpoints
|
|
||||||
|
|
||||||
// OperatingSystem returns the operating system the provider is for.
|
|
||||||
OperatingSystem() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodMetricsProvider is an optional interface that providers can implement to expose pod stats
|
// PodMetricsProvider is an optional interface that providers can implement to expose pod stats
|
||||||
|
|||||||
Reference in New Issue
Block a user