diff --git a/internal/signalfx-agent/pkg/core/config/loader.go b/internal/signalfx-agent/pkg/core/config/loader.go deleted file mode 100644 index c8e0760f9d..0000000000 --- a/internal/signalfx-agent/pkg/core/config/loader.go +++ /dev/null @@ -1,150 +0,0 @@ -package config - -import ( - "context" - "fmt" - "os" - "regexp" - "time" - - yaml "gopkg.in/yaml.v2" - - "github.com/signalfx/defaults" - "github.com/signalfx/signalfx-agent/pkg/core/config/sources" - "github.com/signalfx/signalfx-agent/pkg/utils" - "github.com/signalfx/signalfx-agent/pkg/utils/structtags" - log "github.com/sirupsen/logrus" -) - -// LoadConfig handles loading the main config file and recursively rendering -// any dynamic values in the config. If watchInterval is 0, the config will be -// loaded once and sent to the returned channel, after which the channel will -// be closed. Otherwise, the returned channel will remain open and will be -// sent any config updates. -func LoadConfig(ctx context.Context, configPath string) (<-chan *Config, error) { - configYAML, configFileChanges, err := sources.ReadConfig(configPath, ctx.Done()) - if err != nil { - return nil, fmt.Errorf("could not read config file %s: %w", configPath, err) - } - - dynamicProvider := sources.DynamicValueProvider{} - - dynamicValueCtx, cancelDynamic := context.WithCancel(ctx) - finalYAML, dynamicChanges, err := dynamicProvider.ReadDynamicValues(configYAML, dynamicValueCtx.Done()) - if err != nil { - cancelDynamic() - return nil, err - } - - config, err := loadYAML(finalYAML) - if err != nil { - cancelDynamic() - return nil, err - } - - // Give it enough room to hold the initial config load. - loads := make(chan *Config, 1) - - loads <- config - - if configFileChanges != nil || dynamicChanges != nil { - go func() { - for { - // We can have changes either in the dynamic values or the - // config file itself. If the config file changes, we have to - // recreate the dynamic value watcher since it is configured - // from the config file. - select { - case configYAML = <-configFileChanges: - cancelDynamic() - - dynamicValueCtx, cancelDynamic = context.WithCancel(ctx) - - finalYAML, dynamicChanges, err = dynamicProvider.ReadDynamicValues(configYAML, dynamicValueCtx.Done()) - if err != nil { - log.WithError(err).Error("Could not read dynamic values in config after change") - time.Sleep(5 * time.Second) - continue - } - - config, err := loadYAML(finalYAML) - if err != nil { - log.WithError(err).Error("Could not parse config after change") - continue - } - - loads <- config - case finalYAML = <-dynamicChanges: - config, err := loadYAML(finalYAML) - if err != nil { - log.WithError(err).Error("Could not parse config after change") - continue - } - loads <- config - case <-ctx.Done(): - cancelDynamic() - return - } - } - }() - } else { - cancelDynamic() - } - return loads, nil -} - -func loadYAML(fileContent []byte) (*Config, error) { - config := &Config{} - - preprocessedContent := preprocessConfig(fileContent) - - err := yaml.UnmarshalStrict(preprocessedContent, config) - if err != nil { - return nil, utils.YAMLErrorWithContext(preprocessedContent, err) - } - - if err := defaults.Set(config); err != nil { - panic(fmt.Sprintf("Config defaults are wrong types: %s", err)) - } - - if err := structtags.CopyTo(config); err != nil { - panic(fmt.Sprintf("Error copying configs to fields: %v", err)) - } - - return config.initialize() -} - -var envVarRE = regexp.MustCompile(`\${\s*([\w-]+?)\s*}`) - -// Hold all of the envvars so that when they are sanitized from the proc we can -// still get to them when we need to rerender config -var envVarCache = make(map[string]string) - -var envVarWhitelist = map[string]bool{ - "MY_NODE_NAME": true, -} - -// Replaces envvar syntax with the actual envvars -func preprocessConfig(content []byte) []byte { - return envVarRE.ReplaceAllFunc(content, func(bs []byte) []byte { - parts := envVarRE.FindSubmatch(bs) - envvar := string(parts[1]) - - val, ok := envVarCache[envvar] - - if !ok { - val = os.Getenv(envvar) - envVarCache[envvar] = val - - log.WithFields(log.Fields{ - "envvar": envvar, - }).Debug("Sanitizing envvar from agent") - - if !envVarWhitelist[envvar] { - os.Unsetenv(envvar) - } - } - - return []byte(val) - }) -} diff --git a/internal/signalfx-agent/pkg/core/config/loader_test.go b/internal/signalfx-agent/pkg/core/config/loader_test.go deleted file mode 100644 index b5e534cab8..0000000000 --- a/internal/signalfx-agent/pkg/core/config/loader_test.go +++ /dev/null @@ -1,505 +0,0 @@ -package config - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/signalfx/signalfx-agent/pkg/utils" -) - -var _ = Describe("Config Loader", func() { - var dir string - var ctx context.Context - var cancel func() - - mkFile := func(path string, content string) string { - fullPath := filepath.Join(dir, path) - - err := os.MkdirAll(filepath.Dir(fullPath), 0755) - Expect(err).ShouldNot(HaveOccurred()) - - err = ioutil.WriteFile(fullPath, []byte(content), 0644) - Expect(err).ShouldNot(HaveOccurred()) - - return fullPath - } - - outdent := utils.StripIndent - - BeforeEach(func() { - var err error - dir, err = ioutil.TempDir("", "loader-test") - Expect(err).ShouldNot(HaveOccurred()) - - ctx, cancel = context.WithCancel(context.Background()) - }) - - AfterEach(func() { - if dir != "" { - os.RemoveAll(dir) - } - cancel() - }) - - It("Loads a basic config file", func() { - path := mkFile("agent/agent.yaml", `signalFxAccessToken: abcd`) - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.SignalFxAccessToken).To(Equal("abcd")) - }) - - It("Does basic validation checks on a config file", func() { - path := mkFile("agent/agent.yaml", outdent(` - signalFxAccessToken: abcd - monitors: {} - `)) - _, err := LoadConfig(ctx, path) - Expect(err).To(HaveOccurred()) - }) - - It("Errors on missing source path", func() { - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: {"#from": '%s/does-not-exist'} - `, dir))) - - _, err := LoadConfig(ctx, path) - Expect(err).To(HaveOccurred()) - }) - - It("Fills in dynamic values", func() { - tokenPath := mkFile("agent/token", "abcd") - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: {"#from": '%s'} - `, tokenPath))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.SignalFxAccessToken).To(Equal("abcd")) - }) - - It("Will merge seq into single seq", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - - a - - b - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - - c - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - databases: {"#from": '%s/agent/conf/*.yaml'} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["databases"]).Should(ConsistOf("a", "b", "c")) - }) - - It("Will error if merging maps and seqs", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - - a - - b - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - env: dev - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - databases: {"#from": '%s/agent/conf/*.yaml'} - `, dir))) - - _, err := LoadConfig(ctx, path) - Expect(err).To(HaveOccurred()) - }) - - It("Will render seq into seq", func() { - mkFile("agent/conf/databases.yaml", outdent(` - [a, b, c] - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - databases: {"#from": '%s/agent/conf/databases.yaml'} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["databases"]).Should(ConsistOf("a", "b", "c")) - }) - - It("Flattens seqs into seq", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - - type: collectd/cpu - intervalSeconds: 5 - - type: collectd/vmem - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - - type: collectd/mysql - host: 127.0.0.1 - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: fake - - {"#from": '%s/agent/conf/*.yaml', flatten: true} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(len(config.Monitors)).To(Equal(4)) - }) - - It("Will not flatten seqs into map", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - - type: collectd/cpu - intervalSeconds: 5 - - type: collectd/vmem - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - - type: collectd/mysql - host: 127.0.0.1 - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - _: {"#from": '%s/agent/conf/*.yaml', flatten: true} - `, dir))) - - _, err := LoadConfig(ctx, path) - Expect(err).To(HaveOccurred()) - }) - - It("Flattens dynamic map into map", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - port: 80 - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - host: 127.0.0.1 - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - _: {"#from": '%s/agent/conf/*.yaml', flatten: true} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(len(config.Monitors)).To(Equal(1)) - Expect(config.Monitors[0].OtherConfig["port"]).To(Equal(80)) - }) - - It("Will flatten dynamic map from key that start's with _", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - port: 80 - name: test - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - host: 127.0.0.1 - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - _: {"#from": '%s/agent/conf/*.yaml', flatten: true} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["name"]).To(Equal("test")) - Expect(config.Monitors[0].OtherConfig["port"]).To(Equal(80)) - Expect(config.Monitors[0].OtherConfig["host"]).To(Equal("127.0.0.1")) - }) - - It("Will not flatten dynamic map from key that doesn't start with _", func() { - mkFile("agent/conf/mon1.yaml", outdent(` - port: 80 - name: test - `)) - - mkFile("agent/conf/mon2.yaml", outdent(` - host: 127.0.0.1 - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - password: {"#from": '%s/agent/conf/*.yaml', flatten: true} - `, dir))) - - _, err := LoadConfig(ctx, path) - Expect(err).To(HaveOccurred()) - }) - - It("Watches dynamic value source for changes", func() { - tokenPath := mkFile("agent/token", "abcd") - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: {"#from": '%s'} - configSources: - file: - pollRateSeconds: 1 - `, tokenPath))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - mkFile("agent/token", "1234") - Eventually(loads, 3).Should(Receive(&config)) - - Expect(config.SignalFxAccessToken).To(Equal("1234")) - }) - - It("Recursively watches dynamic value source for changes", func() { - passwordPath := mkFile("agent/password", "s3cr3t") - - monitorPath := mkFile("agent/token", outdent(fmt.Sprintf(` - type: my-monitor - password: {"#from": '%s'} - `, passwordPath))) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: "abcd" - configSources: - file: - pollRateSeconds: 1 - monitors: - - {"#from": '%s'} - `, monitorPath))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["password"]).To(Equal("s3cr3t")) - - mkFile("agent/password", "sup3rs3cr3t") - Eventually(loads, 2).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["password"]).To(Equal("sup3rs3cr3t")) - }) - - It("Recursively watches three levels deep for changes", func() { - envPath := mkFile("agent/env", "dev") - - dimPath := mkFile("agent/dim", outdent(fmt.Sprintf(` - author: bob - env: {"#from": '%s'} - `, envPath))) - - monitorPath := mkFile("agent/monitors", outdent(fmt.Sprintf(` - type: my-monitor - extraDimensions: {"#from": '%s'} - `, dimPath))) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: "abcd" - configSources: - file: - pollRateSeconds: 1 - monitors: - - {"#from": '%s'} - `, monitorPath))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].ExtraDimensions["env"]).To(Equal("dev")) - - mkFile("agent/env", "prod") - Eventually(loads, 2).Should(Receive(&config)) - - Expect(config.Monitors[0].ExtraDimensions["env"]).To(Equal("prod")) - }) - - It("Handles dynamic value reference loops without blowing out stack", func() { - configPath := mkFile("agent/agent.yaml", "") - - dimPath := mkFile("agent/dims", outdent(fmt.Sprintf(` - env: {"#from": "%s"} - `, configPath))) - - monitorPath := mkFile("agent/monitors", outdent(fmt.Sprintf(` - type: my-monitor - extraDimensions: {"#from": "%s"} - `, dimPath))) - - mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: "abcd" - configSources: - file: - pollRateSeconds: 1 - monitors: - - {"#from": "%s", flatten: true} - `, monitorPath))) - - _, err := LoadConfig(ctx, configPath) - Expect(err).To(HaveOccurred()) - }) - - It("Allows multiple references to the same source path", func() { - tokenPath := mkFile("agent/token", "abcd") - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: {"#from": '%s'} - configSources: - file: - pollRateSeconds: 1 - monitors: - - type: my-monitor - password: {"#from": '%s'} - other: {"#from": '%s'} - `, tokenPath, tokenPath, tokenPath))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - mkFile("agent/token", "1234") - Eventually(loads, 2).Should(Receive(&config)) - - Expect(config.SignalFxAccessToken).To(Equal("1234")) - Expect(config.Monitors[0].OtherConfig["password"]).To(Equal(1234)) - }) - - It("Allows optional values", func() { - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - password: {"#from": '%s/agent/mysql-password.yaml', optional: true} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["password"]).To(BeNil()) - }) - - It("Allows default values", func() { - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/mysql - password: {"#from": '%s/agent/mysql-password.yaml', default: "s3cr3t"} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["password"]).To(Equal("s3cr3t")) - }) - - It("Will render raw seq into seq position", func() { - mkFile("agent/conf/config.yaml", outdent(` - LoadPlugin "cpufreq" - `)) - - path := mkFile("agent/agent.yaml", outdent(fmt.Sprintf(` - signalFxAccessToken: abcd - monitors: - - type: collectd/my-monitor - templates: - - {"#from": '%s/agent/conf/*.yaml', flatten: true, raw: true} - `, dir))) - - loads, err := LoadConfig(ctx, path) - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.Monitors[0].OtherConfig["templates"]).Should(ConsistOf(`LoadPlugin "cpufreq"`)) - }) - - It("Allows JSONPath processing of source values", func() { - path := mkFile("agent/agent.yaml", outdent(` - signalFxAccessToken: {"#from": "env:ASDF_INFO", jsonPath: "$.token"} - `)) - - os.Setenv("ASDF_INFO", `{"token": "s3cr3t", "app_name": "my_app"}`) - loads, err := LoadConfig(ctx, path) - os.Unsetenv("ASDF_INFO") - - Expect(err).ShouldNot(HaveOccurred()) - - var config *Config - Eventually(loads).Should(Receive(&config)) - - Expect(config.SignalFxAccessToken).Should(Equal(`s3cr3t`)) - }) - -}) - -func TestLoader(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Config Loader") -} diff --git a/internal/signalfx-agent/pkg/utils/events.go b/internal/signalfx-agent/pkg/utils/events.go deleted file mode 100644 index e03cfcd150..0000000000 --- a/internal/signalfx-agent/pkg/utils/events.go +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -import "github.com/signalfx/golib/v3/event" - -// CloneEvent creates a new instance of the event with a shallow copy of all -// map data structures. -func CloneEvent(ev *event.Event) *event.Event { - return event.NewWithProperties(ev.EventType, ev.Category, CloneStringMap(ev.Dimensions), CloneInterfaceMap(ev.Properties), ev.Timestamp) -} diff --git a/internal/signalfx-agent/pkg/utils/log.go b/internal/signalfx-agent/pkg/utils/log.go index bbc6dc3270..ba9247a3c9 100644 --- a/internal/signalfx-agent/pkg/utils/log.go +++ b/internal/signalfx-agent/pkg/utils/log.go @@ -8,48 +8,8 @@ import ( lru "github.com/hashicorp/golang-lru" "github.com/signalfx/golib/v3/log" "github.com/sirupsen/logrus" - - apmlog "github.com/signalfx/signalfx-agent/pkg/apm/log" ) -func NewAPMShim(log logrus.FieldLogger) apmlog.Logger { - return apmShim{log: log} -} - -type apmShim struct { - log logrus.FieldLogger -} - -func (a apmShim) Debug(msg string) { - a.log.Debug(msg) -} - -func (a apmShim) Warn(msg string) { - a.log.Warn(msg) -} - -func (a apmShim) Error(msg string) { - a.log.Error(msg) -} - -func (a apmShim) Info(msg string) { - a.log.Info(msg) -} - -func (a apmShim) Panic(msg string) { - a.log.Panic(msg) -} - -func (a apmShim) WithFields(fields apmlog.Fields) apmlog.Logger { - return apmShim{log: a.log.WithFields(logrus.Fields(fields))} -} - -func (a apmShim) WithError(err error) apmlog.Logger { - return apmShim{log: a.log.WithError(err)} -} - -var _ apmlog.Logger = &apmShim{} - // LogrusGolibShim makes a Logrus logger conform to the golib Log interface type LogrusGolibShim struct { logrus.FieldLogger diff --git a/pkg/extension/smartagentextension/go.sum b/pkg/extension/smartagentextension/go.sum index d4d17e1257..438060ec11 100644 --- a/pkg/extension/smartagentextension/go.sum +++ b/pkg/extension/smartagentextension/go.sum @@ -503,7 +503,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= @@ -511,8 +510,6 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/okta/okta-sdk-golang/v2 v2.12.1 h1:U+smE7trkHSZO8Mval3Ow85dbxawO+pMAr692VZq9gM= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= @@ -918,7 +915,6 @@ gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=