diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 934bab88b..81fb94eef 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,7 @@ updates: schedule: interval: weekly open-pull-requests-limit: 10 + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c055a2f9..d5104500e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,19 +16,12 @@ jobs: os: [ ubuntu-latest, macos-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: + - name: Checkout code + uses: actions/checkout@v4 - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v2 - - name: Restore cache - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - name: Ensure code is formatted with gofmt run: make gofmt_check if: matrix.os == 'ubuntu-latest' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a64f98b40..c743072f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: runs-on: 'ubuntu-latest' steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # https://github.com/marketplace/actions/goreleaser-action#usage # note the fetch-depth: 0 input in Checkout step. It is required for @@ -19,26 +19,18 @@ jobs: fetch-depth: 0 - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: 1.21.x - - name: Restore cache - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v5 with: distribution: goreleaser version: latest @@ -51,18 +43,18 @@ jobs: runs-on: 'ubuntu-latest' steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # fetch-depth: 0 fetches all history for all branches and tags fetch-depth: 0 - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Buld snap + - name: Build snap id: build run: | make _build_snap && \ diff --git a/.github/workflows/snapcraft-candidate.yml b/.github/workflows/snapcraft-candidate.yml index fc1f3e4e9..62355a1e1 100644 --- a/.github/workflows/snapcraft-candidate.yml +++ b/.github/workflows/snapcraft-candidate.yml @@ -17,12 +17,12 @@ jobs: fetch-depth: 0 - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Buld snap + - name: Build snap id: build run: | make _build_snap && \ diff --git a/commands/activations_test.go b/commands/activations_test.go index ed30042ca..f2c6c79f1 100644 --- a/commands/activations_test.go +++ b/commands/activations_test.go @@ -16,7 +16,6 @@ package commands import ( "bytes" "errors" - "sort" "strconv" "strings" "testing" @@ -37,9 +36,7 @@ func TestActivationsCommand(t *testing.T) { names = append(names, c.Name()) } - sort.Strings(expected) - sort.Strings(names) - assert.Equal(t, expected, names) + assert.ElementsMatch(t, expected, names) } var hello1Result = whisk.Result(map[string]interface{}{ @@ -369,7 +366,7 @@ func TestActivationsList(t *testing.T) { } if k == "limit" { - limit, _ = strconv.ParseInt(v, 0, 64) + limit, _ = strconv.Atoi(v) } if k == "since" { @@ -381,7 +378,7 @@ func TestActivationsList(t *testing.T) { } if k == "skip" { - skip, _ = strconv.ParseInt(v, 0, 64) + skip, _ = strconv.Atoi(v) } if v == "" { @@ -417,11 +414,11 @@ func TestActivationsList(t *testing.T) { expectedListOptions.Name = config.Args[0] } if limit != nil { - expectedListOptions.Limit = int(limit.(int64)) + expectedListOptions.Limit = limit.(int) } if skip != nil { - expectedListOptions.Skip = int(skip.(int64)) + expectedListOptions.Skip = skip.(int) } tm.serverless.EXPECT().ListActivations(expectedListOptions).Return(theActivations, nil) } @@ -475,7 +472,7 @@ func TestActivationsLogs(t *testing.T) { if tt.doctlFlags != nil { for k, v := range tt.doctlFlags { if k == "limit" { - limit, _ = strconv.ParseInt(v, 0, 64) + limit, _ = strconv.Atoi(v) } if k == "follow" { @@ -507,7 +504,7 @@ func TestActivationsLogs(t *testing.T) { } else { expectedListOptions := whisk.ActivationListOptions{Docs: true} if limit != nil { - expectedListOptions.Limit = int(limit.(int64)) + expectedListOptions.Limit = limit.(int) } if funcName != nil { diff --git a/commands/apps.go b/commands/apps.go index fa3f3e190..32eccbdfd 100644 --- a/commands/apps.go +++ b/commands/apps.go @@ -704,9 +704,9 @@ Optionally, pass a deployment ID to get the spec of that specific deployment.`, AddStringFlag(getCmd, doctl.ArgAppDeployment, "", "", "optional: a deployment ID") AddStringFlag(getCmd, doctl.ArgFormat, "", "yaml", `the format to output the spec in; either "yaml" or "json"`) - validateCmd := CmdBuilder(cmd, RunAppsSpecValidate, "validate ", "Validate an application spec", `Use this command to check whether a given app spec (YAML or JSON) is valid. + validateCmd := cmdBuilderWithInit(cmd, RunAppsSpecValidate, "validate ", "Validate an application spec", `Use this command to check whether a given app spec (YAML or JSON) is valid. -You may pass - as the filename to read from stdin.`, Writer) +You may pass - as the filename to read from stdin.`, Writer, false) AddBoolFlag(validateCmd, doctl.ArgSchemaOnly, "", false, "Only validate the spec schema and not the correctness of the spec.") return cmd @@ -762,6 +762,7 @@ func RunAppsSpecGet(c *CmdConfig) error { } // RunAppsSpecValidate validates an app spec file +// doesn't require auth & connection to the API with doctl.ArgSchemaOnly flag func RunAppsSpecValidate(c *CmdConfig) error { if len(c.Args) < 1 { return doctl.NewMissingArgsErr(c.NS) @@ -778,6 +779,7 @@ func RunAppsSpecValidate(c *CmdConfig) error { return err } + // validate schema only (offline) if schemaOnly { ymlSpec, err := yaml.Marshal(appSpec) if err != nil { @@ -787,6 +789,10 @@ func RunAppsSpecValidate(c *CmdConfig) error { return err } + // validate the spec against the API + if err := c.initServices(c); err != nil { + return err + } res, err := c.Apps().Propose(&godo.AppProposeRequest{ Spec: appSpec, }) diff --git a/commands/cdns.go b/commands/cdns.go index 2a6ccdf56..962c6814b 100644 --- a/commands/cdns.go +++ b/commands/cdns.go @@ -87,7 +87,12 @@ Currently, you can only update the custom domain and its certificate ID with thi This is useful when you need to ensure that files which were recently changed on the origin server are immediately available via the CDN. -To purge specific files, you can use the `+"`"+`--files`+"`"+` flag and supply a path. The path may be for a single file or may contain a wildcard (`+"`"+`*`+"`"+`) to recursively purge all files under a directory. When only a wildcard is provided, or no path is provided, all cached files will be purged.`, Writer, +To purge specific files, you can use the `+"`"+`--files`+"`"+` flag and supply a path. The path may be for a single file or may contain a wildcard (`+"`"+`*`+"`"+`) to recursively purge all files under a directory. When only a wildcard is provided, or no path is provided, all cached files will be purged. +Examples: + doctl compute cdn flush --files /path/to/assets/* + doctl compute cdn flush --files "/path/to/file.one, /path/to/file.two" + doctl compute cdn flush --files /path/to/file.one --files /path/to/file.two + doctl compute cdn flush --files * `, Writer, aliasOpt("fc")) AddStringSliceFlag(cmdCDNFlushCache, doctl.ArgCDNFiles, "", []string{"*"}, "cdn files") diff --git a/commands/commands_test.go b/commands/commands_test.go index e5413e4ac..0991468ec 100644 --- a/commands/commands_test.go +++ b/commands/commands_test.go @@ -15,7 +15,6 @@ package commands import ( "io" - "sort" "testing" "github.com/digitalocean/doctl" @@ -140,9 +139,7 @@ func assertCommandNames(t *testing.T, cmd *Command, expected ...string) { } } - sort.Strings(expected) - sort.Strings(names) - assert.Equal(t, expected, names) + assert.ElementsMatch(t, expected, names) } type testFn func(c *CmdConfig, tm *tcMocks) diff --git a/commands/displayers/domain.go b/commands/displayers/domain.go index a01ae648a..376ba1148 100644 --- a/commands/displayers/domain.go +++ b/commands/displayers/domain.go @@ -54,6 +54,7 @@ func (d *Domain) KV() []map[string]interface{} { type DomainRecord struct { DomainRecords do.DomainRecords + Short bool } func (dr *DomainRecord) JSON(out io.Writer) error { @@ -61,16 +62,31 @@ func (dr *DomainRecord) JSON(out io.Writer) error { } func (dr *DomainRecord) Cols() []string { - return []string{ + defaultCols := []string{ "ID", "Type", "Name", "Data", "Priority", "Port", "TTL", "Weight", } + + if dr.Short { + return defaultCols + } + + return append(defaultCols, "Flags", "Tag") } func (dr *DomainRecord) ColMap() map[string]string { - return map[string]string{ + defaultColMap := map[string]string{ "ID": "ID", "Type": "Type", "Name": "Name", "Data": "Data", "Priority": "Priority", "Port": "Port", "TTL": "TTL", "Weight": "Weight", } + + if dr.Short { + return defaultColMap + } + + defaultColMap["Flags"] = "Flags" + defaultColMap["Tag"] = "Tag" + + return defaultColMap } func (dr *DomainRecord) KV() []map[string]interface{} { @@ -81,6 +97,7 @@ func (dr *DomainRecord) KV() []map[string]interface{} { "ID": d.ID, "Type": d.Type, "Name": d.Name, "Data": d.Data, "Priority": d.Priority, "Port": d.Port, "TTL": d.TTL, "Weight": d.Weight, + "Flags": d.Flags, "Tag": d.Tag, } out = append(out, o) } diff --git a/commands/domains.go b/commands/domains.go index 978be4796..9759732e9 100644 --- a/commands/domains.go +++ b/commands/domains.go @@ -203,9 +203,7 @@ func RunRecordList(c *CmdConfig) error { return err } - items := &displayers.DomainRecord{DomainRecords: list} - return c.Display(items) - + return displayDomainRecords(c, list...) } // RunRecordCreate creates a domain record. @@ -284,8 +282,7 @@ func RunRecordCreate(c *CmdConfig) error { return err } - item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}} - return c.Display(item) + return displayDomainRecords(c, *r) } @@ -404,6 +401,22 @@ func RunRecordUpdate(c *CmdConfig) error { return err } - item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}} + return displayDomainRecords(c, *r) +} + +func displayDomainRecords(c *CmdConfig, records ...do.DomainRecord) error { + // Check the format flag to determine if the displayer should use the short + // layout of the record display.The short version is used by default, but to format + // output that includes columns not in the short layout we need the full version. + var short = true + format, err := c.Doit.GetStringSlice(c.NS, doctl.ArgFormat) + if err != nil { + return err + } + if len(format) > 0 { + short = false + } + + item := &displayers.DomainRecord{DomainRecords: do.DomainRecords(records), Short: short} return c.Display(item) } diff --git a/commands/functions_test.go b/commands/functions_test.go index eb86d05fd..d989ffacb 100644 --- a/commands/functions_test.go +++ b/commands/functions_test.go @@ -16,7 +16,6 @@ package commands import ( "bytes" "os" - "sort" "strings" "testing" "time" @@ -37,9 +36,7 @@ func TestFunctionsCommand(t *testing.T) { names = append(names, c.Name()) } - sort.Strings(expected) - sort.Strings(names) - assert.Equal(t, expected, names) + assert.ElementsMatch(t, expected, names) } func TestFunctionsGet(t *testing.T) { diff --git a/commands/kubernetes.go b/commands/kubernetes.go index f6cdb31e1..827d4e2ed 100644 --- a/commands/kubernetes.go +++ b/commands/kubernetes.go @@ -1778,11 +1778,11 @@ func parseNodePoolString(nodePool, defaultName, defaultSize string, defaultCount case "size": out.Size = value case "count": - count, err := strconv.ParseInt(value, 10, 64) + count, err := strconv.Atoi(value) if err != nil { return nil, errors.New("Node pool count must be a valid integer.") } - out.Count = int(count) + out.Count = count case "tag": out.Tags = append(out.Tags, value) case "label": @@ -1806,17 +1806,17 @@ func parseNodePoolString(nodePool, defaultName, defaultSize string, defaultCount } out.AutoScale = autoScale case "min-nodes": - minNodes, err := strconv.ParseInt(value, 10, 64) + minNodes, err := strconv.Atoi(value) if err != nil { return nil, errors.New("Node pool min-nodes must be a valid integer.") } - out.MinNodes = int(minNodes) + out.MinNodes = minNodes case "max-nodes": - maxNodes, err := strconv.ParseInt(value, 10, 64) + maxNodes, err := strconv.Atoi(value) if err != nil { return nil, errors.New("Node pool max-nodes must be a valid integer.") } - out.MaxNodes = int(maxNodes) + out.MaxNodes = maxNodes default: return nil, fmt.Errorf("Unsupported node pool argument %q", key) } diff --git a/commands/load_balancers.go b/commands/load_balancers.go index 4f9d616bf..d9bdec8dc 100644 --- a/commands/load_balancers.go +++ b/commands/load_balancers.go @@ -95,7 +95,7 @@ With the load-balancer command, you can list, create, or delete load balancers, cmdLoadBalancerCreate.Flags().MarkHidden(doctl.ArgLoadBalancerType) cmdRecordUpdate := CmdBuilder(cmd, RunLoadBalancerUpdate, "update ", - "Update a load balancer's configuration", `Use this command to update the configuration of a specified load balancer.`, Writer, aliasOpt("u")) + "Update a load balancer's configuration", `Use this command to update the configuration of a specified load balancer. Using all applicable flags, the command should contain a full representation of the load balancer including existing attributes, such as the load balancer's name, region, forwarding rules, and Droplet IDs. Any attribute that is not provided is reset to its default value.`, Writer, aliasOpt("u")) AddStringFlag(cmdRecordUpdate, doctl.ArgLoadBalancerName, "", "", "The load balancer's name") AddStringFlag(cmdRecordUpdate, doctl.ArgRegionSlug, "", "", diff --git a/commands/namespaces_test.go b/commands/namespaces_test.go index 57a9cb0fb..83a0c0620 100644 --- a/commands/namespaces_test.go +++ b/commands/namespaces_test.go @@ -17,7 +17,6 @@ import ( "bytes" "context" "errors" - "sort" "testing" "github.com/digitalocean/doctl/do" @@ -35,9 +34,7 @@ func TestNamespacesCommand(t *testing.T) { names = append(names, c.Name()) } - sort.Strings(expected) - sort.Strings(names) - assert.Equal(t, expected, names) + assert.ElementsMatch(t, expected, names) } func TestNamespacesCreate(t *testing.T) { diff --git a/commands/triggers_test.go b/commands/triggers_test.go index ec9dc13cb..3989a3284 100644 --- a/commands/triggers_test.go +++ b/commands/triggers_test.go @@ -16,7 +16,6 @@ package commands import ( "bytes" "context" - "sort" "testing" "time" @@ -35,9 +34,7 @@ func TestTriggersCommand(t *testing.T) { names = append(names, c.Name()) } - sort.Strings(expected) - sort.Strings(names) - assert.Equal(t, expected, names) + assert.ElementsMatch(t, expected, names) } func TestTriggersGet(t *testing.T) { diff --git a/go.mod b/go.mod index 8ca788b13..406ebf438 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/blang/semver v3.5.1+incompatible github.com/creack/pty v1.1.11 - github.com/digitalocean/godo v1.104.0 + github.com/digitalocean/godo v1.105.0 github.com/docker/cli v24.0.5+incompatible github.com/docker/docker v24.0.5+incompatible github.com/docker/docker-credential-helpers v0.7.0 // indirect diff --git a/go.sum b/go.sum index fb30c68d1..5676ceedb 100644 --- a/go.sum +++ b/go.sum @@ -103,8 +103,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/digitalocean/godo v1.104.0 h1:bIOKADMS9hKn/qqgbquCmCAUIrZ5dkthdyy9MsdPx8E= -github.com/digitalocean/godo v1.104.0/go.mod h1:rUTTOeu4ozN+i3BnyQasMpDyhIVIefANbc4dYe6v6N0= +github.com/digitalocean/godo v1.105.0 h1:bUfWVsyQCYZ7OQLK+p2EBFYWD5BoOgpyq/PMSQHEeMg= +github.com/digitalocean/godo v1.105.0/go.mod h1:R6EmmWI8CT1+fCtjWY9UCB+L5uufuZH13wk3YhxycCs= github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= diff --git a/integration/apps_spec_test.go b/integration/apps_spec_test.go index 2b74fe156..d32cd5441 100644 --- a/integration/apps_spec_test.go +++ b/integration/apps_spec_test.go @@ -197,6 +197,24 @@ var _ = suite("apps/spec/validate", func(t *testing.T, when spec.G, it spec.S) { expect.Equal(expectedOutput, strings.TrimSpace(string(output))) }) + it("schema-only works without auth", func() { + cmd := exec.Command(builtBinaryPath, + "-u", server.URL, + "apps", "spec", "validate", + "--schema-only", "-", + ) + byt, err := json.Marshal(testAppSpec) + expect.NoError(err) + + cmd.Stdin = bytes.NewReader(byt) + + output, err := cmd.CombinedOutput() + expect.NoError(err) + + expectedOutput := "name: test\nservices:\n- github:\n branch: main\n repo: digitalocean/doctl\n name: service" + expect.Equal(expectedOutput, strings.TrimSpace(string(output))) + }) + it("calls proposeapp", func() { cmd := exec.Command(builtBinaryPath, "-t", "some-magic-token", diff --git a/integration/domain_records_list_test.go b/integration/domain_records_list_test.go new file mode 100644 index 000000000..ea7c4bde0 --- /dev/null +++ b/integration/domain_records_list_test.go @@ -0,0 +1,132 @@ +package integration + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/http/httputil" + "os/exec" + "strings" + "testing" + + "github.com/sclevine/spec" + "github.com/stretchr/testify/require" +) + +var _ = suite("compute/domain/records/list", func(t *testing.T, when spec.G, it spec.S) { + var ( + expect *require.Assertions + server *httptest.Server + ) + + it.Before(func() { + expect = require.New(t) + + server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + switch req.URL.Path { + case "/v2/domains/example.com/records": + auth := req.Header.Get("Authorization") + if auth != "Bearer some-magic-token" { + w.WriteHeader(http.StatusUnauthorized) + return + } + + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + w.Write([]byte(domainRecordsListResponse)) + + default: + dump, err := httputil.DumpRequest(req, true) + if err != nil { + t.Fatal("failed to dump request") + } + + t.Fatalf("received unknown request: %s", dump) + } + })) + }) + + when("command is list", func() { + it("lists domain records", func() { + aliases := []string{"list", "ls"} + + for _, alias := range aliases { + cmd := exec.Command(builtBinaryPath, + "-t", "some-magic-token", + "-u", server.URL, + "compute", + "domain", + "records", + alias, + "example.com", + ) + + output, err := cmd.CombinedOutput() + expect.NoError(err, fmt.Sprintf("received error output: %s", output)) + expect.Equal(strings.TrimSpace(domainRecordsListOutput), strings.TrimSpace(string(output))) + } + }) + }) + + when("format flag is passed", func() { + it("flags and tag can be displayed", func() { + aliases := []string{"list", "ls"} + + for _, alias := range aliases { + cmd := exec.Command(builtBinaryPath, + "-t", "some-magic-token", + "-u", server.URL, + "compute", + "domain", + "records", + alias, + "example.com", + "--format", "ID,Type,Name,Flags,Tag", + ) + + output, err := cmd.CombinedOutput() + expect.NoError(err, fmt.Sprintf("received error output: %s", output)) + expect.Equal(strings.TrimSpace(domainRecordsListFormattedOutput), strings.TrimSpace(string(output))) + } + }) + }) +}) + +const ( + domainRecordsListOutput = ` +ID Type Name Data Priority Port TTL Weight +123 A foo 127.0.0.1 0 0 3600 0 +12345 CAA @ letsencrypt.org 0 0 3600 0 +` + + domainRecordsListFormattedOutput = ` +ID Type Name Flags Tag +123 A foo 0 +12345 CAA @ 1 issuewild +` + + domainRecordsListResponse = ` +{ + "domain_records": [ + { + "id": 123, + "type": "A", + "name": "foo", + "data": "127.0.0.1", + "ttl": 3600 + }, + { + "id": 12345, + "type": "CAA", + "name": "@", + "data": "letsencrypt.org", + "flags": 1, + "tag": "issuewild", + "ttl": 3600 + } + ] +} +` +) diff --git a/pkg/listen/listen_test.go b/pkg/listen/listen_test.go index 401a4a3d8..9727be246 100644 --- a/pkg/listen/listen_test.go +++ b/pkg/listen/listen_test.go @@ -23,9 +23,7 @@ var ( func wsHandler(t *testing.T) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { c, err := upgrader.Upgrade(w, r, nil) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) defer c.Close() i := 0 finish := 5 @@ -43,9 +41,7 @@ func wsHandler(t *testing.T) http.HandlerFunc { json.NewEncoder(buf).Encode(data) err = c.WriteMessage(websocket.TextMessage, buf.Bytes()) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) if i == finish { break @@ -60,17 +56,13 @@ func TestListener(t *testing.T) { u := "ws" + strings.TrimPrefix(server.URL, "http") url, err := url.Parse(u) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) buffer := &bytes.Buffer{} listener := NewListener(url, "", nil, buffer) err = listener.Start() - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) want := `{"message":"1\n"} {"message":"2\n"} @@ -87,9 +79,7 @@ func TestListenerWithSchemaFunc(t *testing.T) { u := "ws" + strings.TrimPrefix(server.URL, "http") url, err := url.Parse(u) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) buffer := &bytes.Buffer{} @@ -108,9 +98,7 @@ func TestListenerWithSchemaFunc(t *testing.T) { listener := NewListener(url, "", schemaFunc, buffer) err = listener.Start() - if err != nil { - t.Fatalf("%v", err) - } + require.NoError(t, err) want := `1 2 @@ -127,9 +115,7 @@ func TestListenerStop(t *testing.T) { u := "ws" + strings.TrimPrefix(server.URL, "http") url, err := url.Parse(u) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) buffer := &bytes.Buffer{} diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index 1c292f4c4..74f07c142 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## [v1.105.0] - 2023-10-16 + +- #643 - @dweinshenker - Add support for scalable storage on database clusters +- #641 - @dweinshenker - Fix Kafka Partition Count +- #645 - @gregmankes - APPS-7325 - update app godo spec +- #642 - @dependabot[bot] - Bump golang.org/x/net from 0.7.0 to 0.17.0 + +## [v1.104.1] - 2023-10-10 + +* #640 - @andrewsomething - Drop required Go version to 1.20 and document policy. +* #640 - @andrewsomething - Fix library version. + ## [v1.104.0] - 2023-10-10 - #637 - @mikesmithgh - chore: change uptime alert comparison type diff --git a/vendor/github.com/digitalocean/godo/CONTRIBUTING.md b/vendor/github.com/digitalocean/godo/CONTRIBUTING.md index 23bbe202c..388a5bda5 100644 --- a/vendor/github.com/digitalocean/godo/CONTRIBUTING.md +++ b/vendor/github.com/digitalocean/godo/CONTRIBUTING.md @@ -67,3 +67,11 @@ github-changelog-generator -org digitalocean -repo godo 5. Update the `Tag version` and `Release title` field with the new godo version. Be sure the version has a `v` prefixed in both places. Ex `v1.8.0`. 6. Copy the changelog bullet points to the description field. 7. Publish the release. + +## Go Version Support + +This project follows the support [policy of Go](https://go.dev/doc/devel/release#policy) +as its support policy. The two latest major releases of Go are supported by the project. +[CI workflows](.github/workflows/ci.yml) should test against both supported versions. +[go.mod](./go.mod) should specify the oldest of the supported versions to give +downstream users of godo flexibility. diff --git a/vendor/github.com/digitalocean/godo/apps.gen.go b/vendor/github.com/digitalocean/godo/apps.gen.go index a3c89faee..8b01dbb7b 100644 --- a/vendor/github.com/digitalocean/godo/apps.gen.go +++ b/vendor/github.com/digitalocean/godo/apps.gen.go @@ -1,4 +1,5 @@ -// Code generated automatically. DO NOT EDIT. +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. +// $ bundle -pkg godo -prefix ./dev/dist/godo package godo @@ -68,7 +69,7 @@ const ( // AppAlertSlackWebhook Configuration of a Slack alerting destination. type AppAlertSlackWebhook struct { - // URL for the Slack webhook. The value will be encrypted on the app spec after it is submitted. + // URL for the Slack webhook. URL string `json:"url,omitempty"` // Name of the Slack channel. Channel string `json:"channel,omitempty"` @@ -120,7 +121,7 @@ const ( AppAlertSpecOperator_LessThan AppAlertSpecOperator = "LESS_THAN" ) -// AppAlertSpecRule - CPU_UTILIZATION: Represents CPU for a given container instance. Only applicable at the component level. - MEM_UTILIZATION: Represents RAM for a given container instance. Only applicable at the component level. - RESTART_COUNT: Represents restart count for a given container instance. Only applicable at the component level. - DEPLOYMENT_FAILED: Represents whether a deployment has failed. Only applicable at the app level. - DEPLOYMENT_LIVE: Represents whether a deployment has succeeded. Only applicable at the app level. - DOMAIN_FAILED: Represents whether a domain configuration has failed. Only applicable at the app level. - DOMAIN_LIVE: Represents whether a domain configuration has succeeded. Only applicable at the app level. - FUNCTIONS_ACTIVATION_COUNT: Represents an activation count for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_DURATION_MS: Represents the average duration for function runtimes. Only applicable to functions components. - FUNCTIONS_ERROR_RATE_PER_MINUTE: Represents an error rate per minute for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_WAIT_TIME_MS: Represents the average wait time for functions. Only applicable to functions components. - FUNCTIONS_ERROR_COUNT: Represents an error count for a given functions instance. Only applicable to functions components. - FUNCTIONS_GB_RATE_PER_SECOND: Represents the rate of memory consumption (GB x seconds) for functions. Only applicable to functions components. +// AppAlertSpecRule - CPU_UTILIZATION: Represents CPU for a given container instance. Only applicable at the component level. - MEM_UTILIZATION: Represents RAM for a given container instance. Only applicable at the component level. - RESTART_COUNT: Represents restart count for a given container instance. Only applicable at the component level. - DEPLOYMENT_FAILED: Represents whether a deployment has failed. Only applicable at the app level. - DEPLOYMENT_LIVE: Represents whether a deployment has succeeded. Only applicable at the app level. - DEPLOYMENT_STARTED: Represents whether a deployment has started. Only applicable at the app level. - DEPLOYMENT_CANCELED: Represents whether a deployment has been canceled. Only applicable at the app level. - DOMAIN_FAILED: Represents whether a domain configuration has failed. Only applicable at the app level. - DOMAIN_LIVE: Represents whether a domain configuration has succeeded. Only applicable at the app level. - FUNCTIONS_ACTIVATION_COUNT: Represents an activation count for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_DURATION_MS: Represents the average duration for function runtimes. Only applicable to functions components. - FUNCTIONS_ERROR_RATE_PER_MINUTE: Represents an error rate per minute for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_WAIT_TIME_MS: Represents the average wait time for functions. Only applicable to functions components. - FUNCTIONS_ERROR_COUNT: Represents an error count for a given functions instance. Only applicable to functions components. - FUNCTIONS_GB_RATE_PER_SECOND: Represents the rate of memory consumption (GB x seconds) for functions. Only applicable to functions components. type AppAlertSpecRule string // List of AppAlertSpecRule @@ -131,6 +132,8 @@ const ( AppAlertSpecRule_RestartCount AppAlertSpecRule = "RESTART_COUNT" AppAlertSpecRule_DeploymentFailed AppAlertSpecRule = "DEPLOYMENT_FAILED" AppAlertSpecRule_DeploymentLive AppAlertSpecRule = "DEPLOYMENT_LIVE" + AppAlertSpecRule_DeploymentStarted AppAlertSpecRule = "DEPLOYMENT_STARTED" + AppAlertSpecRule_DeploymentCanceled AppAlertSpecRule = "DEPLOYMENT_CANCELED" AppAlertSpecRule_DomainFailed AppAlertSpecRule = "DOMAIN_FAILED" AppAlertSpecRule_DomainLive AppAlertSpecRule = "DOMAIN_LIVE" AppAlertSpecRule_FunctionsActivationCount AppAlertSpecRule = "FUNCTIONS_ACTIVATION_COUNT" @@ -153,6 +156,26 @@ const ( AppAlertSpecWindow_OneHour AppAlertSpecWindow = "ONE_HOUR" ) +// AppAutoscalingSpec struct for AppAutoscalingSpec +type AppAutoscalingSpec struct { + // The minimum amount of instances for this component. + MinInstanceCount int64 `json:"min_instance_count,omitempty"` + // The maximum amount of instances for this component. + MaxInstanceCount int64 `json:"max_instance_count,omitempty"` + Metrics *AppAutoscalingSpecMetrics `json:"metrics,omitempty"` +} + +// AppAutoscalingSpecMetricCPU struct for AppAutoscalingSpecMetricCPU +type AppAutoscalingSpecMetricCPU struct { + // The average target CPU utilization for the component. + Percent int64 `json:"percent,omitempty"` +} + +// AppAutoscalingSpecMetrics struct for AppAutoscalingSpecMetrics +type AppAutoscalingSpecMetrics struct { + CPU *AppAutoscalingSpecMetricCPU `json:"cpu,omitempty"` +} + // AppBuildConfig struct for AppBuildConfig type AppBuildConfig struct { CNBVersioning *AppBuildConfigCNBVersioning `json:"cnb_versioning,omitempty"` @@ -232,7 +255,7 @@ type AppFunctionsSpec struct { SourceDir string `json:"source_dir,omitempty"` // A list of environment variables made available to the component. Envs []*AppVariableDefinition `json:"envs,omitempty"` - // A list of HTTP routes that should be routed to this component. + // (Deprecated) A list of HTTP routes that should be routed to this component. Routes []*AppRouteSpec `json:"routes,omitempty"` // A list of configured alerts the user has enabled. Alerts []*AppAlertSpec `json:"alerts,omitempty"` @@ -291,7 +314,7 @@ type AppIngressSpecRuleRoutingRedirect struct { Port int64 `json:"port,omitempty"` // The scheme to redirect to. Supported values are `http` or `https`. Default: `https`. Scheme string `json:"scheme,omitempty"` - // The redirect code to use. Defaults to `302`. Supported values are 300, 301, 302, 303, 304, 305, 307, 308. + // The redirect code to use. Defaults to `302`. Supported values are 300, 301, 302, 303, 304, 307, 308. RedirectCode int64 `json:"redirect_code,omitempty"` } @@ -384,9 +407,9 @@ type AppLogDestinationSpecPapertrail struct { // AppRouteSpec struct for AppRouteSpec type AppRouteSpec struct { - // An HTTP path prefix. Paths must start with / and must be unique across all components within an app. + // (Deprecated) An HTTP path prefix. Paths must start with / and must be unique across all components within an app. Path string `json:"path,omitempty"` - // An optional flag to preserve the path that is forwarded to the backend service. By default, the HTTP request path will be trimmed from the left when forwarded to the component. For example, a component with `path=/api` will have requests to `/api/list` trimmed to `/list`. If this value is `true`, the path will remain `/api/list`. Note: this is not applicable for Functions Components. + // (Deprecated) An optional flag to preserve the path that is forwarded to the backend service. By default, the HTTP request path will be trimmed from the left when forwarded to the component. For example, a component with `path=/api` will have requests to `/api/list` trimmed to `/list`. If this value is `true`, the path will remain `/api/list`. Note: this is not applicable for Functions Components. PreservePathPrefix bool `json:"preserve_path_prefix,omitempty"` } @@ -411,10 +434,12 @@ type AppServiceSpec struct { // A list of environment variables made available to the component. Envs []*AppVariableDefinition `json:"envs,omitempty"` InstanceSizeSlug string `json:"instance_size_slug,omitempty"` - InstanceCount int64 `json:"instance_count,omitempty"` + // The amount of instances that this component should be scaled to. + InstanceCount int64 `json:"instance_count,omitempty"` + Autoscaling *AppAutoscalingSpec `json:"autoscaling,omitempty"` // The internal port on which this service's run command will listen. Default: 8080 If there is not an environment variable with the name `PORT`, one will be automatically added with its value set to the value of this field. HTTPPort int64 `json:"http_port,omitempty"` - // A list of HTTP routes that should be routed to this component. + // (Deprecated) A list of HTTP routes that should be routed to this component. Routes []*AppRouteSpec `json:"routes,omitempty"` HealthCheck *AppServiceSpecHealthCheck `json:"health_check,omitempty"` CORS *AppCORSPolicy `json:"cors,omitempty"` @@ -495,7 +520,7 @@ type AppStaticSiteSpec struct { ErrorDocument string `json:"error_document,omitempty"` // A list of environment variables made available to the component. Envs []*AppVariableDefinition `json:"envs,omitempty"` - // A list of HTTP routes that should be routed to this component. + // (Deprecated) A list of HTTP routes that should be routed to this component. Routes []*AppRouteSpec `json:"routes,omitempty"` CORS *AppCORSPolicy `json:"cors,omitempty"` // The name of the document to use as the fallback for any requests to documents that are not found when serving this static site. Only 1 of `catchall_document` or `error_document` can be set. @@ -533,8 +558,9 @@ type AppWorkerSpec struct { // A list of environment variables made available to the component. Envs []*AppVariableDefinition `json:"envs,omitempty"` // The instance size to use for this component. - InstanceSizeSlug string `json:"instance_size_slug,omitempty"` - InstanceCount int64 `json:"instance_count,omitempty"` + InstanceSizeSlug string `json:"instance_size_slug,omitempty"` + InstanceCount int64 `json:"instance_count,omitempty"` + Autoscaling *AppAutoscalingSpec `json:"autoscaling,omitempty"` // A list of configured alerts which apply to the component. Alerts []*AppAlertSpec `json:"alerts,omitempty"` // A list of configured log forwarding destinations. @@ -559,6 +585,12 @@ type Buildpack struct { DocsLink string `json:"docs_link,omitempty"` } +// DeploymentCauseDetailsAutoscalerAction struct for DeploymentCauseDetailsAutoscalerAction +type DeploymentCauseDetailsAutoscalerAction struct { + // Marker for the deployment being autoscaled. Necessary because the generation tooling can't handle empty messages. + Autoscaled bool `json:"autoscaled,omitempty"` +} + // DeploymentCauseDetailsDigitalOceanUser struct for DeploymentCauseDetailsDigitalOceanUser type DeploymentCauseDetailsDigitalOceanUser struct { UUID string `json:"uuid,omitempty"` @@ -651,10 +683,11 @@ type DeploymentCauseDetails struct { GitPush *DeploymentCauseDetailsGitPush `json:"git_push,omitempty"` DOCRPush *DeploymentCauseDetailsDOCRPush `json:"docr_push,omitempty"` Internal bool `json:"internal,omitempty"` + Autoscaler *DeploymentCauseDetailsAutoscalerAction `json:"autoscaler,omitempty"` Type DeploymentCauseDetailsType `json:"type,omitempty"` } -// DeploymentCauseDetailsType - MANUAL: A deployment that was manually created - DEPLOY_ON_PUSH: A deployment that was automatically created by a Deploy on Push hook - MAINTENANCE: A deployment created for App Platform maintenance - MANUAL_ROLLBACK: A rollback deployment that was manually created - AUTO_ROLLBACK: An automatic rollback deployment created as a result of a previous deployment failing - UPDATE_DATABASE_TRUSTED_SOURCES: A deployment that was created due to an update in database trusted sources. +// DeploymentCauseDetailsType - MANUAL: A deployment that was manually created - DEPLOY_ON_PUSH: A deployment that was automatically created by a Deploy on Push hook - MAINTENANCE: A deployment created for App Platform maintenance - MANUAL_ROLLBACK: A rollback deployment that was manually created - AUTO_ROLLBACK: An automatic rollback deployment created as a result of a previous deployment failing - UPDATE_DATABASE_TRUSTED_SOURCES: A deployment that was created due to an update in database trusted sources. - AUTOSCALED: A deployment that was created due to an autoscaler update. type DeploymentCauseDetailsType string // List of DeploymentCauseDetailsType @@ -666,6 +699,7 @@ const ( DeploymentCauseDetailsType_ManualRollback DeploymentCauseDetailsType = "MANUAL_ROLLBACK" DeploymentCauseDetailsType_AutoRollback DeploymentCauseDetailsType = "AUTO_ROLLBACK" DeploymentCauseDetailsType_UpdateDatabaseTrustedSources DeploymentCauseDetailsType = "UPDATE_DATABASE_TRUSTED_SOURCES" + DeploymentCauseDetailsType_Autoscaled DeploymentCauseDetailsType = "AUTOSCALED" ) // DeploymentFunctions struct for DeploymentFunctions diff --git a/vendor/github.com/digitalocean/godo/apps_accessors.go b/vendor/github.com/digitalocean/godo/apps_accessors.go index 85a34638e..486c75973 100644 --- a/vendor/github.com/digitalocean/godo/apps_accessors.go +++ b/vendor/github.com/digitalocean/godo/apps_accessors.go @@ -1,4 +1,11 @@ -// Code generated automatically. DO NOT EDIT. +// Copyright 2017 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by gen-accessors; DO NOT EDIT. +// Instead, please run "go generate ./..." as described here: +// https://github.com/google/go-github/blob/master/CONTRIBUTING.md#submitting-a-patch package godo @@ -350,6 +357,46 @@ func (a *AppAlertSpec) GetWindow() AppAlertSpecWindow { return a.Window } +// GetMaxInstanceCount returns the MaxInstanceCount field. +func (a *AppAutoscalingSpec) GetMaxInstanceCount() int64 { + if a == nil { + return 0 + } + return a.MaxInstanceCount +} + +// GetMetrics returns the Metrics field. +func (a *AppAutoscalingSpec) GetMetrics() *AppAutoscalingSpecMetrics { + if a == nil { + return nil + } + return a.Metrics +} + +// GetMinInstanceCount returns the MinInstanceCount field. +func (a *AppAutoscalingSpec) GetMinInstanceCount() int64 { + if a == nil { + return 0 + } + return a.MinInstanceCount +} + +// GetPercent returns the Percent field. +func (a *AppAutoscalingSpecMetricCPU) GetPercent() int64 { + if a == nil { + return 0 + } + return a.Percent +} + +// GetCPU returns the CPU field. +func (a *AppAutoscalingSpecMetrics) GetCPU() *AppAutoscalingSpecMetricCPU { + if a == nil { + return nil + } + return a.CPU +} + // GetCNBVersioning returns the CNBVersioning field. func (a *AppBuildConfig) GetCNBVersioning() *AppBuildConfigCNBVersioning { if a == nil { @@ -1438,6 +1485,14 @@ func (a *AppServiceSpec) GetAlerts() []*AppAlertSpec { return a.Alerts } +// GetAutoscaling returns the Autoscaling field. +func (a *AppServiceSpec) GetAutoscaling() *AppAutoscalingSpec { + if a == nil { + return nil + } + return a.Autoscaling +} + // GetBuildCommand returns the BuildCommand field. func (a *AppServiceSpec) GetBuildCommand() string { if a == nil { @@ -1974,6 +2029,14 @@ func (a *AppWorkerSpec) GetAlerts() []*AppAlertSpec { return a.Alerts } +// GetAutoscaling returns the Autoscaling field. +func (a *AppWorkerSpec) GetAutoscaling() *AppAutoscalingSpec { + if a == nil { + return nil + } + return a.Autoscaling +} + // GetBuildCommand returns the BuildCommand field. func (a *AppWorkerSpec) GetBuildCommand() string { if a == nil { @@ -2294,6 +2357,14 @@ func (d *Deployment) GetWorkers() []*DeploymentWorker { return d.Workers } +// GetAutoscaler returns the Autoscaler field. +func (d *DeploymentCauseDetails) GetAutoscaler() *DeploymentCauseDetailsAutoscalerAction { + if d == nil { + return nil + } + return d.Autoscaler +} + // GetDigitalOceanUserAction returns the DigitalOceanUserAction field. func (d *DeploymentCauseDetails) GetDigitalOceanUserAction() *DeploymentCauseDetailsDigitalOceanUserAction { if d == nil { @@ -2334,6 +2405,14 @@ func (d *DeploymentCauseDetails) GetType() DeploymentCauseDetailsType { return d.Type } +// GetAutoscaled returns the Autoscaled field. +func (d *DeploymentCauseDetailsAutoscalerAction) GetAutoscaled() bool { + if d == nil { + return false + } + return d.Autoscaled +} + // GetEmail returns the Email field. func (d *DeploymentCauseDetailsDigitalOceanUser) GetEmail() string { if d == nil { diff --git a/vendor/github.com/digitalocean/godo/databases.go b/vendor/github.com/digitalocean/godo/databases.go index fe0bac78c..4b3749978 100644 --- a/vendor/github.com/digitalocean/godo/databases.go +++ b/vendor/github.com/digitalocean/godo/databases.go @@ -186,6 +186,7 @@ type Database struct { PrivateNetworkUUID string `json:"private_network_uuid,omitempty"` Tags []string `json:"tags,omitempty"` ProjectID string `json:"project_id,omitempty"` + StorageSizeMib uint64 `json:"storage_size_mib,omitempty"` } // DatabaseCA represents a database ca. @@ -267,12 +268,14 @@ type DatabaseCreateRequest struct { Tags []string `json:"tags,omitempty"` BackupRestore *DatabaseBackupRestore `json:"backup_restore,omitempty"` ProjectID string `json:"project_id"` + StorageSizeMib uint64 `json:"storage_size_mib,omitempty"` } // DatabaseResizeRequest can be used to initiate a database resize operation. type DatabaseResizeRequest struct { - SizeSlug string `json:"size,omitempty"` - NumNodes int `json:"num_nodes,omitempty"` + SizeSlug string `json:"size,omitempty"` + NumNodes int `json:"num_nodes,omitempty"` + StorageSizeMib uint64 `json:"storage_size_mib,omitempty"` } // DatabaseMigrateRequest can be used to initiate a database migrate operation. @@ -297,11 +300,26 @@ type DatabaseDB struct { // DatabaseTopic represents a Kafka topic type DatabaseTopic struct { - Name string `json:"name"` - PartitionCount *uint32 `json:"partition_count,omitempty"` - ReplicationFactor *uint32 `json:"replication_factor,omitempty"` - State string `json:"state,omitempty"` - Config *TopicConfig `json:"config,omitempty"` + Name string `json:"name"` + Partitions []*TopicPartition `json:"partitions,omitempty"` + ReplicationFactor *uint32 `json:"replication_factor,omitempty"` + State string `json:"state,omitempty"` + Config *TopicConfig `json:"config,omitempty"` +} + +// TopicPartition represents the state of a Kafka topic partition +type TopicPartition struct { + EarliestOffset uint64 `json:"earliest_offset,omitempty"` + InSyncReplicas uint32 `json:"in_sync_replicas,omitempty"` + Id uint32 `json:"id,omitempty"` + Size uint64 `json:"size,omitempty"` + ConsumerGroups []*TopicConsumerGroup `json:"consumer_groups,omitempty"` +} + +// TopicConsumerGroup represents a consumer group for a particular Kafka topic +type TopicConsumerGroup struct { + Name string `json:"name,omitempty"` + Offset uint64 `json:"offset,omitempty"` } // TopicConfig represents all configurable options for a Kafka topic @@ -342,7 +360,9 @@ type DatabaseCreateTopicRequest struct { // DatabaseUpdateTopicRequest ... type DatabaseUpdateTopicRequest struct { - Topic *DatabaseTopic `json:"topic"` // note: `name` field in Topic unused on update + PartitionCount *uint32 `json:"partition_count,omitempty"` + ReplicationFactor *uint32 `json:"replication_factor,omitempty"` + Config *TopicConfig `json:"config,omitempty"` } // DatabaseReplica represents a read-only replica of a particular database diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index 0177ed3a5..e3f2ec2c5 100644 --- a/vendor/github.com/digitalocean/godo/godo.go +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -21,7 +21,7 @@ import ( ) const ( - libraryVersion = "1.103.0" + libraryVersion = "1.105.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" diff --git a/vendor/modules.txt b/vendor/modules.txt index 07e8da623..6c960ca1d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -55,8 +55,8 @@ github.com/creack/pty # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/digitalocean/godo v1.104.0 -## explicit; go 1.21 +# github.com/digitalocean/godo v1.105.0 +## explicit; go 1.20 github.com/digitalocean/godo github.com/digitalocean/godo/metrics github.com/digitalocean/godo/util