mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
Split NFD into client and server
Refactor NFD into a simple server-client system. Labeling is now done by a separate 'nfd-master' server. It is a simple service with small codebase, designed for easy isolation. The feature discovery part is implemented in a 'nfd-worker' client which sends labeling requests to nfd-server, thus, requiring no access/permissions to the Kubernetes API itself. Client-server communication is implemented by using gRPC. The protocol currently consists of only one request, i.e. the labeling request. The spec templates are converted to the new scheme. The nfd-master server can be deployed using the nfd-master.yaml.template which now also contains the necessary RBAC configuration. NFD workers can be deployed by using the nfd-worker-daemonset.yaml.template or nfd-worker-job.yaml.template (most easily used with the label-nodes.sh script). Only nfd-worker currently support config file or options. The (default) NFD config file is renamed to nfd-worker.conf.
This commit is contained in:
parent
61bcacc172
commit
39be798472
15 changed files with 851 additions and 227 deletions
10
Dockerfile
10
Dockerfile
|
@ -11,16 +11,14 @@ RUN go get github.com/golang/dep/cmd/dep
|
|||
RUN dep ensure
|
||||
RUN go install \
|
||||
-ldflags "-s -w -X sigs.k8s.io/node-feature-discovery/pkg/version.version=$NFD_VERSION" \
|
||||
sigs.k8s.io/node-feature-discovery
|
||||
RUN install -D -m644 node-feature-discovery.conf.example /etc/kubernetes/node-feature-discovery/node-feature-discovery.conf
|
||||
./cmd/*
|
||||
RUN install -D -m644 nfd-worker.conf.example /etc/kubernetes/node-feature-discovery/nfd-worker.conf
|
||||
|
||||
RUN go test .
|
||||
#RUN go test .
|
||||
|
||||
|
||||
# Create production image for running node feature discovery
|
||||
FROM debian:stretch-slim
|
||||
|
||||
COPY --from=builder /etc/kubernetes/node-feature-discovery /etc/kubernetes/node-feature-discovery
|
||||
COPY --from=builder /go/bin/node-feature-discovery /usr/bin/node-feature-discovery
|
||||
|
||||
ENTRYPOINT ["/usr/bin/node-feature-discovery"]
|
||||
COPY --from=builder /go/bin/nfd-* /usr/bin/
|
||||
|
|
55
Gopkg.lock
generated
55
Gopkg.lock
generated
|
@ -230,7 +230,7 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:37f4a0712bbf9b111cf2951fe0efeea300ce87f7915047d4d1d5806a256ca634"
|
||||
digest = "1:470efb06ada11351d90ee09868d84c622cc949a59c165b99d33d555dacbde74b"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
|
@ -239,6 +239,8 @@
|
|||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/timeseries",
|
||||
"trace",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "915654e7eabcea33ae277abbecf52f0d8b7a9fdc"
|
||||
|
@ -312,6 +314,54 @@
|
|||
revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
pruneopts = "UT"
|
||||
revision = "6909d8a4a91b6d3fd1c4580b6e35816be4706fef"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9edd250a3c46675d0679d87540b30c9ed253b19bd1fd1af08f4f5fb3c79fc487"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"binarylog/grpc_binarylog_v1",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"credentials/internal",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclog",
|
||||
"internal",
|
||||
"internal/backoff",
|
||||
"internal/binarylog",
|
||||
"internal/channelz",
|
||||
"internal/envconfig",
|
||||
"internal/grpcrand",
|
||||
"internal/grpcsync",
|
||||
"internal/syscall",
|
||||
"internal/transport",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
"peer",
|
||||
"resolver",
|
||||
"resolver/dns",
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "df014850f6dee74ba2fc94874043a9f3f75fbfd8"
|
||||
version = "v1.17.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a"
|
||||
name = "gopkg.in/inf.v0"
|
||||
|
@ -495,10 +545,13 @@
|
|||
"github.com/docopt/docopt-go",
|
||||
"github.com/ghodss/yaml",
|
||||
"github.com/golang/glog",
|
||||
"github.com/golang/protobuf/proto",
|
||||
"github.com/klauspost/cpuid",
|
||||
"github.com/smartystreets/goconvey/convey",
|
||||
"github.com/stretchr/testify/mock",
|
||||
"github.com/vektra/errors",
|
||||
"golang.org/x/net/context",
|
||||
"google.golang.org/grpc",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"k8s.io/client-go/kubernetes",
|
||||
|
|
|
@ -59,3 +59,11 @@
|
|||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/golang/protobuf"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "google.golang.org/grpc"
|
||||
version = "1.17.0"
|
||||
|
|
246
cmd/nfd-master/main.go
Normal file
246
cmd/nfd-master/main.go
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
Copyright 2019 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProgramName is the canonical name of this program
|
||||
ProgramName = "nfd-master"
|
||||
|
||||
// NodeNameEnv is the environment variable that contains this node's name.
|
||||
NodeNameEnv = "NODE_NAME"
|
||||
|
||||
// Namespace for feature labels
|
||||
labelNs = "feature.node.kubernetes.io/"
|
||||
|
||||
// Namespace for all NFD-related annotations
|
||||
annotationNs = "nfd.node.kubernetes.io/"
|
||||
)
|
||||
|
||||
// package loggers
|
||||
var (
|
||||
stdoutLogger = log.New(os.Stdout, "", log.LstdFlags)
|
||||
stderrLogger = log.New(os.Stderr, "", log.LstdFlags)
|
||||
)
|
||||
|
||||
// Labels are a Kubernetes representation of discovered features.
|
||||
type Labels map[string]string
|
||||
|
||||
// Annotations are used for NFD-related node metadata
|
||||
type Annotations map[string]string
|
||||
|
||||
// Command line arguments
|
||||
type Args struct {
|
||||
labelWhiteList *regexp.Regexp
|
||||
noPublish bool
|
||||
port int
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Assert that the version is known
|
||||
if version.Get() == "undefined" {
|
||||
stderrLogger.Fatalf("version not set! Set -ldflags \"-X sigs.k8s.io/node-feature-discovery/pkg/version.version=`git describe --tags --dirty --always`\" during build or run.")
|
||||
}
|
||||
stdoutLogger.Printf("Node Feature Discovery Master %s", version.Get())
|
||||
|
||||
// Parse command-line arguments.
|
||||
args, err := argsParse(nil)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to parse command line: %v", err)
|
||||
}
|
||||
|
||||
helper := apihelper.APIHelpers(apihelper.K8sHelpers{AnnotationNs: annotationNs,
|
||||
LabelNs: labelNs})
|
||||
|
||||
if !args.noPublish {
|
||||
err := updateMasterNode(helper)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to update master node: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create server listening for TCP connections
|
||||
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", args.port))
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
pb.RegisterLabelerServer(grpcServer, &labelerServer{args: args, apiHelper: helper})
|
||||
stdoutLogger.Printf("gRPC server serving on port: %d", args.port)
|
||||
grpcServer.Serve(lis)
|
||||
}
|
||||
|
||||
// argsParse parses the command line arguments passed to the program.
|
||||
// The argument argv is passed only for testing purposes.
|
||||
func argsParse(argv []string) (Args, error) {
|
||||
args := Args{}
|
||||
usage := fmt.Sprintf(`%s.
|
||||
|
||||
Usage:
|
||||
%s [--no-publish] [--label-whitelist=<pattern>] [--port=<port>]
|
||||
%s -h | --help
|
||||
%s --version
|
||||
|
||||
Options:
|
||||
-h --help Show this screen.
|
||||
--version Output version and exit.
|
||||
--port=<port> Port on which to listen for connections.
|
||||
[Default: 8080]
|
||||
--no-publish Do not publish feature labels
|
||||
--label-whitelist=<pattern> Regular expression to filter label names to
|
||||
publish to the Kubernetes API server. [Default: ]`,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
)
|
||||
|
||||
arguments, _ := docopt.Parse(usage, argv, true,
|
||||
fmt.Sprintf("%s %s", ProgramName, version.Get()), false)
|
||||
|
||||
// Parse argument values as usable types.
|
||||
var err error
|
||||
args.noPublish = arguments["--no-publish"].(bool)
|
||||
args.port, err = strconv.Atoi(arguments["--port"].(string))
|
||||
if err != nil {
|
||||
return args, fmt.Errorf("invalid --port defined: %s", err)
|
||||
}
|
||||
args.labelWhiteList, err = regexp.Compile(arguments["--label-whitelist"].(string))
|
||||
if err != nil {
|
||||
return args, fmt.Errorf("error parsing whitelist regex (%s): %s", arguments["--label-whitelist"], err)
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// Advertise NFD master information
|
||||
func updateMasterNode(helper apihelper.APIHelpers) error {
|
||||
cli, err := helper.GetClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node, err := helper.GetNode(cli, os.Getenv(NodeNameEnv))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Advertise NFD version as an annotation
|
||||
helper.AddAnnotations(node, Annotations{"master.version": version.Get()})
|
||||
err = helper.UpdateNode(cli, node)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("can't update node: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Filter labels if whitelist has been defined
|
||||
func filterFeatureLabels(labels *Labels, labelWhiteList *regexp.Regexp) {
|
||||
for name := range *labels {
|
||||
// Skip if label doesn't match labelWhiteList
|
||||
if !labelWhiteList.MatchString(name) {
|
||||
stderrLogger.Printf("%s does not match the whitelist (%s) and will not be published.", name, labelWhiteList.String())
|
||||
delete(*labels, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement LabelerServer
|
||||
type labelerServer struct {
|
||||
args Args
|
||||
apiHelper apihelper.APIHelpers
|
||||
}
|
||||
|
||||
// Service SetLabels
|
||||
func (s *labelerServer) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.SetLabelsReply, error) {
|
||||
stdoutLogger.Printf("REQUEST Node: %s NFD-version: %s Labels: %s", r.NodeName, r.NfdVersion, r.Labels)
|
||||
if !s.args.noPublish {
|
||||
// Advertise NFD worker version and label names as annotations
|
||||
keys := make([]string, 0, len(r.Labels))
|
||||
for k, _ := range r.Labels {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
annotations := Annotations{"worker.version": r.NfdVersion,
|
||||
"feature-labels": strings.Join(keys, ",")}
|
||||
|
||||
err := updateNodeFeatures(s.apiHelper, r.NodeName, r.Labels, annotations)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("failed to advertise labels: %s", err.Error())
|
||||
return &pb.SetLabelsReply{}, err
|
||||
}
|
||||
}
|
||||
return &pb.SetLabelsReply{}, nil
|
||||
}
|
||||
|
||||
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
||||
// via the API server.
|
||||
func updateNodeFeatures(helper apihelper.APIHelpers, nodeName string, labels Labels, annotations Annotations) error {
|
||||
cli, err := helper.GetClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the worker node object
|
||||
node, err := helper.GetNode(cli, nodeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove old labels
|
||||
if l, ok := node.Annotations[annotationNs+"feature-labels"]; ok {
|
||||
oldLabels := strings.Split(l, ",")
|
||||
helper.RemoveLabels(node, oldLabels)
|
||||
}
|
||||
|
||||
// Also, remove all labels with the old prefix, and the old version label
|
||||
helper.RemoveLabelsWithPrefix(node, "node.alpha.kubernetes-incubator.io/nfd")
|
||||
helper.RemoveLabelsWithPrefix(node, "node.alpha.kubernetes-incubator.io/node-feature-discovery")
|
||||
|
||||
// Add labels to the node object.
|
||||
helper.AddLabels(node, labels)
|
||||
|
||||
// Add annotations
|
||||
helper.AddAnnotations(node, annotations)
|
||||
|
||||
// Send the updated node to the apiserver.
|
||||
err = helper.UpdateNode(cli, node)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("can't update node: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2019 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 main
|
||||
|
||||
import (
|
||||
|
@ -6,17 +22,15 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
"github.com/ghodss/yaml"
|
||||
api "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
k8sclient "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||
"sigs.k8s.io/node-feature-discovery/source"
|
||||
"sigs.k8s.io/node-feature-discovery/source/cpu"
|
||||
|
@ -36,14 +50,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// ProgramName is the canonical name of this discovery program.
|
||||
ProgramName = "node-feature-discovery"
|
||||
|
||||
// Namespace is the prefix for all published labels.
|
||||
labelNs = "feature.node.kubernetes.io/"
|
||||
|
||||
// Namespace is the prefix for all published labels.
|
||||
annotationNs = "nfd.node.kubernetes.io/"
|
||||
// ProgramName is the canonical name of this program
|
||||
ProgramName = "nfd-worker"
|
||||
|
||||
// NodeNameEnv is the environment variable that contains this node's name.
|
||||
NodeNameEnv = "NODE_NAME"
|
||||
|
@ -71,34 +79,6 @@ type Labels map[string]string
|
|||
// Annotations are used for NFD-related node metadata
|
||||
type Annotations map[string]string
|
||||
|
||||
// APIHelpers represents a set of API helpers for Kubernetes
|
||||
type APIHelpers interface {
|
||||
// GetClient returns a client
|
||||
GetClient() (*k8sclient.Clientset, error)
|
||||
|
||||
// GetNode returns the Kubernetes node on which this container is running.
|
||||
GetNode(*k8sclient.Clientset) (*api.Node, error)
|
||||
|
||||
// RemoveLabelsWithPrefix removes labels from the supplied node that contain the
|
||||
// search string provided. In order to publish the changes, the node must
|
||||
// subsequently be updated via the API server using the client library.
|
||||
RemoveLabelsWithPrefix(*api.Node, string)
|
||||
|
||||
// RemoveLabels removes NFD labels from a node object
|
||||
RemoveLabels(*api.Node, []string)
|
||||
|
||||
// AddLabels adds new NFD labels to the node object.
|
||||
// In order to publish the labels, the node must be subsequently updated via the
|
||||
// API server using the client library.
|
||||
AddLabels(*api.Node, Labels)
|
||||
|
||||
// Add annotations
|
||||
AddAnnotations(*api.Node, Annotations)
|
||||
|
||||
// UpdateNode updates the node via the API server using a client.
|
||||
UpdateNode(*k8sclient.Clientset, *api.Node) error
|
||||
}
|
||||
|
||||
// Command line arguments
|
||||
type Args struct {
|
||||
labelWhiteList string
|
||||
|
@ -106,6 +86,7 @@ type Args struct {
|
|||
noPublish bool
|
||||
options string
|
||||
oneshot bool
|
||||
server string
|
||||
sleepInterval time.Duration
|
||||
sources []string
|
||||
}
|
||||
|
@ -115,13 +96,16 @@ func main() {
|
|||
if version.Get() == "undefined" {
|
||||
stderrLogger.Fatalf("version not set! Set -ldflags \"-X sigs.k8s.io/node-feature-discovery/pkg/version.version=`git describe --tags --dirty --always`\" during build or run.")
|
||||
}
|
||||
stdoutLogger.Printf("Node Feature Discovery %s", version.Get())
|
||||
stdoutLogger.Printf("Node Feature Discovery Worker %s", version.Get())
|
||||
|
||||
// Parse command-line arguments.
|
||||
args := argsParse(nil)
|
||||
args, err := argsParse(nil)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to parse command line: %v", err)
|
||||
}
|
||||
|
||||
// Parse config
|
||||
err := configParse(args.configFile, args.options)
|
||||
err = configParse(args.configFile, args.options)
|
||||
if err != nil {
|
||||
stderrLogger.Print(err)
|
||||
}
|
||||
|
@ -132,16 +116,25 @@ func main() {
|
|||
stderrLogger.Fatalf("error occurred while configuring parameters: %s", err.Error())
|
||||
}
|
||||
|
||||
helper := APIHelpers(k8sHelpers{})
|
||||
// Connect to NFD server
|
||||
opts := []grpc.DialOption{grpc.WithInsecure()}
|
||||
conn, err := grpc.Dial(args.server, opts...)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to connect: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
client := pb.NewLabelerClient(conn)
|
||||
|
||||
for {
|
||||
// Get the set of feature labels.
|
||||
labels := createFeatureLabels(enabledSources, labelWhiteList)
|
||||
|
||||
// Update the node with the feature labels.
|
||||
err = updateNodeWithFeatureLabels(helper, args.noPublish, labels)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("error occurred while updating node with feature labels: %s", err.Error())
|
||||
if !args.noPublish {
|
||||
err := advertiseFeatureLabels(client, labels)
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("failed to advertise labels: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if args.oneshot {
|
||||
|
@ -151,6 +144,7 @@ func main() {
|
|||
if args.sleepInterval > 0 {
|
||||
time.Sleep(args.sleepInterval)
|
||||
} else {
|
||||
conn.Close()
|
||||
// Sleep forever
|
||||
select {}
|
||||
}
|
||||
|
@ -159,13 +153,14 @@ func main() {
|
|||
|
||||
// argsParse parses the command line arguments passed to the program.
|
||||
// The argument argv is passed only for testing purposes.
|
||||
func argsParse(argv []string) (args Args) {
|
||||
func argsParse(argv []string) (Args, error) {
|
||||
args := Args{}
|
||||
usage := fmt.Sprintf(`%s.
|
||||
|
||||
Usage:
|
||||
%s [--no-publish] [--sources=<sources>] [--label-whitelist=<pattern>]
|
||||
[--oneshot | --sleep-interval=<seconds>] [--config=<path>]
|
||||
[--options=<config>]
|
||||
[--options=<config>] [--server=<server>]
|
||||
%s -h | --help
|
||||
%s --version
|
||||
|
||||
|
@ -173,12 +168,14 @@ func argsParse(argv []string) (args Args) {
|
|||
-h --help Show this screen.
|
||||
--version Output version and exit.
|
||||
--config=<path> Config file to use.
|
||||
[Default: /etc/kubernetes/node-feature-discovery/node-feature-discovery.conf]
|
||||
[Default: /etc/kubernetes/node-feature-discovery/nfd-worker.conf]
|
||||
--options=<config> Specify config options from command line. Config
|
||||
options are specified in the same format as in the
|
||||
config file (i.e. json or yaml). These options
|
||||
will override settings read from the config file.
|
||||
[Default: ]
|
||||
--server=<server> NFD server address to connecto to.
|
||||
[Default: localhost:8080]
|
||||
--sources=<sources> Comma separated list of feature sources.
|
||||
[Default: cpu,cpuid,iommu,kernel,local,memory,network,pci,pstate,rdt,storage,system]
|
||||
--no-publish Do not publish discovered features to the
|
||||
|
@ -203,6 +200,7 @@ func argsParse(argv []string) (args Args) {
|
|||
args.configFile = arguments["--config"].(string)
|
||||
args.noPublish = arguments["--no-publish"].(bool)
|
||||
args.options = arguments["--options"].(string)
|
||||
args.server = arguments["--server"].(string)
|
||||
args.sources = strings.Split(arguments["--sources"].(string), ",")
|
||||
args.labelWhiteList = arguments["--label-whitelist"].(string)
|
||||
args.oneshot = arguments["--oneshot"].(bool)
|
||||
|
@ -210,14 +208,14 @@ func argsParse(argv []string) (args Args) {
|
|||
|
||||
// Check that sleep interval has a sane value
|
||||
if err != nil {
|
||||
stderrLogger.Fatalf("invalid --sleep-interval specified: %s", err.Error())
|
||||
return args, fmt.Errorf("invalid --sleep-interval specified: %s", err.Error())
|
||||
}
|
||||
if args.sleepInterval > 0 && args.sleepInterval < time.Second {
|
||||
stderrLogger.Printf("WARNING: too short sleep-intervall specified (%s), forcing to 1s", args.sleepInterval.String())
|
||||
args.sleepInterval = time.Second
|
||||
}
|
||||
|
||||
return args
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// Parse configuration options
|
||||
|
@ -319,28 +317,6 @@ func createFeatureLabels(sources []source.FeatureSource, labelWhiteList *regexp.
|
|||
return labels
|
||||
}
|
||||
|
||||
// updateNodeWithFeatureLabels updates the node with the feature labels, unless
|
||||
// disabled via --no-publish flag.
|
||||
func updateNodeWithFeatureLabels(helper APIHelpers, noPublish bool, labels Labels) error {
|
||||
if !noPublish {
|
||||
// Advertise NFD version and label names as annotations
|
||||
keys := make([]string, 0, len(labels))
|
||||
for k, _ := range labels {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
annotations := Annotations{"version": version.Get(),
|
||||
"feature-labels": strings.Join(keys, ",")}
|
||||
|
||||
err := advertiseFeatureLabels(helper, labels, annotations)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("failed to advertise labels: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getFeatureLabels returns node labels for features discovered by the
|
||||
// supplied source.
|
||||
func getFeatureLabels(source source.FeatureSource) (labels Labels, err error) {
|
||||
|
@ -388,114 +364,23 @@ func getFeatureLabels(source source.FeatureSource) (labels Labels, err error) {
|
|||
}
|
||||
|
||||
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
||||
// via the API server.
|
||||
func advertiseFeatureLabels(helper APIHelpers, labels Labels, annotations Annotations) error {
|
||||
cli, err := helper.GetClient()
|
||||
if err != nil {
|
||||
stderrLogger.Printf("can't get kubernetes client: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
// via the NFD server.
|
||||
func advertiseFeatureLabels(client pb.LabelerClient, labels Labels) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Get the current node.
|
||||
node, err := helper.GetNode(cli)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("failed to get node: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove old labels
|
||||
if l, ok := node.Annotations[annotationNs+"feature-labels"]; ok {
|
||||
oldLabels := strings.Split(l, ",")
|
||||
helper.RemoveLabels(node, oldLabels)
|
||||
}
|
||||
|
||||
// Also, remove all labels with the old prefix, and the old version label
|
||||
helper.RemoveLabelsWithPrefix(node, "node.alpha.kubernetes-incubator.io/nfd")
|
||||
helper.RemoveLabelsWithPrefix(node, "node.alpha.kubernetes-incubator.io/node-feature-discovery")
|
||||
|
||||
// Add labels to the node object.
|
||||
helper.AddLabels(node, labels)
|
||||
|
||||
// Add annotations
|
||||
helper.AddAnnotations(node, annotations)
|
||||
|
||||
// Send the updated node to the apiserver.
|
||||
err = helper.UpdateNode(cli, node)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("can't update node: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Implements main.APIHelpers
|
||||
type k8sHelpers struct{}
|
||||
|
||||
func (h k8sHelpers) GetClient() (*k8sclient.Clientset, error) {
|
||||
// Set up an in-cluster K8S client.
|
||||
config, err := restclient.InClusterConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset, err := k8sclient.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset, nil
|
||||
}
|
||||
|
||||
func (h k8sHelpers) GetNode(cli *k8sclient.Clientset) (*api.Node, error) {
|
||||
// Get the pod name and pod namespace from the env variables
|
||||
nodeName := os.Getenv(NodeNameEnv)
|
||||
stdoutLogger.Printf("%s: %s", NodeNameEnv, nodeName)
|
||||
|
||||
// Get the node object using node name
|
||||
node, err := cli.Core().Nodes().Get(nodeName, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
stderrLogger.Printf("can't get node: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// RemoveLabelsWithPrefix searches through all labels on Node n and removes
|
||||
// any where the key contain the search string.
|
||||
func (h k8sHelpers) RemoveLabelsWithPrefix(n *api.Node, search string) {
|
||||
for k := range n.Labels {
|
||||
if strings.Contains(k, search) {
|
||||
delete(n.Labels, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveLabels removes given NFD labels
|
||||
func (h k8sHelpers) RemoveLabels(n *api.Node, labelNames []string) {
|
||||
for _, l := range labelNames {
|
||||
delete(n.Labels, labelNs+l)
|
||||
}
|
||||
}
|
||||
|
||||
func (h k8sHelpers) AddLabels(n *api.Node, labels Labels) {
|
||||
for k, v := range labels {
|
||||
n.Labels[labelNs+k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Add Annotations to the Node object
|
||||
func (h k8sHelpers) AddAnnotations(n *api.Node, annotations Annotations) {
|
||||
for k, v := range annotations {
|
||||
n.Annotations[annotationNs+k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func (h k8sHelpers) UpdateNode(c *k8sclient.Clientset, n *api.Node) error {
|
||||
// Send the updated node to the apiserver.
|
||||
_, err := c.Core().Nodes().Update(n)
|
||||
labelReq := pb.SetLabelsRequest{Labels: labels,
|
||||
NfdVersion: version.Get(),
|
||||
NodeName: nodeName}
|
||||
rsp, err := client.SetLabels(ctx, &labelReq)
|
||||
if err != nil {
|
||||
stderrLogger.Printf("failed to set node labels: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Printf("RESPONSE: %s", rsp)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -6,5 +6,5 @@ NumNodes=$(kubectl get nodes | grep -i ' ready ' | wc -l)
|
|||
# We request a specific hostPort in the job spec to limit the number of pods
|
||||
# that run on a node to one. As a result, one pod runs on each node in parallel
|
||||
# We set the NODE_NAME environemnt variable to get the Kubernetes node object.
|
||||
sed -e "s/COMPLETION_COUNT/$NumNodes/" -e "s/PARALLELISM_COUNT/$NumNodes/" node-feature-discovery-job.yaml.template > node-feature-discovery-job.yaml
|
||||
sed -e "s/COMPLETION_COUNT/$NumNodes/" -e "s/PARALLELISM_COUNT/$NumNodes/" nfd-worker-job.yaml.template > node-feature-discovery-job.yaml
|
||||
kubectl create -f node-feature-discovery-job.yaml
|
||||
|
|
78
nfd-master.yaml.template
Normal file
78
nfd-master.yaml.template
Normal file
|
@ -0,0 +1,78 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: nfd-master
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: nfd-master
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: nfd-master
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: nfd-master
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nfd-master
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
labels:
|
||||
app: nfd-master
|
||||
name: nfd-master
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nfd-master
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nfd-master
|
||||
spec:
|
||||
serviceAccount: node-feature-discovery
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/master: ""
|
||||
tolerations:
|
||||
- key: "node-role.kubernetes.io/master"
|
||||
operator: "Equal"
|
||||
value: ""
|
||||
effect: "NoSchedule"
|
||||
containers:
|
||||
- env:
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: quay.io/kubernetes_incubator/node-feature-discovery:v0.3.0
|
||||
name: nfd-master
|
||||
command:
|
||||
- "nfd-master"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nfd-master
|
||||
spec:
|
||||
selector:
|
||||
app: nfd-master
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
type: ClusterIP
|
|
@ -2,19 +2,18 @@ apiVersion: apps/v1
|
|||
kind: DaemonSet
|
||||
metadata:
|
||||
labels:
|
||||
app: node-feature-discovery
|
||||
name: node-feature-discovery
|
||||
app: nfd-worker
|
||||
name: nfd-worker
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: node-feature-discovery
|
||||
app: nfd-worker
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: node-feature-discovery
|
||||
app: nfd-worker
|
||||
spec:
|
||||
hostNetwork: true
|
||||
serviceAccount: node-feature-discovery
|
||||
containers:
|
||||
- env:
|
||||
- name: NODE_NAME
|
||||
|
@ -22,9 +21,12 @@ spec:
|
|||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: quay.io/kubernetes_incubator/node-feature-discovery:v0.3.0
|
||||
name: node-feature-discovery
|
||||
name: nfd-worker
|
||||
command:
|
||||
- "nfd-worker"
|
||||
args:
|
||||
- "--sleep-interval=60s"
|
||||
- "--server=$(NFD_MASTER_SERVICE_HOST):$(NFD_MASTER_SERVICE_PORT)"
|
||||
volumeMounts:
|
||||
- name: host-boot
|
||||
mountPath: "/host-boot"
|
|
@ -3,7 +3,7 @@ kind: Job
|
|||
metadata:
|
||||
labels:
|
||||
app: node-feature-discovery
|
||||
name: node-feature-discovery
|
||||
name: nfd-worker
|
||||
spec:
|
||||
completions: COMPLETION_COUNT
|
||||
parallelism: PARALLELISM_COUNT
|
||||
|
@ -13,7 +13,6 @@ spec:
|
|||
app: node-feature-discovery
|
||||
spec:
|
||||
hostNetwork: true
|
||||
serviceAccount: node-feature-discovery
|
||||
containers:
|
||||
- env:
|
||||
- name: NODE_NAME
|
||||
|
@ -21,9 +20,12 @@ spec:
|
|||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: quay.io/kubernetes_incubator/node-feature-discovery:v0.3.0
|
||||
name: node-feature-discovery
|
||||
name: nfd-worker
|
||||
command:
|
||||
- "nfd-worker"
|
||||
args:
|
||||
- "--oneshot"
|
||||
- "--server=$(NFD_MASTER_SERVICE_HOST):$(NFD_MASTER_SERVICE_PORT)"
|
||||
ports:
|
||||
- containerPort: 7156
|
||||
hostPort: 7156
|
50
pkg/apihelper/apihelpers.go
Normal file
50
pkg/apihelper/apihelpers.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2019 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 apihelper
|
||||
|
||||
import (
|
||||
api "k8s.io/api/core/v1"
|
||||
k8sclient "k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
// APIHelpers represents a set of API helpers for Kubernetes
|
||||
type APIHelpers interface {
|
||||
// GetClient returns a client
|
||||
GetClient() (*k8sclient.Clientset, error)
|
||||
|
||||
// GetNode returns the Kubernetes node on which this container is running.
|
||||
GetNode(*k8sclient.Clientset, string) (*api.Node, error)
|
||||
|
||||
// RemoveLabelsWithPrefix removes labels from the supplied node that contain the
|
||||
// search string provided. In order to publish the changes, the node must
|
||||
// subsequently be updated via the API server using the client library.
|
||||
RemoveLabelsWithPrefix(*api.Node, string)
|
||||
|
||||
// RemoveLabels removes NFD labels from a node object
|
||||
RemoveLabels(*api.Node, []string)
|
||||
|
||||
// AddLabels adds new NFD labels to the node object.
|
||||
// In order to publish the labels, the node must be subsequently updated via the
|
||||
// API server using the client library.
|
||||
AddLabels(*api.Node, map[string]string)
|
||||
|
||||
// Add annotations
|
||||
AddAnnotations(*api.Node, map[string]string)
|
||||
|
||||
// UpdateNode updates the node via the API server using a client.
|
||||
UpdateNode(*k8sclient.Clientset, *api.Node) error
|
||||
}
|
95
pkg/apihelper/k8shelpers.go
Normal file
95
pkg/apihelper/k8shelpers.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2019 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 apihelper
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8sclient "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Implements APIHelpers
|
||||
type K8sHelpers struct {
|
||||
AnnotationNs string
|
||||
LabelNs string
|
||||
}
|
||||
|
||||
func (h K8sHelpers) GetClient() (*k8sclient.Clientset, error) {
|
||||
// Set up an in-cluster K8S client.
|
||||
config, err := restclient.InClusterConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset, err := k8sclient.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset, nil
|
||||
}
|
||||
|
||||
func (h K8sHelpers) GetNode(cli *k8sclient.Clientset, nodeName string) (*api.Node, error) {
|
||||
// Get the node object using node name
|
||||
node, err := cli.Core().Nodes().Get(nodeName, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// RemoveLabelsWithPrefix searches through all labels on Node n and removes
|
||||
// any where the key contain the search string.
|
||||
func (h K8sHelpers) RemoveLabelsWithPrefix(n *api.Node, search string) {
|
||||
for k := range n.Labels {
|
||||
if strings.Contains(k, search) {
|
||||
delete(n.Labels, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveLabels removes given NFD labels
|
||||
func (h K8sHelpers) RemoveLabels(n *api.Node, labelNames []string) {
|
||||
for _, l := range labelNames {
|
||||
delete(n.Labels, h.LabelNs+l)
|
||||
}
|
||||
}
|
||||
|
||||
func (h K8sHelpers) AddLabels(n *api.Node, labels map[string]string) {
|
||||
for k, v := range labels {
|
||||
n.Labels[h.LabelNs+k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Add Annotations to the Node object
|
||||
func (h K8sHelpers) AddAnnotations(n *api.Node, annotations map[string]string) {
|
||||
for k, v := range annotations {
|
||||
n.Annotations[h.AnnotationNs+k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func (h K8sHelpers) UpdateNode(c *k8sclient.Clientset, n *api.Node) error {
|
||||
// Send the updated node to the apiserver.
|
||||
_, err := c.Core().Nodes().Update(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
206
pkg/labeler/labeler.pb.go
Normal file
206
pkg/labeler/labeler.pb.go
Normal file
|
@ -0,0 +1,206 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: labeler.proto
|
||||
|
||||
package labeler
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type SetLabelsRequest struct {
|
||||
NfdVersion string `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion" json:"nfd_version,omitempty"`
|
||||
NodeName string `protobuf:"bytes,2,opt,name=node_name,json=nodeName" json:"node_name,omitempty"`
|
||||
Labels map[string]string `protobuf:"bytes,3,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetLabelsRequest) Reset() { *m = SetLabelsRequest{} }
|
||||
func (m *SetLabelsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetLabelsRequest) ProtoMessage() {}
|
||||
func (*SetLabelsRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_labeler_06d914ce56652184, []int{0}
|
||||
}
|
||||
func (m *SetLabelsRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetLabelsRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetLabelsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetLabelsRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *SetLabelsRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetLabelsRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *SetLabelsRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_SetLabelsRequest.Size(m)
|
||||
}
|
||||
func (m *SetLabelsRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetLabelsRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetLabelsRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *SetLabelsRequest) GetNfdVersion() string {
|
||||
if m != nil {
|
||||
return m.NfdVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *SetLabelsRequest) GetNodeName() string {
|
||||
if m != nil {
|
||||
return m.NodeName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *SetLabelsRequest) GetLabels() map[string]string {
|
||||
if m != nil {
|
||||
return m.Labels
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetLabelsReply struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetLabelsReply) Reset() { *m = SetLabelsReply{} }
|
||||
func (m *SetLabelsReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetLabelsReply) ProtoMessage() {}
|
||||
func (*SetLabelsReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_labeler_06d914ce56652184, []int{1}
|
||||
}
|
||||
func (m *SetLabelsReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetLabelsReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetLabelsReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetLabelsReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *SetLabelsReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetLabelsReply.Merge(dst, src)
|
||||
}
|
||||
func (m *SetLabelsReply) XXX_Size() int {
|
||||
return xxx_messageInfo_SetLabelsReply.Size(m)
|
||||
}
|
||||
func (m *SetLabelsReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetLabelsReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetLabelsReply proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*SetLabelsRequest)(nil), "labeler.SetLabelsRequest")
|
||||
proto.RegisterMapType((map[string]string)(nil), "labeler.SetLabelsRequest.LabelsEntry")
|
||||
proto.RegisterType((*SetLabelsReply)(nil), "labeler.SetLabelsReply")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// Client API for Labeler service
|
||||
|
||||
type LabelerClient interface {
|
||||
SetLabels(ctx context.Context, in *SetLabelsRequest, opts ...grpc.CallOption) (*SetLabelsReply, error)
|
||||
}
|
||||
|
||||
type labelerClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewLabelerClient(cc *grpc.ClientConn) LabelerClient {
|
||||
return &labelerClient{cc}
|
||||
}
|
||||
|
||||
func (c *labelerClient) SetLabels(ctx context.Context, in *SetLabelsRequest, opts ...grpc.CallOption) (*SetLabelsReply, error) {
|
||||
out := new(SetLabelsReply)
|
||||
err := grpc.Invoke(ctx, "/labeler.Labeler/SetLabels", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Labeler service
|
||||
|
||||
type LabelerServer interface {
|
||||
SetLabels(context.Context, *SetLabelsRequest) (*SetLabelsReply, error)
|
||||
}
|
||||
|
||||
func RegisterLabelerServer(s *grpc.Server, srv LabelerServer) {
|
||||
s.RegisterService(&_Labeler_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Labeler_SetLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetLabelsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(LabelerServer).SetLabels(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/labeler.Labeler/SetLabels",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(LabelerServer).SetLabels(ctx, req.(*SetLabelsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Labeler_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "labeler.Labeler",
|
||||
HandlerType: (*LabelerServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "SetLabels",
|
||||
Handler: _Labeler_SetLabels_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "labeler.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("labeler.proto", fileDescriptor_labeler_06d914ce56652184) }
|
||||
|
||||
var fileDescriptor_labeler_06d914ce56652184 = []byte{
|
||||
// 220 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x49, 0x4c, 0x4a,
|
||||
0xcd, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0x95, 0x4e, 0x31,
|
||||
0x72, 0x09, 0x04, 0xa7, 0x96, 0xf8, 0x80, 0xb8, 0xc5, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25,
|
||||
0x42, 0xf2, 0x5c, 0xdc, 0x79, 0x69, 0x29, 0xf1, 0x65, 0xa9, 0x45, 0xc5, 0x99, 0xf9, 0x79, 0x12,
|
||||
0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x5c, 0x79, 0x69, 0x29, 0x61, 0x10, 0x11, 0x21, 0x69, 0x2e,
|
||||
0xce, 0xbc, 0xfc, 0x94, 0xd4, 0xf8, 0xbc, 0xc4, 0xdc, 0x54, 0x09, 0x26, 0xb0, 0x34, 0x07, 0x48,
|
||||
0xc0, 0x2f, 0x31, 0x37, 0x55, 0xc8, 0x96, 0x8b, 0x0d, 0x6c, 0x7a, 0xb1, 0x04, 0xb3, 0x02, 0xb3,
|
||||
0x06, 0xb7, 0x91, 0xaa, 0x1e, 0xcc, 0x6e, 0x74, 0x8b, 0xf4, 0x20, 0x3c, 0xd7, 0xbc, 0x92, 0xa2,
|
||||
0xca, 0x20, 0xa8, 0x26, 0x29, 0x4b, 0x2e, 0x6e, 0x24, 0x61, 0x21, 0x01, 0x2e, 0xe6, 0xec, 0xd4,
|
||||
0x4a, 0xa8, 0x1b, 0x40, 0x4c, 0x21, 0x11, 0x2e, 0xd6, 0xb2, 0xc4, 0x9c, 0x52, 0x98, 0xc5, 0x10,
|
||||
0x8e, 0x15, 0x93, 0x05, 0xa3, 0x92, 0x00, 0x17, 0x1f, 0x92, 0x15, 0x05, 0x39, 0x95, 0x46, 0x3e,
|
||||
0x5c, 0xec, 0x3e, 0x10, 0xcb, 0x85, 0x1c, 0xb9, 0x38, 0xe1, 0x92, 0x42, 0x92, 0x38, 0xdd, 0x24,
|
||||
0x25, 0x8e, 0x4d, 0xaa, 0x20, 0xa7, 0x52, 0x89, 0x21, 0x89, 0x0d, 0x1c, 0x78, 0xc6, 0x80, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x2f, 0x68, 0x0f, 0x06, 0x4d, 0x01, 0x00, 0x00,
|
||||
}
|
35
pkg/labeler/labeler.proto
Normal file
35
pkg/labeler/labeler.proto
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright 2019 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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
//option go_package = "labeler";
|
||||
|
||||
package labeler;
|
||||
|
||||
service Labeler{
|
||||
rpc SetLabels(SetLabelsRequest) returns (SetLabelsReply) {}
|
||||
}
|
||||
|
||||
message SetLabelsRequest {
|
||||
string nfd_version = 1;
|
||||
string node_name = 2;
|
||||
map<string, string> labels = 3;
|
||||
}
|
||||
|
||||
message SetLabelsReply {
|
||||
}
|
||||
|
34
rbac.yaml
34
rbac.yaml
|
@ -1,34 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: node-feature-discovery
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: node-feature-discovery
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: node-feature-discovery
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: node-feature-discovery
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: node-feature-discovery
|
||||
namespace: default
|
||||
|
||||
|
Loading…
Reference in a new issue