mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
nfd-master: use flag for command line parsing
This commit is contained in:
parent
a7d0439af6
commit
47033db9c1
8 changed files with 171 additions and 205 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Copyright 2019-2021 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.
|
||||
|
@ -17,14 +17,14 @@ limitations under the License.
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
master "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||
)
|
||||
|
||||
|
@ -34,17 +34,29 @@ const (
|
|||
)
|
||||
|
||||
func main() {
|
||||
flags := flag.NewFlagSet(ProgramName, flag.ExitOnError)
|
||||
|
||||
printVersion := flags.Bool("version", false, "Print version and exit.")
|
||||
|
||||
args := initFlags(flags)
|
||||
|
||||
_ = flags.Parse(os.Args[1:])
|
||||
if len(flags.Args()) > 0 {
|
||||
fmt.Printf("unknown command line argument: %s\n", flags.Args()[0])
|
||||
flags.Usage()
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if *printVersion {
|
||||
fmt.Println(ProgramName, version.Get())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Assert that the version is known
|
||||
if version.Undefined() {
|
||||
log.Print("WARNING: version not set! Set -ldflags \"-X sigs.k8s.io/node-feature-discovery/pkg/version.version=`git describe --tags --dirty --always`\" during build or run.")
|
||||
}
|
||||
|
||||
// Parse command-line arguments.
|
||||
args, err := argsParse(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse command line: %v", err)
|
||||
}
|
||||
|
||||
// Get new NfdMaster instance
|
||||
instance, err := master.NewNfdMaster(args)
|
||||
if err != nil {
|
||||
|
@ -56,88 +68,37 @@ 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) (master.Args, error) {
|
||||
args := master.Args{}
|
||||
usage := fmt.Sprintf(`%s.
|
||||
|
||||
Usage:
|
||||
%s [--prune] [--no-publish] [--label-whitelist=<pattern>] [--port=<port>]
|
||||
[--ca-file=<path>] [--cert-file=<path>] [--key-file=<path>]
|
||||
[--verify-node-name] [--extra-label-ns=<list>] [--resource-labels=<list>]
|
||||
[--kubeconfig=<path>] [--instance=<name>]
|
||||
%s -h | --help
|
||||
%s --version
|
||||
|
||||
Options:
|
||||
-h --help Show this screen.
|
||||
--version Output version and exit.
|
||||
--prune Prune all NFD related attributes from all nodes
|
||||
of the cluster and exit.
|
||||
--instance=<name> Instance name. Used to separate annotation
|
||||
namespaces for multiple parallel deployments.
|
||||
[Default: ]
|
||||
--kubeconfig=<path> Kubeconfig to use [Default: ]
|
||||
of the cluster and exit.
|
||||
--port=<port> Port on which to listen for connections.
|
||||
[Default: 8080]
|
||||
--ca-file=<path> Root certificate for verifying connections
|
||||
[Default: ]
|
||||
--cert-file=<path> Certificate used for authenticating connections
|
||||
[Default: ]
|
||||
--key-file=<path> Private key matching --cert-file
|
||||
[Default: ]
|
||||
--verify-node-name Verify worker node name against CN from the TLS
|
||||
certificate. Only has effect when TLS authentication
|
||||
has been enabled.
|
||||
--no-publish Do not publish feature labels
|
||||
--label-whitelist=<pattern> Regular expression to filter label names to
|
||||
publish to the Kubernetes API server.
|
||||
NB: the label namespace is omitted i.e. the filter
|
||||
is only applied to the name part after '/'.
|
||||
[Default: ]
|
||||
--extra-label-ns=<list> Comma separated list of allowed extra label namespaces
|
||||
[Default: ]
|
||||
--resource-labels=<list> Comma separated list of labels to be exposed as extended resources.
|
||||
[Default: ]`,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
ProgramName,
|
||||
)
|
||||
|
||||
arguments, _ := docopt.ParseArgs(usage, argv,
|
||||
fmt.Sprintf("%s %s", ProgramName, version.Get()))
|
||||
|
||||
// Parse argument values as usable types.
|
||||
var err error
|
||||
args.Instance = arguments["--instance"].(string)
|
||||
if ok, _ := regexp.MatchString(`^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`, args.Instance); args.Instance != "" && !ok {
|
||||
return args, fmt.Errorf("invalid --instance %q: instance name "+
|
||||
"must start and end with an alphanumeric character and may only contain "+
|
||||
"alphanumerics, `-`, `_` or `.`", args.Instance)
|
||||
func initFlags(flagset *flag.FlagSet) *master.Args {
|
||||
args := &master.Args{
|
||||
LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
|
||||
}
|
||||
args.CaFile = arguments["--ca-file"].(string)
|
||||
args.CertFile = arguments["--cert-file"].(string)
|
||||
args.KeyFile = arguments["--key-file"].(string)
|
||||
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)
|
||||
}
|
||||
args.VerifyNodeName = arguments["--verify-node-name"].(bool)
|
||||
args.ExtraLabelNs = map[string]struct{}{}
|
||||
for _, n := range strings.Split(arguments["--extra-label-ns"].(string), ",") {
|
||||
args.ExtraLabelNs[n] = struct{}{}
|
||||
}
|
||||
args.ResourceLabels = strings.Split(arguments["--resource-labels"].(string), ",")
|
||||
args.Prune = arguments["--prune"].(bool)
|
||||
args.Kubeconfig = arguments["--kubeconfig"].(string)
|
||||
|
||||
return args, nil
|
||||
flagset.StringVar(&args.CaFile, "ca-file", "",
|
||||
"Root certificate for verifying connections")
|
||||
flagset.StringVar(&args.CertFile, "cert-file", "",
|
||||
"Certificate used for authenticating connections")
|
||||
flagset.Var(&args.ExtraLabelNs, "extra-label-ns",
|
||||
"Comma separated list of allowed extra label namespaces")
|
||||
flagset.StringVar(&args.Instance, "instance", "",
|
||||
"Instance name. Used to separate annotation namespaces for multiple parallel deployments.")
|
||||
flagset.StringVar(&args.KeyFile, "key-file", "",
|
||||
"Private key matching -cert-file")
|
||||
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
|
||||
"Kubeconfig to use")
|
||||
flagset.Var(&args.LabelWhiteList, "label-whitelist",
|
||||
"Regular expression to filter label names to publish to the Kubernetes API server. "+
|
||||
"NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.")
|
||||
flagset.BoolVar(&args.NoPublish, "no-publish", false,
|
||||
"Do not publish feature labels")
|
||||
flagset.IntVar(&args.Port, "port", 8080,
|
||||
"Port on which to listen for connections.")
|
||||
flagset.BoolVar(&args.Prune, "prune", false,
|
||||
"Prune all NFD related attributes from all nodes of the cluaster and exit.")
|
||||
flagset.Var(&args.ResourceLabels, "resource-labels",
|
||||
"Comma separated list of labels to be exposed as extended resources.")
|
||||
flagset.BoolVar(&args.VerifyNodeName, "verify-node-name", false,
|
||||
"Verify worker node name against CN from the TLS certificate. "+
|
||||
"Only takes effect when TLS authentication has been enabled.")
|
||||
|
||||
return args
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
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 (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestArgsParse(t *testing.T) {
|
||||
Convey("When parsing command line arguments", t, func() {
|
||||
Convey("When --no-publish and --oneshot flags are passed", func() {
|
||||
args, err := argsParse([]string{"--no-publish"})
|
||||
Convey("noPublish is set and args.sources is set to the default value", func() {
|
||||
So(args.NoPublish, ShouldBeTrue)
|
||||
So(len(args.LabelWhiteList.String()), ShouldEqual, 0)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("When valid args are specified", func() {
|
||||
args, err := argsParse([]string{"--label-whitelist=.*rdt.*", "--port=1234", "--cert-file=crt", "--key-file=key", "--ca-file=ca"})
|
||||
Convey("Argument parsing should succeed and args set to correct values", func() {
|
||||
So(args.NoPublish, ShouldBeFalse)
|
||||
So(args.Port, ShouldEqual, 1234)
|
||||
So(args.CertFile, ShouldEqual, "crt")
|
||||
So(args.KeyFile, ShouldEqual, "key")
|
||||
So(args.CaFile, ShouldEqual, "ca")
|
||||
So(args.LabelWhiteList.String(), ShouldResemble, ".*rdt.*")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
Convey("When invalid --port is defined", func() {
|
||||
_, err := argsParse([]string{"--port=123a"})
|
||||
Convey("argsParse should fail", func() {
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
|
@ -164,43 +164,34 @@ $ docker run --rm --name=nfd-test ${NFD_CONTAINER_IMAGE} nfd-master --no-publish
|
|||
Command line flags of nfd-master:
|
||||
|
||||
```bash
|
||||
$ docker run --rm ${NFD_CONTAINER_IMAGE} nfd-master --help
|
||||
...
|
||||
Usage:
|
||||
nfd-master [--prune] [--no-publish] [--label-whitelist=<pattern>] [--port=<port>]
|
||||
[--ca-file=<path>] [--cert-file=<path>] [--key-file=<path>]
|
||||
[--verify-node-name] [--extra-label-ns=<list>] [--resource-labels=<list>]
|
||||
[--kubeconfig=<path>]
|
||||
nfd-master -h | --help
|
||||
nfd-master --version
|
||||
|
||||
Options:
|
||||
-h --help Show this screen.
|
||||
--version Output version and exit.
|
||||
--prune Prune all NFD related attributes from all nodes
|
||||
of the cluster and exit.
|
||||
--kubeconfig=<path> Kubeconfig to use [Default: ]
|
||||
--port=<port> Port on which to listen for connections.
|
||||
[Default: 8080]
|
||||
--ca-file=<path> Root certificate for verifying connections
|
||||
[Default: ]
|
||||
--cert-file=<path> Certificate used for authenticating connections
|
||||
[Default: ]
|
||||
--key-file=<path> Private key matching --cert-file
|
||||
[Default: ]
|
||||
--verify-node-name Verify worker node name against CN from the TLS
|
||||
certificate. Only has effect when TLS authentication
|
||||
has been enabled.
|
||||
--no-publish Do not publish feature labels
|
||||
--label-whitelist=<pattern> Regular expression to filter label names to
|
||||
publish to the Kubernetes API server.
|
||||
NB: the label namespace is omitted i.e. the filter
|
||||
is only applied to the name part after '/'.
|
||||
[Default: ]
|
||||
--extra-label-ns=<list> Comma separated list of allowed extra label namespaces
|
||||
[Default: ]
|
||||
--resource-labels=<list> Comma separated list of labels to be exposed as extended resources.
|
||||
[Default: ]
|
||||
$ docker run --rm ${NFD_CONTAINER_IMAGE} nfd-master -help
|
||||
Usage of nfd-master:
|
||||
-ca-file string
|
||||
Root certificate for verifying connections
|
||||
-cert-file string
|
||||
Certificate used for authenticating connections
|
||||
-extra-label-ns value
|
||||
Comma separated list of allowed extra label namespaces
|
||||
-instance string
|
||||
Instance name. Used to separate annotation namespaces for multiple parallel deployments.
|
||||
-key-file string
|
||||
Private key matching -cert-file
|
||||
-kubeconfig string
|
||||
Kubeconfig to use
|
||||
-label-whitelist value
|
||||
Regular expression to filter label names to publish to the Kubernetes API server. NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.
|
||||
-no-publish
|
||||
Do not publish feature labels
|
||||
-port int
|
||||
Port on which to listen for connections. (default 8080)
|
||||
-prune
|
||||
Prune all NFD related attributes from all nodes of the cluaster and exit.
|
||||
-resource-labels value
|
||||
Comma separated list of labels to be exposed as extended resources.
|
||||
-verify-node-name
|
||||
Verify worker node name against CN from the TLS certificate. Only takes effect when TLS authentication has been enabled.
|
||||
-version
|
||||
Print version and exit.
|
||||
```
|
||||
|
||||
### NFD-Worker
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Copyright 2019-2021 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.
|
||||
|
@ -34,6 +34,7 @@ import (
|
|||
k8sclient "k8s.io/client-go/kubernetes"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
@ -55,7 +56,7 @@ func newMockMaster(apihelper apihelper.APIHelpers) *nfdMaster {
|
|||
return &nfdMaster{
|
||||
nodeName: mockNodeName,
|
||||
annotationNs: AnnotationNsBase,
|
||||
args: Args{LabelWhiteList: regexp.MustCompile("")},
|
||||
args: Args{LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")}},
|
||||
apihelper: apihelper,
|
||||
}
|
||||
}
|
||||
|
@ -339,7 +340,7 @@ func TestSetLabels(t *testing.T) {
|
|||
apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/feature-2", mockLabels["feature-2"]),
|
||||
}
|
||||
|
||||
mockMaster.args.LabelWhiteList = regexp.MustCompile("^f.*2$")
|
||||
mockMaster.args.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
|
||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||
mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
|
||||
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
||||
|
@ -390,7 +391,7 @@ func TestSetLabels(t *testing.T) {
|
|||
apihelper.NewJsonPatch("add", "/status/capacity", LabelNs+"/feature-3", mockLabels["feature-3"]),
|
||||
}
|
||||
|
||||
mockMaster.args.ResourceLabels = []string{"feature-3", "feature-1"}
|
||||
mockMaster.args.ResourceLabels = map[string]struct{}{"feature-3": struct{}{}, "feature-1": struct{}{}}
|
||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||
mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
|
||||
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Copyright 2019-2021 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.
|
||||
|
@ -38,6 +38,7 @@ import (
|
|||
api "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||
)
|
||||
|
||||
|
@ -74,16 +75,16 @@ type Annotations map[string]string
|
|||
type Args struct {
|
||||
CaFile string
|
||||
CertFile string
|
||||
ExtraLabelNs map[string]struct{}
|
||||
ExtraLabelNs utils.StringSetVal
|
||||
Instance string
|
||||
KeyFile string
|
||||
Kubeconfig string
|
||||
LabelWhiteList *regexp.Regexp
|
||||
LabelWhiteList utils.RegexpVal
|
||||
NoPublish bool
|
||||
Port int
|
||||
Prune bool
|
||||
VerifyNodeName bool
|
||||
ResourceLabels []string
|
||||
ResourceLabels utils.StringSetVal
|
||||
}
|
||||
|
||||
type NfdMaster interface {
|
||||
|
@ -102,8 +103,8 @@ type nfdMaster struct {
|
|||
}
|
||||
|
||||
// Create new NfdMaster server instance.
|
||||
func NewNfdMaster(args Args) (NfdMaster, error) {
|
||||
nfd := &nfdMaster{args: args,
|
||||
func NewNfdMaster(args *Args) (NfdMaster, error) {
|
||||
nfd := &nfdMaster{args: *args,
|
||||
nodeName: os.Getenv("NODE_NAME"),
|
||||
ready: make(chan bool, 1),
|
||||
}
|
||||
|
@ -111,6 +112,11 @@ func NewNfdMaster(args Args) (NfdMaster, error) {
|
|||
if args.Instance == "" {
|
||||
nfd.annotationNs = AnnotationNsBase
|
||||
} else {
|
||||
if ok, _ := regexp.MatchString(`^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`, args.Instance); !ok {
|
||||
return nfd, fmt.Errorf("invalid --instance %q: instance name "+
|
||||
"must start and end with an alphanumeric character and may only contain "+
|
||||
"alphanumerics, `-`, `_` or `.`", args.Instance)
|
||||
}
|
||||
nfd.annotationNs = args.Instance + "." + AnnotationNsBase
|
||||
}
|
||||
|
||||
|
@ -283,7 +289,7 @@ func (m *nfdMaster) updateMasterNode() error {
|
|||
// into extended resources. This function also handles proper namespacing of
|
||||
// labels and ERs, i.e. adds the possibly missing default namespace for labels
|
||||
// arriving through the gRPC API.
|
||||
func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelWhiteList *regexp.Regexp, extendedResourceNames []string) (Labels, ExtendedResources) {
|
||||
func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelWhiteList regexp.Regexp, extendedResourceNames map[string]struct{}) (Labels, ExtendedResources) {
|
||||
outLabels := Labels{}
|
||||
|
||||
for label, value := range labels {
|
||||
|
@ -310,7 +316,7 @@ func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelW
|
|||
|
||||
// Remove labels which are intended to be extended resources
|
||||
extendedResources := ExtendedResources{}
|
||||
for _, extendedResourceName := range extendedResourceNames {
|
||||
for extendedResourceName := range extendedResourceNames {
|
||||
// Add possibly missing default ns
|
||||
extendedResourceName = addNs(extendedResourceName, LabelNs)
|
||||
if value, ok := outLabels[extendedResourceName]; ok {
|
||||
|
@ -354,7 +360,7 @@ func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.Se
|
|||
}
|
||||
stdoutLogger.Printf("REQUEST Node: %s NFD-version: %s Labels: %s", r.NodeName, r.NfdVersion, r.Labels)
|
||||
|
||||
labels, extendedResources := filterFeatureLabels(r.Labels, m.args.ExtraLabelNs, m.args.LabelWhiteList, m.args.ResourceLabels)
|
||||
labels, extendedResources := filterFeatureLabels(r.Labels, m.args.ExtraLabelNs, m.args.LabelWhiteList.Regexp, m.args.ResourceLabels)
|
||||
|
||||
if !m.args.NoPublish {
|
||||
// Advertise NFD worker version as an annotation
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
Copyright 2019-2021 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.
|
||||
|
@ -26,9 +26,9 @@ import (
|
|||
func TestNewNfdMaster(t *testing.T) {
|
||||
Convey("When initializing new NfdMaster instance", t, func() {
|
||||
Convey("When one of --cert-file, --key-file or --ca-file is missing", func() {
|
||||
_, err := m.NewNfdMaster(m.Args{CertFile: "crt", KeyFile: "key"})
|
||||
_, err2 := m.NewNfdMaster(m.Args{KeyFile: "key", CaFile: "ca"})
|
||||
_, err3 := m.NewNfdMaster(m.Args{CertFile: "crt", CaFile: "ca"})
|
||||
_, err := m.NewNfdMaster(&m.Args{CertFile: "crt", KeyFile: "key"})
|
||||
_, err2 := m.NewNfdMaster(&m.Args{KeyFile: "key", CaFile: "ca"})
|
||||
_, err3 := m.NewNfdMaster(&m.Args{CertFile: "crt", CaFile: "ca"})
|
||||
Convey("An error should be returned", func() {
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err2, ShouldNotBeNil)
|
||||
|
|
|
@ -34,11 +34,11 @@ type testContext struct {
|
|||
errs chan error
|
||||
}
|
||||
|
||||
func setupTest(args nfdmaster.Args) testContext {
|
||||
func setupTest(args *nfdmaster.Args) testContext {
|
||||
// Fixed port and no-publish, for convenience
|
||||
args.NoPublish = true
|
||||
args.Port = 8192
|
||||
args.LabelWhiteList = regexp.MustCompile("")
|
||||
args.LabelWhiteList.Regexp = *regexp.MustCompile("")
|
||||
m, err := nfdmaster.NewNfdMaster(args)
|
||||
if err != nil {
|
||||
fmt.Printf("Test setup failed: %v\n", err)
|
||||
|
@ -86,7 +86,7 @@ func TestNewNfdWorker(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
ctx := setupTest(nfdmaster.Args{})
|
||||
ctx := setupTest(&nfdmaster.Args{})
|
||||
defer teardownTest(ctx)
|
||||
Convey("When running nfd-worker against nfd-master", t, func() {
|
||||
Convey("When publishing features from fake source", func() {
|
||||
|
@ -100,7 +100,7 @@ func TestRun(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRunTls(t *testing.T) {
|
||||
masterArgs := nfdmaster.Args{
|
||||
masterArgs := &nfdmaster.Args{
|
||||
CaFile: data.FilePath("ca.crt"),
|
||||
CertFile: data.FilePath("nfd-test-master.crt"),
|
||||
KeyFile: data.FilePath("nfd-test-master.key"),
|
||||
|
|
62
pkg/utils/flags.go
Normal file
62
pkg/utils/flags.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2021 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 utils
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RegexpVal is a wrapper for regexp command line flags
|
||||
type RegexpVal struct {
|
||||
regexp.Regexp
|
||||
}
|
||||
|
||||
// Set implements the flag.Value interface
|
||||
func (a *RegexpVal) Set(val string) error {
|
||||
r, err := regexp.Compile(val)
|
||||
a.Regexp = *r
|
||||
return err
|
||||
}
|
||||
|
||||
// StringSetVal is a Value encapsulating a set of comma-separated strings
|
||||
type StringSetVal map[string]struct{}
|
||||
|
||||
// Set implements the flag.Value interface
|
||||
func (a *StringSetVal) Set(val string) error {
|
||||
m := map[string]struct{}{}
|
||||
for _, n := range strings.Split(val, ",") {
|
||||
m[n] = struct{}{}
|
||||
}
|
||||
*a = m
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the flag.Value interface
|
||||
func (a *StringSetVal) String() string {
|
||||
if *a == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
vals := make([]string, len(*a), 0)
|
||||
for val := range *a {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
sort.Strings(vals)
|
||||
return strings.Join(vals, ",")
|
||||
}
|
Loading…
Reference in a new issue