diff --git a/digitalocean/datasource_digitalocean_loadbalancer.go b/digitalocean/datasource_digitalocean_loadbalancer.go index 088877300..bf45b83bd 100644 --- a/digitalocean/datasource_digitalocean_loadbalancer.go +++ b/digitalocean/datasource_digitalocean_loadbalancer.go @@ -215,6 +215,17 @@ func dataSourceDigitalOceanLoadbalancer() *schema.Resource { Computed: true, Description: "UUID of the VPC in which the load balancer is located", }, + "http_idle_timeout_seconds": { + Type: schema.TypeInt, + Computed: true, + Description: " Specifies the idle timeout for HTTPS connections on the load balancer.", + }, + + "project_id": { + Type: schema.TypeString, + Computed: true, + Description: "The ID of the project that the load balancer is associated with.", + }, }, } } @@ -289,6 +300,8 @@ func dataSourceDigitalOceanLoadbalancerRead(ctx context.Context, d *schema.Resou d.Set("enable_backend_keepalive", foundLoadbalancer.EnableBackendKeepalive) d.Set("disable_lets_encrypt_dns_records", foundLoadbalancer.DisableLetsEncryptDNSRecords) d.Set("vpc_uuid", foundLoadbalancer.VPCUUID) + d.Set("http_idle_timeout_seconds", foundLoadbalancer.HTTPIdleTimeoutSeconds) + d.Set("project_id", foundLoadbalancer.ProjectID) if err := d.Set("droplet_ids", flattenDropletIds(foundLoadbalancer.DropletIDs)); err != nil { return diag.Errorf("[DEBUG] Error setting Load Balancer droplet_ids - error: %#v", err) diff --git a/digitalocean/datasource_digitalocean_loadbalancer_test.go b/digitalocean/datasource_digitalocean_loadbalancer_test.go index 70e491cb2..1795ca85f 100644 --- a/digitalocean/datasource_digitalocean_loadbalancer_test.go +++ b/digitalocean/datasource_digitalocean_loadbalancer_test.go @@ -70,6 +70,10 @@ data "digitalocean_loadbalancer" "foobar" { "data.digitalocean_loadbalancer.foobar", "enable_backend_keepalive", "false"), resource.TestCheckResourceAttr( "data.digitalocean_loadbalancer.foobar", "disable_lets_encrypt_dns_records", "false"), + resource.TestCheckResourceAttrSet( + "data.digitalocean_loadbalancer.foobar", "project_id"), + resource.TestCheckResourceAttrSet( + "data.digitalocean_loadbalancer.foobar", "http_idle_timeout_seconds"), ), }, }, diff --git a/digitalocean/resource_digitalocean_loadbalancer.go b/digitalocean/resource_digitalocean_loadbalancer.go index 857b7a6af..17f178887 100644 --- a/digitalocean/resource_digitalocean_loadbalancer.go +++ b/digitalocean/resource_digitalocean_loadbalancer.go @@ -365,6 +365,18 @@ func resourceDigitalOceanLoadBalancerV0() *schema.Resource { Type: schema.TypeString, Computed: true, }, + + "http_idle_timeout_seconds": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + + "project_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, }, } } @@ -413,6 +425,7 @@ func buildLoadBalancerRequest(client *godo.Client, d *schema.ResourceData) (*god EnableBackendKeepalive: d.Get("enable_backend_keepalive").(bool), ForwardingRules: forwardingRules, DisableLetsEncryptDNSRecords: godo.Bool(d.Get("disable_lets_encrypt_dns_records").(bool)), + ProjectID: d.Get("project_id").(string), } sizeUnit, ok := d.GetOk("size_unit") if ok { @@ -421,6 +434,12 @@ func buildLoadBalancerRequest(client *godo.Client, d *schema.ResourceData) (*god opts.SizeSlug = d.Get("size").(string) } + idleTimeout, ok := d.GetOk("http_idle_timeout_seconds") + if ok { + t := uint64(idleTimeout.(int)) + opts.HTTPIdleTimeoutSeconds = &t + } + if v, ok := d.GetOk("droplet_tag"); ok { opts.Tag = v.(string) } else if v, ok := d.GetOk("droplet_ids"); ok { @@ -505,6 +524,9 @@ func resourceDigitalOceanLoadbalancerRead(ctx context.Context, d *schema.Resourc d.Set("enable_backend_keepalive", loadbalancer.EnableBackendKeepalive) d.Set("droplet_tag", loadbalancer.Tag) d.Set("vpc_uuid", loadbalancer.VPCUUID) + d.Set("http_idle_timeout_seconds", loadbalancer.HTTPIdleTimeoutSeconds) + d.Set("project_id", loadbalancer.ProjectID) + if loadbalancer.SizeUnit > 0 { d.Set("size_unit", loadbalancer.SizeUnit) } else { diff --git a/digitalocean/resource_digitalocean_loadbalancer_test.go b/digitalocean/resource_digitalocean_loadbalancer_test.go index accfdef28..4a8f85f79 100644 --- a/digitalocean/resource_digitalocean_loadbalancer_test.go +++ b/digitalocean/resource_digitalocean_loadbalancer_test.go @@ -7,6 +7,7 @@ import ( "regexp" "strings" "testing" + "time" "github.com/digitalocean/godo" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -100,6 +101,10 @@ func TestAccDigitalOceanLoadbalancer_Basic(t *testing.T) { "digitalocean_loadbalancer.foobar", "enable_backend_keepalive", "true"), resource.TestCheckResourceAttr( "digitalocean_loadbalancer.foobar", "disable_lets_encrypt_dns_records", "false"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.foobar", "http_idle_timeout_seconds", "90"), + resource.TestCheckResourceAttrSet( + "digitalocean_loadbalancer.foobar", "project_id"), ), }, }, @@ -152,6 +157,10 @@ func TestAccDigitalOceanLoadbalancer_Updated(t *testing.T) { "digitalocean_loadbalancer.foobar", "enable_backend_keepalive", "true"), resource.TestCheckResourceAttr( "digitalocean_loadbalancer.foobar", "disable_lets_encrypt_dns_records", "false"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.foobar", "http_idle_timeout_seconds", "90"), + resource.TestCheckResourceAttrSet( + "digitalocean_loadbalancer.foobar", "project_id"), ), }, { @@ -191,6 +200,10 @@ func TestAccDigitalOceanLoadbalancer_Updated(t *testing.T) { "digitalocean_loadbalancer.foobar", "enable_backend_keepalive", "false"), resource.TestCheckResourceAttr( "digitalocean_loadbalancer.foobar", "disable_lets_encrypt_dns_records", "true"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.foobar", "http_idle_timeout_seconds", "120"), + resource.TestCheckResourceAttrSet( + "digitalocean_loadbalancer.foobar", "project_id"), ), }, }, @@ -291,6 +304,75 @@ func TestAccDigitalOceanLoadbalancer_minimal(t *testing.T) { "digitalocean_loadbalancer.foobar", "enable_proxy_protocol", "false"), resource.TestCheckResourceAttr( "digitalocean_loadbalancer.foobar", "enable_backend_keepalive", "false"), + resource.TestCheckResourceAttrSet( + "digitalocean_loadbalancer.foobar", "project_id"), + ), + }, + }, + }) +} + +func TestAccDigitalOceanLoadbalancer_NonDefaultProject(t *testing.T) { + var loadbalancer godo.LoadBalancer + lbName := randomTestName() + projectName := randomTestName() + + projectConfig := ` + +resource "digitalocean_project" "test" { + name = "%s" +} +` + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckDigitalOceanLoadbalancerDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(projectConfig, projectName) + testAccCheckDigitalOceanLoadbalancerConfig_NonDefaultProject(projectName, lbName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDigitalOceanLoadbalancerExists("digitalocean_loadbalancer.test", &loadbalancer), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "name", lbName), + resource.TestCheckResourceAttrPair( + "digitalocean_loadbalancer.test", "project_id", "digitalocean_project.test", "id"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "region", "nyc3"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "size_unit", "1"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "forwarding_rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs( + "digitalocean_loadbalancer.test", + "forwarding_rule.*", + map[string]string{ + "entry_port": "80", + "entry_protocol": "http", + "target_port": "80", + "target_protocol": "http", + "tls_passthrough": "false", + }, + ), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "healthcheck.#", "1"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "healthcheck.0.port", "80"), + resource.TestCheckResourceAttr( + "digitalocean_loadbalancer.test", "healthcheck.0.protocol", "http"), + ), + }, + { + // The load balancer must be destroyed before the project which + // discovers that asynchronously. + Config: fmt.Sprintf(projectConfig, projectName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckFunc( + func(s *terraform.State) error { + time.Sleep(10 * time.Second) + return nil + }, + ), ), }, }, @@ -409,6 +491,7 @@ func TestAccDigitalOceanLoadbalancer_sslTermination(t *testing.T) { var loadbalancer godo.LoadBalancer rInt := acctest.RandInt() privateKeyMaterial, leafCertMaterial, certChainMaterial := generateTestCertMaterial(t) + certName := randomTestName() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -417,7 +500,7 @@ func TestAccDigitalOceanLoadbalancer_sslTermination(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccCheckDigitalOceanLoadbalancerConfig_sslTermination( - "tf-acc-test-certificate-01", rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial, "certificate_id"), + certName, rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial, "certificate_id"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckDigitalOceanLoadbalancerExists("digitalocean_loadbalancer.foobar", &loadbalancer), resource.TestCheckResourceAttr( @@ -436,7 +519,7 @@ func TestAccDigitalOceanLoadbalancer_sslTermination(t *testing.T) { "entry_protocol": "https", "target_port": "80", "target_protocol": "http", - "certificate_name": "tf-acc-test-certificate-01", + "certificate_name": certName, "tls_passthrough": "false", }, ), @@ -454,6 +537,7 @@ func TestAccDigitalOceanLoadbalancer_sslCertByName(t *testing.T) { var loadbalancer godo.LoadBalancer rInt := acctest.RandInt() privateKeyMaterial, leafCertMaterial, certChainMaterial := generateTestCertMaterial(t) + certName := randomTestName() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -462,7 +546,7 @@ func TestAccDigitalOceanLoadbalancer_sslCertByName(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccCheckDigitalOceanLoadbalancerConfig_sslTermination( - "tf-acc-test-certificate-02", rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial, "certificate_name"), + certName, rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial, "certificate_name"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckDigitalOceanLoadbalancerExists("digitalocean_loadbalancer.foobar", &loadbalancer), resource.TestCheckResourceAttr( @@ -479,7 +563,7 @@ func TestAccDigitalOceanLoadbalancer_sslCertByName(t *testing.T) { "entry_protocol": "https", "target_port": "80", "target_protocol": "http", - "certificate_name": "tf-acc-test-certificate-02", + "certificate_name": certName, "tls_passthrough": "false", }, ), @@ -728,6 +812,7 @@ resource "digitalocean_loadbalancer" "foobar" { enable_proxy_protocol = true enable_backend_keepalive = true + http_idle_timeout_seconds = 90 droplet_ids = [digitalocean_droplet.foobar.id] }`, rInt, rInt) @@ -769,6 +854,7 @@ resource "digitalocean_loadbalancer" "foobar" { enable_proxy_protocol = false enable_backend_keepalive = false disable_lets_encrypt_dns_records = true + http_idle_timeout_seconds = 120 droplet_ids = [digitalocean_droplet.foobar.id, digitalocean_droplet.foo.id] }`, rInt, rInt, rInt) @@ -821,9 +907,9 @@ resource "digitalocean_droplet" "foobar" { } resource "digitalocean_loadbalancer" "foobar" { - name = "loadbalancer-%d" - region = "nyc3" - size = "lb-small" + name = "loadbalancer-%d" + region = "nyc3" + size_unit = 1 forwarding_rule { entry_port = 80 @@ -837,6 +923,30 @@ resource "digitalocean_loadbalancer" "foobar" { }`, rInt, rInt) } +func testAccCheckDigitalOceanLoadbalancerConfig_NonDefaultProject(projectName, lbName string) string { + return fmt.Sprintf(` +resource "digitalocean_tag" "test" { + name = "%s" +} + +resource "digitalocean_loadbalancer" "test" { + name = "%s" + region = "nyc3" + size = "lb-small" + project_id = digitalocean_project.test.id + + forwarding_rule { + entry_port = 80 + entry_protocol = "http" + + target_port = 80 + target_protocol = "http" + } + + droplet_tag = digitalocean_tag.test.name +}`, projectName, lbName) +} + func testAccCheckDigitalOceanLoadbalancerConfig_minimalUDP(rInt int) string { return fmt.Sprintf(` resource "digitalocean_droplet" "foobar" { diff --git a/docs/resources/loadbalancer.md b/docs/resources/loadbalancer.md index 5b17bc026..0236e58a8 100644 --- a/docs/resources/loadbalancer.md +++ b/docs/resources/loadbalancer.md @@ -109,7 +109,9 @@ Default value is `false`. Protocol should be used to pass information from connecting client requests to the backend service. Default value is `false`. * `enable_backend_keepalive` - (Optional) A boolean value indicating whether HTTP keepalive connections are maintained to target Droplets. Default value is `false`. +* `http_idle_timeout_seconds` - (Optional) Specifies the idle timeout for HTTPS connections on the load balancer in seconds. * `disable_lets_encrypt_dns_records` - (Optional) A boolean value indicating whether to disable automatic DNS record creation for Let's Encrypt certificates that are added to the load balancer. Default value is `false`. +* `project_id` - (Optional) The ID of the project that the load balancer is associated with. If no ID is provided at creation, the load balancer associates with the user's default project. * `vpc_uuid` - (Optional) The ID of the VPC where the load balancer will be located. * `droplet_ids` (Optional) - A list of the IDs of each droplet to be attached to the Load Balancer. * `droplet_tag` (Optional) - The name of a Droplet tag corresponding to Droplets to be assigned to the Load Balancer. @@ -130,7 +132,6 @@ the backend service. Default value is `false`. * `cookie_name` - (Optional) The name to be used for the cookie sent to the client. This attribute is required when using `cookies` for the sticky sessions type. * `cookie_ttl_seconds` - (Optional) The number of seconds until the cookie set by the Load Balancer expires. This attribute is required when using `cookies` for the sticky sessions type. - `healthcheck` supports the following: * `protocol` - (Required) The protocol used for health checks sent to the backend Droplets. The possible values are `http`, `https` or `tcp`. diff --git a/go.mod b/go.mod index 7cf2952e3..4d119aa98 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/digitalocean/terraform-provider-digitalocean require ( github.com/aws/aws-sdk-go v1.42.18 - github.com/digitalocean/godo v1.87.0 + github.com/digitalocean/godo v1.90.0 github.com/hashicorp/awspolicyequivalence v1.5.0 github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/go-version v1.3.0 diff --git a/go.sum b/go.sum index 63d2a35d0..fdcd21565 100644 --- a/go.sum +++ b/go.sum @@ -81,8 +81,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/digitalocean/godo v1.87.0 h1:U6jyE7Ga+6NkAa8pnpgrKk0lEU1e3Fc/kWipC9tARds= -github.com/digitalocean/godo v1.87.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA= +github.com/digitalocean/godo v1.90.0 h1:mnluEWL5eXFNYnLzHFuwsPuXZsWmzGoMNYSLZi9QPgc= +github.com/digitalocean/godo v1.90.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index a94da0e18..d9cf04f70 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,24 @@ # Change Log +## [v1.90.0] - 2022-11-16 + +- #571 - @kraai - Add WaitForAvailable +- #579 - @bentranter - Deprecate old pointer helpers, use generic one +- #580 - @StephenVarela - LBAAS Fixup default http idle timeout behaviour +- #578 - @StephenVarela - LBAAS-2430 Add support for HTTP idle timeout seconds +- #577 - @ddebarros - Functions api support + +## [v1.89.0] - 2022-11-02 + +- #575 - @ghostlandr - apps: add option to get projects data from Apps List endpoint + +## [v1.88.0] - 2022-10-31 + +- #573 - @kamaln7 - apps: add ListBuildpacks, UpgradeBuildpack +- #572 - @ghostlandr - Apps: add project id as a parameter to CreateApp and to the App struct +- #570 - @kraai - Fix copy-and-paste error in comment +- #568 - @StephenVarela - LBAAS-2321 Add project_id to load balancers structs + ## [v1.87.0] - 2022-10-12 - #564 - @DWizGuy58 - Add public monitoring alert policies for dbaas @@ -521,16 +540,19 @@ ## [v1.1.0] - 2017-06-06 ### Added + - #145 Add FirewallsService for managing Firewalls with the DigitalOcean API. - @viola - #139 Add TTL field to the Domains. - @xmudrii ### Fixed + - #143 Fix oauth2.NoContext depreciation. - @jbowens - #141 Fix DropletActions on tagged resources. - @xmudrii ## [v1.0.0] - 2017-03-10 ### Added + - #130 Add Convert to ImageActionsService. - @xmudrii - #126 Add CertificatesService for managing certificates with the DigitalOcean API. - @viola - #125 Add LoadBalancersService for managing load balancers with the DigitalOcean API. - @viola diff --git a/vendor/github.com/digitalocean/godo/apps.gen.go b/vendor/github.com/digitalocean/godo/apps.gen.go index dbc2c4a9b..7761d9af5 100644 --- a/vendor/github.com/digitalocean/godo/apps.gen.go +++ b/vendor/github.com/digitalocean/godo/apps.gen.go @@ -94,6 +94,8 @@ type App struct { Domains []*AppDomain `json:"domains,omitempty"` PinnedDeployment *Deployment `json:"pinned_deployment,omitempty"` BuildConfig *AppBuildConfig `json:"build_config,omitempty"` + // The id of the project for the app. This will be empty if there is a lookup failure. + ProjectID string `json:"project_id,omitempty"` } // AppAlertSpec Configuration of an alert for the app or a individual component. @@ -563,6 +565,8 @@ type AppCORSPolicy struct { // AppCreateRequest struct for AppCreateRequest type AppCreateRequest struct { Spec *AppSpec `json:"spec"` + // Optional. The UUID of the project the app should be assigned. + ProjectID string `json:"project_id,omitempty"` } // DeployTemplate struct for DeployTemplate @@ -1007,18 +1011,6 @@ type AppTier struct { BuildSeconds string `json:"build_seconds,omitempty"` } -// UpgradeBuildpackRequest struct for UpgradeBuildpackRequest -type UpgradeBuildpackRequest struct { - // The ID of the app to upgrade buildpack versions for. - AppID string `json:"app_id,omitempty"` - // The ID of the buildpack to upgrade. - BuildpackID string `json:"buildpack_id,omitempty"` - // The Major Version to upgrade the buildpack to. If omitted, the latest available major version will be used. - MajorVersion int32 `json:"major_version,omitempty"` - // Whether or not to trigger a deployment for the app after upgrading the buildpack. - TriggerDeployment bool `json:"trigger_deployment,omitempty"` -} - // UpgradeBuildpackResponse struct for UpgradeBuildpackResponse type UpgradeBuildpackResponse struct { // The components that were affected by the upgrade. diff --git a/vendor/github.com/digitalocean/godo/apps.go b/vendor/github.com/digitalocean/godo/apps.go index a9195d4e9..f19ea1e5a 100644 --- a/vendor/github.com/digitalocean/godo/apps.go +++ b/vendor/github.com/digitalocean/godo/apps.go @@ -51,6 +51,9 @@ type AppsService interface { UpdateAlertDestinations(ctx context.Context, appID, alertID string, update *AlertDestinationUpdateRequest) (*AppAlert, *Response, error) Detect(ctx context.Context, detect *DetectRequest) (*DetectResponse, *Response, error) + + ListBuildpacks(ctx context.Context) ([]*Buildpack, *Response, error) + UpgradeBuildpack(ctx context.Context, appID string, opts UpgradeBuildpackOptions) (*UpgradeBuildpackResponse, *Response, error) } // AppLogs represent app logs. @@ -75,6 +78,16 @@ type AlertDestinationUpdateRequest struct { SlackWebhooks []*AppAlertSlackWebhook `json:"slack_webhooks"` } +// UpgradeBuildpackOptions struct for UpgradeBuildpackOptions +type UpgradeBuildpackOptions struct { + // The ID of the buildpack to upgrade. + BuildpackID string `json:"buildpack_id,omitempty"` + // The Major Version to upgrade the buildpack to. If omitted, the latest available major version will be used. + MajorVersion int32 `json:"major_version,omitempty"` + // Whether or not to trigger a deployment for the app after upgrading the buildpack. + TriggerDeployment bool `json:"trigger_deployment,omitempty"` +} + type appRoot struct { App *App `json:"app"` } @@ -123,6 +136,10 @@ type appAlertRoot struct { Alert *AppAlert `json:"alert"` } +type buildpacksRoot struct { + Buildpacks []*Buildpack `json:"buildpacks,omitempty"` +} + // AppsServiceOp handles communication with Apps methods of the DigitalOcean API. type AppsServiceOp struct { client *Client @@ -444,6 +461,36 @@ func (s *AppsServiceOp) Detect(ctx context.Context, detect *DetectRequest) (*Det return res, resp, nil } +// ListBuildpacks lists the available buildpacks on App Platform. +func (s *AppsServiceOp) ListBuildpacks(ctx context.Context) ([]*Buildpack, *Response, error) { + path := fmt.Sprintf("%s/buildpacks", appsBasePath) + req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + root := new(buildpacksRoot) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root.Buildpacks, resp, nil +} + +// UpgradeBuildpack upgrades a buildpack for an app. +func (s *AppsServiceOp) UpgradeBuildpack(ctx context.Context, appID string, opts UpgradeBuildpackOptions) (*UpgradeBuildpackResponse, *Response, error) { + path := fmt.Sprintf("%s/%s/upgrade_buildpack", appsBasePath, appID) + req, err := s.client.NewRequest(ctx, http.MethodPost, path, opts) + if err != nil { + return nil, nil, err + } + root := new(UpgradeBuildpackResponse) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + // AppComponentType is an app component type. type AppComponentType string diff --git a/vendor/github.com/digitalocean/godo/apps_accessors.go b/vendor/github.com/digitalocean/godo/apps_accessors.go index b968459c5..6af35b2c1 100644 --- a/vendor/github.com/digitalocean/godo/apps_accessors.go +++ b/vendor/github.com/digitalocean/godo/apps_accessors.go @@ -118,6 +118,14 @@ func (a *App) GetPinnedDeployment() *Deployment { return a.PinnedDeployment } +// GetProjectID returns the ProjectID field. +func (a *App) GetProjectID() string { + if a == nil { + return "" + } + return a.ProjectID +} + // GetRegion returns the Region field. func (a *App) GetRegion() *AppRegion { if a == nil { @@ -398,6 +406,14 @@ func (a *AppCORSPolicy) GetMaxAge() string { return a.MaxAge } +// GetProjectID returns the ProjectID field. +func (a *AppCreateRequest) GetProjectID() string { + if a == nil { + return "" + } + return a.ProjectID +} + // GetSpec returns the Spec field. func (a *AppCreateRequest) GetSpec() *AppSpec { if a == nil { @@ -2870,38 +2886,6 @@ func (i *ImageSourceSpecDeployOnPush) GetEnabled() bool { return i.Enabled } -// GetAppID returns the AppID field. -func (u *UpgradeBuildpackRequest) GetAppID() string { - if u == nil { - return "" - } - return u.AppID -} - -// GetBuildpackID returns the BuildpackID field. -func (u *UpgradeBuildpackRequest) GetBuildpackID() string { - if u == nil { - return "" - } - return u.BuildpackID -} - -// GetMajorVersion returns the MajorVersion field. -func (u *UpgradeBuildpackRequest) GetMajorVersion() int32 { - if u == nil { - return 0 - } - return u.MajorVersion -} - -// GetTriggerDeployment returns the TriggerDeployment field. -func (u *UpgradeBuildpackRequest) GetTriggerDeployment() bool { - if u == nil { - return false - } - return u.TriggerDeployment -} - // GetAffectedComponents returns the AffectedComponents field. func (u *UpgradeBuildpackResponse) GetAffectedComponents() []string { if u == nil { diff --git a/vendor/github.com/digitalocean/godo/droplet_actions.go b/vendor/github.com/digitalocean/godo/droplet_actions.go index c1045cdfc..2e09d0c59 100644 --- a/vendor/github.com/digitalocean/godo/droplet_actions.go +++ b/vendor/github.com/digitalocean/godo/droplet_actions.go @@ -293,7 +293,7 @@ func (s *DropletActionsServiceOp) Get(ctx context.Context, dropletID, actionID i return s.get(ctx, path) } -// GetByURI gets an action for a particular Droplet by id. +// GetByURI gets an action for a particular Droplet by URI. func (s *DropletActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (*Action, *Response, error) { u, err := url.Parse(rawurl) if err != nil { diff --git a/vendor/github.com/digitalocean/godo/functions.go b/vendor/github.com/digitalocean/godo/functions.go new file mode 100644 index 000000000..b3829367a --- /dev/null +++ b/vendor/github.com/digitalocean/godo/functions.go @@ -0,0 +1,110 @@ +package godo + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const ( + functionsBasePath = "/v2/functions/namespaces" + functionsNamespacePath = functionsBasePath + "/%s" +) + +type FunctionsService interface { + ListNamespaces(context.Context) ([]FunctionsNamespace, *Response, error) + GetNamespace(context.Context, string) (*FunctionsNamespace, *Response, error) + CreateNamespace(context.Context, *FunctionsNamespaceCreateRequest) (*FunctionsNamespace, *Response, error) + DeleteNamespace(context.Context, string) (*Response, error) +} + +type FunctionsServiceOp struct { + client *Client +} + +var _ FunctionsService = &FunctionsServiceOp{} + +type namespacesRoot struct { + Namespaces []FunctionsNamespace `json:"namespaces,omitempty"` +} + +type namespaceRoot struct { + Namespace *FunctionsNamespace `json:"namespace,omitempty"` +} + +type FunctionsNamespace struct { + ApiHost string `json:"api_host,omitempty"` + Namespace string `json:"namespace,omitempty"` + CreatedAt time.Time `json:"created_at,omitempty"` + UpdatedAt time.Time `json:"updated_at,omitempty"` + Label string `json:"label,omitempty"` + Region string `json:"region,omitempty"` + UUID string `json:"uuid,omitempty"` + Key string `json:"key,omitempty"` +} + +type FunctionsNamespaceCreateRequest struct { + Label string `json:"label"` + Region string `json:"region"` +} + +// Gets a list of namespaces +func (s *FunctionsServiceOp) ListNamespaces(ctx context.Context) ([]FunctionsNamespace, *Response, error) { + req, err := s.client.NewRequest(ctx, http.MethodGet, functionsBasePath, nil) + if err != nil { + return nil, nil, err + } + nsRoot := new(namespacesRoot) + resp, err := s.client.Do(ctx, req, nsRoot) + if err != nil { + return nil, resp, err + } + return nsRoot.Namespaces, resp, nil +} + +// Gets a single namespace +func (s *FunctionsServiceOp) GetNamespace(ctx context.Context, namespace string) (*FunctionsNamespace, *Response, error) { + path := fmt.Sprintf(functionsNamespacePath, namespace) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + nsRoot := new(namespaceRoot) + resp, err := s.client.Do(ctx, req, nsRoot) + if err != nil { + return nil, resp, err + } + return nsRoot.Namespace, resp, nil +} + +// Creates a namespace +func (s *FunctionsServiceOp) CreateNamespace(ctx context.Context, opts *FunctionsNamespaceCreateRequest) (*FunctionsNamespace, *Response, error) { + req, err := s.client.NewRequest(ctx, http.MethodPost, functionsBasePath, opts) + if err != nil { + return nil, nil, err + } + nsRoot := new(namespaceRoot) + resp, err := s.client.Do(ctx, req, nsRoot) + if err != nil { + return nil, resp, err + } + return nsRoot.Namespace, resp, nil +} + +// Delete a namespace +func (s *FunctionsServiceOp) DeleteNamespace(ctx context.Context, namespace string) (*Response, error) { + path := fmt.Sprintf(functionsNamespacePath, namespace) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil +} diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index b92c72f63..854ff185e 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.87.0" + libraryVersion = "1.90.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" @@ -81,6 +81,7 @@ type Client struct { VPCs VPCsService OneClick OneClickService Monitoring MonitoringService + Functions FunctionsService // Optional function called after every successful request made to the DO APIs onRequestCompleted RequestCompletionCallback @@ -103,6 +104,9 @@ type ListOptions struct { // For paginated result sets, the number of results to include per page. PerPage int `url:"per_page,omitempty"` + + // Whether App responses should include project_id fields. The field will be empty if false or if omitted. (ListApps) + WithProjects bool `url:"with_projects,omitempty"` } // TokenListOptions specifies the optional parameters to various List methods that support token pagination. @@ -245,7 +249,7 @@ func NewClient(httpClient *http.Client) *Client { c.VPCs = &VPCsServiceOp{client: c} c.OneClick = &OneClickServiceOp{client: c} c.Monitoring = &MonitoringServiceOp{client: c} - + c.Functions = &FunctionsServiceOp{client: c} c.headers = make(map[string]string) return c @@ -501,8 +505,15 @@ func (r Rate) String() string { return Stringify(r) } +// PtrTo returns a pointer to the provided input. +func PtrTo[T any](v T) *T { + return &v +} + // String is a helper routine that allocates a new string value // to store v and returns a pointer to it. +// +// Deprecated: Use PtrTo instead. func String(v string) *string { p := new(string) *p = v @@ -512,6 +523,8 @@ func String(v string) *string { // Int is a helper routine that allocates a new int32 value // to store v and returns a pointer to it, but unlike Int32 // its argument value is an int. +// +// Deprecated: Use PtrTo instead. func Int(v int) *int { p := new(int) *p = v @@ -520,6 +533,8 @@ func Int(v int) *int { // Bool is a helper routine that allocates a new bool value // to store v and returns a pointer to it. +// +// Deprecated: Use PtrTo instead. func Bool(v bool) *bool { p := new(bool) *p = v diff --git a/vendor/github.com/digitalocean/godo/image_actions.go b/vendor/github.com/digitalocean/godo/image_actions.go index 8006b3729..2ee508c7a 100644 --- a/vendor/github.com/digitalocean/godo/image_actions.go +++ b/vendor/github.com/digitalocean/godo/image_actions.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "net/url" ) // ImageActionsService is an interface for interfacing with the image actions @@ -11,6 +12,7 @@ import ( // See: https://docs.digitalocean.com/reference/api/api-reference/#tag/Image-Actions type ImageActionsService interface { Get(context.Context, int, int) (*Action, *Response, error) + GetByURI(context.Context, string) (*Action, *Response, error) Transfer(context.Context, int, *ActionRequest) (*Action, *Response, error) Convert(context.Context, int) (*Action, *Response, error) } @@ -86,7 +88,20 @@ func (i *ImageActionsServiceOp) Get(ctx context.Context, imageID, actionID int) } path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID) + return i.get(ctx, path) +} + +// GetByURI gets an action for a particular image by URI. +func (i *ImageActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (*Action, *Response, error) { + u, err := url.Parse(rawurl) + if err != nil { + return nil, nil, err + } + + return i.get(ctx, u.Path) +} +func (i *ImageActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { req, err := i.client.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, nil, err diff --git a/vendor/github.com/digitalocean/godo/load_balancers.go b/vendor/github.com/digitalocean/godo/load_balancers.go index da19a5193..1466d5239 100644 --- a/vendor/github.com/digitalocean/godo/load_balancers.go +++ b/vendor/github.com/digitalocean/godo/load_balancers.go @@ -51,6 +51,8 @@ type LoadBalancer struct { VPCUUID string `json:"vpc_uuid,omitempty"` DisableLetsEncryptDNSRecords *bool `json:"disable_lets_encrypt_dns_records,omitempty"` ValidateOnly bool `json:"validate_only,omitempty"` + ProjectID string `json:"project_id,omitempty"` + HTTPIdleTimeoutSeconds *uint64 `json:"http_idle_timeout_seconds,omitempty"` } // String creates a human-readable description of a LoadBalancer. @@ -81,6 +83,8 @@ func (l LoadBalancer) AsRequest() *LoadBalancerRequest { VPCUUID: l.VPCUUID, DisableLetsEncryptDNSRecords: l.DisableLetsEncryptDNSRecords, ValidateOnly: l.ValidateOnly, + ProjectID: l.ProjectID, + HTTPIdleTimeoutSeconds: l.HTTPIdleTimeoutSeconds, } if l.DisableLetsEncryptDNSRecords != nil { @@ -98,6 +102,7 @@ func (l LoadBalancer) AsRequest() *LoadBalancerRequest { if l.Region != nil { r.Region = l.Region.Slug } + return &r } @@ -165,6 +170,8 @@ type LoadBalancerRequest struct { VPCUUID string `json:"vpc_uuid,omitempty"` DisableLetsEncryptDNSRecords *bool `json:"disable_lets_encrypt_dns_records,omitempty"` ValidateOnly bool `json:"validate_only,omitempty"` + ProjectID string `json:"project_id,omitempty"` + HTTPIdleTimeoutSeconds *uint64 `json:"http_idle_timeout_seconds,omitempty"` } // String creates a human-readable description of a LoadBalancerRequest. diff --git a/vendor/modules.txt b/vendor/modules.txt index 32053eea8..6f342492f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -64,7 +64,7 @@ github.com/aws/aws-sdk-go/service/sts/stsiface # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/digitalocean/godo v1.87.0 +# github.com/digitalocean/godo v1.90.0 ## explicit; go 1.18 github.com/digitalocean/godo github.com/digitalocean/godo/metrics