From 2512ef435f0bfb1ffcf7da12c57d7812d9ea207c Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 5 Jul 2024 19:21:59 +0400 Subject: [PATCH] test: fix the integrtion tests for apply-config They got broken after refactoring. Also use this PR to test things before the release. Signed-off-by: Andrey Smirnov --- Dockerfile | 24 ++-- go.mod | 2 +- .../server/v1alpha1/v1alpha1_server.go | 36 ++--- .../pkg/runtime/v1alpha1/v1alpha1_runtime.go | 11 +- internal/integration/api/apply-config.go | 22 +-- pkg/machinery/config/configdiff/configdiff.go | 129 ++++++++++++++++++ .../config/configdiff/configdiff_test.go | 84 ++++++++++++ pkg/machinery/go.mod | 4 + pkg/machinery/go.sum | 10 ++ 9 files changed, 268 insertions(+), 54 deletions(-) create mode 100644 pkg/machinery/config/configdiff/configdiff.go create mode 100644 pkg/machinery/config/configdiff/configdiff_test.go diff --git a/Dockerfile b/Dockerfile index f15c97030f..4226a921e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -504,9 +504,9 @@ FROM scratch AS talosctl ARG TARGETARCH COPY --from=talosctl-all /talosctl-linux-${TARGETARCH} /talosctl ARG TAG -ENV VERSION ${TAG} +ENV VERSION=${TAG} LABEL "alpha.talos.dev/version"="${VERSION}" -LABEL org.opencontainers.image.source https://github.com/siderolabs/talos +LABEL org.opencontainers.image.source=https://github.com/siderolabs/talos ENTRYPOINT ["/talosctl"] # The kernel target is the linux kernel. @@ -755,7 +755,7 @@ COPY --from=initramfs-archive /initramfs.xz /initramfs-${TARGETARCH}.xz FROM scratch AS talos COPY --from=rootfs / / -LABEL org.opencontainers.image.source https://github.com/siderolabs/talos +LABEL org.opencontainers.image.source=https://github.com/siderolabs/talos ENTRYPOINT ["/sbin/init"] # The installer target generates an image that can be used to install Talos to @@ -793,7 +793,7 @@ FROM install-artifacts-${INSTALLER_ARCH} AS install-artifacts FROM alpine:3.18.4 AS installer-image ARG SOURCE_DATE_EPOCH -ENV SOURCE_DATE_EPOCH ${SOURCE_DATE_EPOCH} +ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} RUN apk add --no-cache --update --no-scripts \ bash \ binutils-aarch64 \ @@ -813,7 +813,7 @@ RUN apk add --no-cache --update --no-scripts \ xz \ zstd ARG TARGETARCH -ENV TARGETARCH ${TARGETARCH} +ENV TARGETARCH=${TARGETARCH} COPY --from=installer-build /installer /bin/installer COPY --chmod=0644 hack/extra-modules.conf /etc/modules.d/10-extra-modules.conf COPY --from=pkg-grub / / @@ -827,9 +827,9 @@ RUN find /bin /etc /lib /usr /sbin | grep -Ev '/etc/hosts|/etc/resolv.conf' \ FROM scratch AS installer-image-squashed COPY --from=installer-image / / ARG TAG -ENV VERSION ${TAG} +ENV VERSION=${TAG} LABEL "alpha.talos.dev/version"="${VERSION}" -LABEL org.opencontainers.image.source https://github.com/siderolabs/talos +LABEL org.opencontainers.image.source=https://github.com/siderolabs/talos ENTRYPOINT ["/bin/installer"] FROM installer-image-squashed AS installer @@ -841,7 +841,7 @@ ENTRYPOINT ["/bin/imager"] FROM imager AS iso-amd64-build ARG SOURCE_DATE_EPOCH -ENV SOURCE_DATE_EPOCH ${SOURCE_DATE_EPOCH} +ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} RUN /bin/installer \ iso \ --arch amd64 \ @@ -849,7 +849,7 @@ RUN /bin/installer \ FROM imager AS iso-arm64-build ARG SOURCE_DATE_EPOCH -ENV SOURCE_DATE_EPOCH ${SOURCE_DATE_EPOCH} +ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} RUN /bin/installer \ iso \ --arch arm64 \ @@ -868,7 +868,7 @@ FROM base AS unit-tests-runner RUN unlink /etc/ssl COPY --from=rootfs / / ARG TESTPKGS -ENV PLATFORM container +ENV PLATFORM=container ARG GO_LDFLAGS RUN --security=insecure --mount=type=cache,id=testspace,target=/tmp --mount=type=cache,target=/.cache go test -failfast -v \ -ldflags "${GO_LDFLAGS}" \ @@ -882,8 +882,8 @@ FROM base AS unit-tests-race RUN unlink /etc/ssl COPY --from=rootfs / / ARG TESTPKGS -ENV PLATFORM container -ENV CGO_ENABLED 1 +ENV PLATFORM=container +ENV CGO_ENABLED=1 ARG GO_LDFLAGS RUN --security=insecure --mount=type=cache,id=testspace,target=/tmp --mount=type=cache,target=/.cache go test -v \ -ldflags "${GO_LDFLAGS}" \ diff --git a/go.mod b/go.mod index 447bb88a32..42df527915 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,6 @@ require ( github.com/gizak/termui/v3 v3.1.0 github.com/godbus/dbus/v5 v5.1.0 github.com/golang/mock v1.6.0 - github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.19.2 github.com/google/go-tpm v0.9.1 github.com/google/nftables v0.2.0 @@ -249,6 +248,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/websocket v1.5.1 // indirect diff --git a/internal/app/machined/internal/server/v1alpha1/v1alpha1_server.go b/internal/app/machined/internal/server/v1alpha1/v1alpha1_server.go index 4000dabd9e..07a4f7d247 100644 --- a/internal/app/machined/internal/server/v1alpha1/v1alpha1_server.go +++ b/internal/app/machined/internal/server/v1alpha1/v1alpha1_server.go @@ -8,7 +8,6 @@ import ( "archive/tar" "bufio" "bytes" - stdcmp "cmp" "compress/gzip" "context" "encoding/json" @@ -28,7 +27,6 @@ import ( "github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state/protobuf/server" - "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/gopacket/gopacket/afpacket" multierror "github.com/hashicorp/go-multierror" @@ -78,11 +76,10 @@ import ( timeapi "github.com/siderolabs/talos/pkg/machinery/api/time" clientconfig "github.com/siderolabs/talos/pkg/machinery/client/config" "github.com/siderolabs/talos/pkg/machinery/config" - docscfg "github.com/siderolabs/talos/pkg/machinery/config/config" + "github.com/siderolabs/talos/pkg/machinery/config/configdiff" "github.com/siderolabs/talos/pkg/machinery/config/configloader" "github.com/siderolabs/talos/pkg/machinery/config/generate/secrets" machinetype "github.com/siderolabs/talos/pkg/machinery/config/machine" - "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" "github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/nethelpers" etcdresource "github.com/siderolabs/talos/pkg/machinery/resources/etcd" @@ -221,7 +218,10 @@ func (s *Server) ApplyConfiguration(ctx context.Context, in *machine.ApplyConfig } if in.DryRun { - details := generateDiff(s.Controller.Runtime(), cfgProvider) + details, err := generateDiff(s.Controller.Runtime(), cfgProvider) + if err != nil { + return nil, fmt.Errorf("failed to generate diff: %w", err) + } return &machine.ApplyConfigurationResponse{ Messages: []*machine.ApplyConfiguration{ @@ -295,33 +295,17 @@ func (s *Server) ApplyConfiguration(ctx context.Context, in *machine.ApplyConfig }, nil } -func generateDiff(r runtime.Runtime, provider config.Provider) string { - var cfg *v1alpha1.Config - - if r.Config() != nil { - cfg = r.ConfigContainer().RawV1Alpha1() - } - - v1alpha1Diff := cmp.Diff(cfg, provider.RawV1Alpha1(), cmp.AllowUnexported(v1alpha1.InstallDiskSizeMatcher{})) - if v1alpha1Diff == "" { - v1alpha1Diff = "No changes." +func generateDiff(r runtime.Runtime, provider config.Provider) (string, error) { + documentsDiff, err := configdiff.DiffToString(r.ConfigContainer(), provider) + if err != nil { + return "", err } - origDocs := slices.DeleteFunc(r.ConfigContainer().Documents(), func(doc docscfg.Document) bool { return doc.Kind() == v1alpha1.Version }) - newDocs := slices.DeleteFunc(provider.Documents(), func(doc docscfg.Document) bool { return doc.Kind() == v1alpha1.Version }) - - slices.SortStableFunc(origDocs, func(a, b docscfg.Document) int { return stdcmp.Compare(a.Kind(), b.Kind()) }) - slices.SortStableFunc(newDocs, func(a, b docscfg.Document) int { return stdcmp.Compare(a.Kind(), b.Kind()) }) - - documentsDiff := cmp.Diff(origDocs, newDocs) if documentsDiff == "" { documentsDiff = "No changes." } - return fmt.Sprintf(`Config diff: -%s -Documents diff: -%s`, v1alpha1Diff, documentsDiff) + return "Config diff:\n\n" + documentsDiff, nil } // GenerateConfiguration implements the machine.MachineServer interface. diff --git a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go index 23b60b7fea..c3d5b83276 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go @@ -16,13 +16,13 @@ import ( "github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe" - "github.com/google/go-cmp/cmp" "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" "github.com/siderolabs/talos/internal/app/machined/pkg/system" "github.com/siderolabs/talos/internal/app/machined/pkg/system/services" "github.com/siderolabs/talos/pkg/machinery/config" - "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" + "github.com/siderolabs/talos/pkg/machinery/config/configdiff" + "github.com/siderolabs/talos/pkg/machinery/config/container" "github.com/siderolabs/talos/pkg/machinery/resources/hardware" "github.com/siderolabs/talos/pkg/machinery/resources/k8s" ) @@ -165,9 +165,12 @@ func (r *Runtime) CanApplyImmediate(cfg config.Provider) error { } if !reflect.DeepEqual(currentConfig, newConfig) { - diff := cmp.Diff(currentConfig, newConfig, cmp.AllowUnexported(v1alpha1.InstallDiskSizeMatcher{})) + diff, err := configdiff.DiffToString(container.NewV1Alpha1(currentConfig), container.NewV1Alpha1(newConfig)) + if err != nil { + return fmt.Errorf("error calculating diff: %w", err) + } - return fmt.Errorf("this config change can't be applied in immediate mode\ndiff: %s", diff) + return fmt.Errorf("this config change can't be applied in immediate mode\ndiff:\n%s", diff) } return nil diff --git a/internal/integration/api/apply-config.go b/internal/integration/api/apply-config.go index 5497e43dd7..dc60aa5e3b 100644 --- a/internal/integration/api/apply-config.go +++ b/internal/integration/api/apply-config.go @@ -98,7 +98,7 @@ func (suite *ApplyConfigSuite) TestApply() { nodeCtx := client.WithNode(suite.ctx, node) provider, err := suite.ReadConfigFromNode(nodeCtx) - suite.Assert().NoErrorf(err, "failed to read existing config from node %q: %w", node, err) + suite.Assert().NoErrorf(err, "failed to read existing config from node %q", node) cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) { if cfg.MachineConfig.MachineSysctls == nil { @@ -118,7 +118,7 @@ func (suite *ApplyConfigSuite) TestApply() { ) if err != nil { // It is expected that the connection will EOF here, so just log the error - suite.Assert().NoErrorf(err, "failed to apply configuration (node %q): %w", node, err) + suite.Assert().NoErrorf(err, "failed to apply configuration (node %q)", node) } return nil @@ -138,7 +138,7 @@ func (suite *ApplyConfigSuite) TestApply() { return nil }, - ), "failed to read updated configuration from node %q: %w", node, err, + ), "failed to read updated configuration from node %q", node, ) suite.Assert().Equal( @@ -177,14 +177,14 @@ func (suite *ApplyConfigSuite) TestApplyWithoutReboot() { Mode: mode, }, ) - suite.Require().NoError(err, "failed to apply deferred configuration (node %q): %w", node) + suite.Require().NoError(err, "failed to apply deferred configuration (node %q)", node) // Verify configuration change var newProvider config.Provider newProvider, err = suite.ReadConfigFromNode(nodeCtx) - suite.Require().NoError(err, "failed to read updated configuration from node %q: %w", node) + suite.Require().NoError(err, "failed to read updated configuration from node %q", node) if mode == machineapi.ApplyConfigurationRequest_AUTO { suite.Assert().Equal( @@ -206,7 +206,7 @@ func (suite *ApplyConfigSuite) TestApplyWithoutReboot() { Mode: mode, }, ) - suite.Require().NoError(err, "failed to apply deferred configuration (node %q): %w", node) + suite.Require().NoError(err, "failed to apply deferred configuration (node %q)", node) } } @@ -303,7 +303,7 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { ) if err != nil { // It is expected that the connection will EOF here, so just log the error - suite.Assert().Errorf(err, "failed to apply configuration (node %q): %w", node, err) + suite.T().Logf("failed to apply configuration (node %q): %s", node, err) } return nil @@ -315,7 +315,7 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { // Verify configuration change var newProvider config.Provider - suite.Require().Errorf( + suite.Require().NoError( retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry( func() error { newProvider, err = suite.ReadConfigFromNode(nodeCtx) @@ -325,7 +325,7 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { return nil }, - ), "failed to read updated configuration from node %q: %w", node, err, + ), "failed to read updated configuration from node %q", node, ) e := newProvider.Machine().SystemDiskEncryption().Get(constants.EphemeralPartitionLabel) @@ -504,10 +504,10 @@ func (suite *ApplyConfigSuite) TestApplyTry() { TryModeTimeout: durationpb.New(time.Second * 1), }, ) - suite.Assert().NoErrorf(err, "failed to apply configuration (node %q): %s", node, err) + suite.Assert().NoErrorf(err, "failed to apply configuration (node %q)", node) provider, err = getMachineConfig(nodeCtx) - suite.Require().NoErrorf(err, "failed to read existing config from node %q: %w", node, err) + suite.Require().NoErrorf(err, "failed to read existing config from node %q", node) suite.Assert().NotNil(provider.Config().Machine().Network()) suite.Assert().NotNil(provider.Config().Machine().Network().Devices()) diff --git a/pkg/machinery/config/configdiff/configdiff.go b/pkg/machinery/config/configdiff/configdiff.go new file mode 100644 index 0000000000..908d5c70d9 --- /dev/null +++ b/pkg/machinery/config/configdiff/configdiff.go @@ -0,0 +1,129 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package configdiff provides a way to compare two config trees. +package configdiff + +import ( + "fmt" + "io" + "strings" + + "github.com/fatih/color" + "github.com/hexops/gotextdiff" + "github.com/hexops/gotextdiff/myers" + "github.com/hexops/gotextdiff/span" + + "github.com/siderolabs/talos/pkg/machinery/config" + "github.com/siderolabs/talos/pkg/machinery/config/encoder" +) + +// Diff outputs (optionally) colorized diff between two machine configurations. +// +// One of the resources might be nil. +func Diff(w io.Writer, oldCfg, newCfg config.Encoder) error { + var ( + oldYaml, newYaml []byte + err error + ) + + if oldCfg != nil { + oldYaml, err = oldCfg.EncodeBytes(encoder.WithComments(encoder.CommentsDisabled)) + if err != nil { + return err + } + } + + if newCfg != nil { + newYaml, err = newCfg.EncodeBytes(encoder.WithComments(encoder.CommentsDisabled)) + if err != nil { + return err + } + } + + edits := myers.ComputeEdits(span.URIFromPath("a"), string(oldYaml), string(newYaml)) + diff := gotextdiff.ToUnified("a", "b", string(oldYaml), edits) + + outputDiff(w, diff, true) + + return nil +} + +// DiffToString returns a string representation of the diff between two machine configurations. +func DiffToString(oldCfg, newCfg config.Encoder) (string, error) { + var sb strings.Builder + + err := Diff(&sb, oldCfg, newCfg) + + return sb.String(), err +} + +//nolint:gocyclo +func outputDiff(w io.Writer, u gotextdiff.Unified, noColor bool) { + if len(u.Hunks) == 0 { + return + } + + bold := color.New(color.Bold) + cyan := color.New(color.FgCyan) + red := color.New(color.FgRed) + green := color.New(color.FgGreen) + + if noColor { + bold.DisableColor() + cyan.DisableColor() + red.DisableColor() + green.DisableColor() + } + + bold.Fprintf(w, "--- %s\n", u.From) //nolint:errcheck + bold.Fprintf(w, "+++ %s\n", u.To) //nolint:errcheck + + for _, hunk := range u.Hunks { + fromCount, toCount := 0, 0 + + for _, l := range hunk.Lines { + switch l.Kind { //nolint:exhaustive + case gotextdiff.Delete: + fromCount++ + case gotextdiff.Insert: + toCount++ + default: + fromCount++ + toCount++ + } + } + + cyan.Fprintf(w, "@@") //nolint:errcheck + + if fromCount > 1 { + cyan.Fprintf(w, " -%d,%d", hunk.FromLine, fromCount) //nolint:errcheck + } else { + cyan.Fprintf(w, " -%d", hunk.FromLine) //nolint:errcheck + } + + if toCount > 1 { + cyan.Fprintf(w, " +%d,%d", hunk.ToLine, toCount) //nolint:errcheck + } else { + cyan.Fprintf(w, " +%d", hunk.ToLine) //nolint:errcheck + } + + cyan.Printf(" @@\n") //nolint:errcheck + + for _, l := range hunk.Lines { + switch l.Kind { //nolint:exhaustive + case gotextdiff.Delete: + red.Fprintf(w, "-%s", l.Content) //nolint:errcheck + case gotextdiff.Insert: + green.Fprintf(w, "+%s", l.Content) //nolint:errcheck + default: + fmt.Fprintf(w, " %s", l.Content) + } + + if !strings.HasSuffix(l.Content, "\n") { + red.Fprintf(w, "\n\\ No newline at end of file\n") //nolint:errcheck + } + } + } +} diff --git a/pkg/machinery/config/configdiff/configdiff_test.go b/pkg/machinery/config/configdiff/configdiff_test.go new file mode 100644 index 0000000000..f6cb0b4fe6 --- /dev/null +++ b/pkg/machinery/config/configdiff/configdiff_test.go @@ -0,0 +1,84 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package configdiff_test + +import ( + "net/url" + "testing" + + "github.com/siderolabs/gen/xtesting/must" + "github.com/stretchr/testify/require" + + "github.com/siderolabs/talos/pkg/machinery/config/config" + "github.com/siderolabs/talos/pkg/machinery/config/configdiff" + "github.com/siderolabs/talos/pkg/machinery/config/container" + "github.com/siderolabs/talos/pkg/machinery/config/types/meta" + "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink" + "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" +) + +func TestDiffString(t *testing.T) { + t.Parallel() + + v1alpha1Cfg := &v1alpha1.Config{ + ConfigVersion: "v1alpha1", + MachineConfig: &v1alpha1.MachineConfig{ + MachineType: "controlplane", + MachineToken: "foo", + }, + } + + v1alpha1CfgOther := v1alpha1Cfg.DeepCopy() + v1alpha1CfgOther.MachineConfig.MachineType = "worker" + + siderolinkConfig := siderolink.NewConfigV1Alpha1() + siderolinkConfig.APIUrlConfig = meta.URL{ + URL: must.Value(url.Parse("https://example.com"))(t), + } + + for _, test := range []struct { + name string + oldCfg []config.Document + newCfg []config.Document + want string + }{ + { + name: "empty", + oldCfg: nil, + newCfg: nil, + want: "", + }, + { + name: "same", + oldCfg: []config.Document{v1alpha1Cfg}, + newCfg: []config.Document{v1alpha1Cfg}, + want: "", + }, + { + name: "new doc", + oldCfg: []config.Document{v1alpha1Cfg}, + newCfg: []config.Document{v1alpha1Cfg, siderolinkConfig}, + want: "--- a\n+++ b\n@@ -4,3 +4,7 token: foo\n certSANs: []\n cluster: null\n+---\n+apiVersion: v1alpha1\n+kind: SideroLinkConfig\n+apiUrl: https://example.com\n", + }, + { + name: "updated field", + oldCfg: []config.Document{v1alpha1Cfg, siderolinkConfig}, + newCfg: []config.Document{v1alpha1CfgOther, siderolinkConfig}, + want: "--- a\n+++ b\n@@ -1,6 +1,6 version: v1alpha1\n machine:\n- type: controlplane\n+ type: worker\n token: foo\n certSANs: []\n cluster: null\n", + }, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + oldCfg := must.Value(container.New(test.oldCfg...))(t) + newCfg := must.Value(container.New(test.newCfg...))(t) + + got, err := configdiff.DiffToString(oldCfg, newCfg) + require.NoError(t, err) + + require.Equal(t, test.want, got) + }) + } +} diff --git a/pkg/machinery/go.mod b/pkg/machinery/go.mod index 67a7b53138..93d36b2058 100644 --- a/pkg/machinery/go.mod +++ b/pkg/machinery/go.mod @@ -13,8 +13,10 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/emicklei/dot v1.6.2 github.com/evanphx/json-patch v5.9.0+incompatible + github.com/fatih/color v1.17.0 github.com/ghodss/yaml v1.0.0 github.com/hashicorp/go-multierror v1.1.1 + github.com/hexops/gotextdiff v1.0.3 github.com/jsimonetti/rtnetlink/v2 v2.0.2 github.com/mdlayher/ethtool v0.1.0 github.com/opencontainers/runtime-spec v1.2.0 @@ -47,6 +49,8 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mdlayher/genetlink v1.3.2 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect diff --git a/pkg/machinery/go.sum b/pkg/machinery/go.sum index 4780d11fb8..fbea85d6e3 100644 --- a/pkg/machinery/go.sum +++ b/pkg/machinery/go.sum @@ -33,6 +33,8 @@ github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA= github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -52,6 +54,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jsimonetti/rtnetlink/v2 v2.0.2 h1:ZKlbCujrIpp4/u3V2Ka0oxlf4BCkt6ojkvpy3nZoCBY= @@ -60,6 +64,11 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdlayher/ethtool v0.1.0 h1:XAWHsmKhyPOo42qq/yTPb0eFBGUKKTR1rE0dVrWVQ0Y= github.com/mdlayher/ethtool v0.1.0/go.mod h1:fBMLn2UhfRGtcH5ZFjr+6GUiHEjZsItFD7fSn7jbZVQ= github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= @@ -150,6 +159,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=