Skip to content

Commit

Permalink
Merge pull request #2426 from coutinhop/automated-cherry-pick-of-#239…
Browse files Browse the repository at this point in the history
…0-upstream-release-v3.20

Automated cherry pick of #2390: Refactor version mismatch checking to not need argument
  • Loading branch information
coutinhop authored Sep 28, 2021
2 parents 0e555ea + c75e7d8 commit dcb4b76
Show file tree
Hide file tree
Showing 26 changed files with 346 additions and 291 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ TEST_CONTAINER_NAME ?= calico/test
CALICOCTL_GIT_REVISION?=$(shell git rev-parse --short HEAD)

LDFLAGS=-ldflags "-X $(PACKAGE_NAME)/v3/calicoctl/commands.VERSION=$(GIT_VERSION) \
-X $(PACKAGE_NAME)/v3/calicoctl/commands.GIT_REVISION=$(CALICOCTL_GIT_REVISION) -s -w"
-X $(PACKAGE_NAME)/v3/calicoctl/commands.GIT_REVISION=$(CALICOCTL_GIT_REVISION) \
-X $(PACKAGE_NAME)/v3/calicoctl/commands/common.VERSION=$(GIT_VERSION) -s -w"

.PHONY: clean
## Clean enough that a new release build will be clean
Expand Down
25 changes: 8 additions & 17 deletions calicoctl/calicoctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ func main() {
datastore Calico datastore management.
Options:
-h --help Show this screen.
-l --log-level=<level> Set the log level (one of panic, fatal, error,
warn, info, debug) [default: panic]
--context=<context> The name of the kubeconfig context to use.
--allow-version-mismatch Allow client and cluster versions mismatch.
-h --help Show this screen.
-l --log-level=<level> Set the log level (one of panic, fatal, error,
warn, info, debug) [default: panic]
--context=<context> The name of the kubeconfig context to use.
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
The %s is used to manage Calico network and security
Expand Down Expand Up @@ -101,18 +101,9 @@ Description:
command := arguments["<command>"].(string)
args := append([]string{command}, arguments["<args>"].([]string)...)

// A "datastore migrate import" command should skip version mismatch checking,
// since the datastore will not have the cluster version set
isImport := args[0] == "datastore" && args[1] == "migrate" && args[2] == "import"

// Check for client/cluster version mismatch. If a mismatch occurs, check for
// --allow-version-mismatch arg to override/fail.
allowMismatch, ok := arguments["--allow-version-mismatch"].(bool)
if (!ok || !allowMismatch) && !isImport {
if err = commands.VersionMismatch(args); err != nil {
fmt.Fprintf(os.Stderr, "%s\n Use --allow-version-mismatch to override.", err)
os.Exit(1)
}
// Propagate the '--allow-version-mismatch' arg to override version mismatch checking.
if allowMismatch, _ := arguments["--allow-version-mismatch"].(bool); allowMismatch {
args = append(args, "--allow-version-mismatch")
}

var err error
Expand Down
33 changes: 17 additions & 16 deletions calicoctl/commands/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
func Apply(args []string) error {
doc := constants.DatastoreIntro + `Usage:
<BINARY_NAME> apply --filename=<FILENAME> [--recursive] [--skip-empty]
[--config=<CONFIG>] [--namespace=<NS>] [--context=<context>]
[--config=<CONFIG>] [--namespace=<NS>] [--context=<context>] [--allow-version-mismatch]
Examples:
# Apply a policy using the data in policy.yaml.
Expand All @@ -40,21 +40,22 @@ Examples:
cat policy.json | <BINARY_NAME> apply -f -
Options:
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to apply the resource. If set to
"-" loads from stdin. If filename is a directory, this command is
invoked for each .json .yaml and .yml file within that directory,
terminating after the first failure.
-R --recursive Process the filename specified in -f or --filename recursively.
--skip-empty Do not error if any files or directory specified using -f or --filename contain no
data.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-n --namespace=<NS> Namespace of the resource.
Only applicable to NetworkPolicy, NetworkSet, and WorkloadEndpoint.
Uses the default namespace if not specified.
--context=<context> The name of the kubeconfig context to use.
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to apply the resource. If set to
"-" loads from stdin. If filename is a directory, this command is
invoked for each .json .yaml and .yml file within that directory,
terminating after the first failure.
-R --recursive Process the filename specified in -f or --filename recursively.
--skip-empty Do not error if any files or directory specified using -f or --filename contain no
data.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-n --namespace=<NS> Namespace of the resource.
Only applicable to NetworkPolicy, NetworkSet, and WorkloadEndpoint.
Uses the default namespace if not specified.
--context=<context> The name of the kubeconfig context to use.
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
The apply command is used to create or replace a set of resources by filename
Expand Down
5 changes: 5 additions & 0 deletions calicoctl/commands/common/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ func ExecuteConfigCommand(args map[string]interface{}, action action) CommandRes

log.Info("Executing config command")

err := CheckVersionMismatch(args["--config"], args["--allow-version-mismatch"])
if err != nil {
return CommandResults{Err: err}
}

errorOnEmpty := !argutils.ArgBoolOrFalse(args, "--skip-empty")

if filename := args["--filename"]; filename != nil {
Expand Down
82 changes: 82 additions & 0 deletions calicoctl/commands/common/version_mismatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) 2021 Tigera, Inc. All rights reserved.

// 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 common

import (
"context"
"errors"
"fmt"
"strings"

log "github.com/sirupsen/logrus"

"github.com/projectcalico/calicoctl/v3/calicoctl/commands/clientmgr"
cerrors "github.com/projectcalico/libcalico-go/lib/errors"
"github.com/projectcalico/libcalico-go/lib/options"
)

var VERSION string

func CheckVersionMismatch(configArg, allowMismatchArg interface{}) error {
if allowMismatch, _ := allowMismatchArg.(bool); allowMismatch {
log.Infof("Skip version mismatch checking due to '--allow-version-mismatch' argument")

return nil
}

cf, _ := configArg.(string)

client, err := clientmgr.NewClient(cf)
if err != nil {
// If we can't connect to the cluster, skip the check. Either we're running a command that
// doesn't need API access, in which case the check doesn't need to be run, or we'll
// fail on the actual command.
log.Infof("Skip version mismatch checking due to not being able to connect to the cluster")

return nil
}

ctx := context.Background()

ci, err := client.ClusterInformation().Get(ctx, "default", options.GetOptions{})
if err != nil {
var notFound cerrors.ErrorResourceDoesNotExist
if errors.As(err, &notFound) {
// ClusterInformation does not exist, so skip version check.
log.Infof("Skip version mismatch checking due to ClusterInformation not being present")

return nil
}
return fmt.Errorf("Unable to get Cluster Information to verify version mismatch: %w\nUse --allow-version-mismatch to override.\n", err)
}

clusterv := ci.Spec.CalicoVersion
if clusterv == "" {
// CalicoVersion field not specified in the cluster, so skip check.
log.Infof("Skip version mismatch checking due to CalicoVersion not being set")

return nil
}

clusterv = strings.Split(clusterv, "-")[0]

clientv := strings.Split(VERSION, "-")[0]

if clusterv != clientv {
return fmt.Errorf("Version mismatch.\nClient Version: %s\nCluster Version: %s\nUse --allow-version-mismatch to override.\n", VERSION, clusterv)
}

return nil
}
7 changes: 5 additions & 2 deletions calicoctl/commands/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
func Convert(args []string) error {
doc := constants.DatastoreIntro + `Usage:
<BINARY_NAME> convert --filename=<FILENAME>
[--output=<OUTPUT>] [--ignore-validation]
[--output=<OUTPUT>] [--ignore-validation] [--allow-version-mismatch]
Examples:
# Convert the contents of policy.yaml to v3 policy.
Expand All @@ -51,7 +51,8 @@ Options:
"-" loads from stdin.
-o --output=<OUTPUT FORMAT> Output format. One of: yaml or json.
[Default: yaml]
--ignore-validation Skip validation on the converted manifest.
--ignore-validation Skip validation on the converted manifest.
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
Expand All @@ -71,6 +72,8 @@ Description:
return nil
}

// Note: Intentionally not check version mismatch for this command

var rp common.ResourcePrinter
output := parsedArgs["--output"].(string)
// Only supported output formats are yaml (default) and json.
Expand Down
37 changes: 19 additions & 18 deletions calicoctl/commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
func Create(args []string) error {
doc := constants.DatastoreIntro + `Usage:
<BINARY_NAME> create --filename=<FILENAME> [--recursive] [--skip-empty]
[--skip-exists] [--config=<CONFIG>] [--namespace=<NS>] [--context=<context>]
[--skip-exists] [--config=<CONFIG>] [--namespace=<NS>] [--context=<context>] [--allow-version-mismatch]
Examples:
# Create a policy using the data in policy.yaml.
Expand All @@ -40,23 +40,24 @@ Examples:
cat policy.json | <BINARY_NAME> create -f -
Options:
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to create the resource. If set to
"-" loads from stdin. If filename is a directory, this command is
invoked for each .json .yaml and .yml file within that directory,
terminating after the first failure.
-R --recursive Process the filename specified in -f or --filename recursively.
--skip-empty Do not error if any files or directory specified using -f or --filename contain no
data.
--skip-exists Skip over and treat as successful any attempts to
create an entry that already exists.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-n --namespace=<NS> Namespace of the resource.
Only applicable to NetworkPolicy, NetworkSet, and WorkloadEndpoint.
Uses the default namespace if not specified.
--context=<context> The name of the kubeconfig context to use.
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to create the resource. If set to
"-" loads from stdin. If filename is a directory, this command is
invoked for each .json .yaml and .yml file within that directory,
terminating after the first failure.
-R --recursive Process the filename specified in -f or --filename recursively.
--skip-empty Do not error if any files or directory specified using -f or --filename contain no
data.
--skip-exists Skip over and treat as successful any attempts to
create an entry that already exists.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-n --namespace=<NS> Namespace of the resource.
Only applicable to NetworkPolicy, NetworkSet, and WorkloadEndpoint.
Uses the default namespace if not specified.
--context=<context> The name of the kubeconfig context to use.
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
The create command is used to create a set of resources by filename or stdin.
Expand Down
18 changes: 12 additions & 6 deletions calicoctl/commands/datastore/migrate/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"

apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
"github.com/projectcalico/calicoctl/v3/calicoctl/commands/clientmgr"
"github.com/projectcalico/calicoctl/v3/calicoctl/commands/common"
"github.com/projectcalico/calicoctl/v3/calicoctl/commands/constants"
"github.com/projectcalico/calicoctl/v3/calicoctl/util"
"github.com/projectcalico/libcalico-go/lib/apiconfig"
apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
libapiv3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
"github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion"
)
Expand Down Expand Up @@ -80,13 +80,14 @@ var namespacedResources map[string]struct{} = map[string]struct{}{

func Export(args []string) error {
doc := `Usage:
<BINARY_NAME> datastore migrate export [--config=<CONFIG>]
<BINARY_NAME> datastore migrate export [--config=<CONFIG>] [--allow-version-mismatch]
Options:
-h --help Show this screen.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-h --help Show this screen.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
Export the contents of the etcdv3 datastore. Resources will be exported
Expand Down Expand Up @@ -127,6 +128,11 @@ Description:
return nil
}

err = common.CheckVersionMismatch(parsedArgs["--config"], parsedArgs["--allow-version-mismatch"])
if err != nil {
return err
}

cf := parsedArgs["--config"].(string)
// Get the backend client.
client, err := clientmgr.NewClient(cf)
Expand Down
17 changes: 10 additions & 7 deletions calicoctl/commands/datastore/migrate/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ import (

func Import(args []string) error {
doc := `Usage:
<BINARY_NAME> datastore migrate import --filename=<FILENAME> [--config=<CONFIG>]
<BINARY_NAME> datastore migrate import --filename=<FILENAME> [--config=<CONFIG>] [--allow-version-mismatch]
Options:
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to import resources. If set to
"-" loads from stdin.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-h --help Show this screen.
-f --filename=<FILENAME> Filename to use to import resources. If set to
"-" loads from stdin.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
Import the contents of the etcdv3 datastore from the file created by the
Expand All @@ -75,6 +76,8 @@ Description:
return nil
}

// Note: Intentionally not check version mismatch for this command

cf := parsedArgs["--config"].(string)
cfg, err := clientmgr.LoadClientConfig(cf)
if err != nil {
Expand Down
17 changes: 12 additions & 5 deletions calicoctl/commands/datastore/migrate/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/docopt/docopt-go"

"github.com/projectcalico/calicoctl/v3/calicoctl/commands/clientmgr"
"github.com/projectcalico/calicoctl/v3/calicoctl/commands/common"
"github.com/projectcalico/calicoctl/v3/calicoctl/commands/constants"
"github.com/projectcalico/calicoctl/v3/calicoctl/util"
"github.com/projectcalico/libcalico-go/lib/clientv3"
Expand All @@ -30,13 +31,14 @@ import (

func Lock(args []string) error {
doc := `Usage:
<BINARY_NAME> datastore migrate lock [--config=<CONFIG>]
<BINARY_NAME> datastore migrate lock [--config=<CONFIG>] [--allow-version-mismatch]
Options:
-h --help Show this screen.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
-h --help Show this screen.
-c --config=<CONFIG> Path to the file containing connection
configuration in YAML or JSON format.
[default: ` + constants.DefaultConfigPath + `]
--allow-version-mismatch Allow client and cluster versions mismatch.
Description:
Lock the datastore to prepare it for migration. This prevents any new
Expand All @@ -55,6 +57,11 @@ Description:
return nil
}

err = common.CheckVersionMismatch(parsedArgs["--config"], parsedArgs["--allow-version-mismatch"])
if err != nil {
return err
}

cf := parsedArgs["--config"].(string)
client, err := clientmgr.NewClient(cf)
if err != nil {
Expand Down
Loading

0 comments on commit dcb4b76

Please sign in to comment.